Add structured logging infrastructure (#246)
New global flags:
* `--log-file FILE`: can be literal `stdout`, `stderr`, or a file name (default `stderr`)
* `--log-level LEVEL`: can be `error`, `warn`, `info`, `debug`, `trace`, or `disabled` (default `disabled`)
* `--log-format TYPE`: can be `text` or `json` (default `text`)
New functions in the `log` package take a `context.Context` and retrieve
the logger from said context.
Because we carry the logger in a context, adding
[attributes](https://pkg.go.dev/golang.org/x/exp/slog#hdr-Attrs_and_Values)
to the logger can be done as follows:
```go
ctx = log.NewContext(ctx, log.GetLogger(ctx).With("foo", "bar"))
```
2023-03-16 13:46:53 +00:00
|
|
|
package flags
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
2023-05-16 16:35:39 +00:00
|
|
|
"github.com/databricks/cli/libs/log"
|
Add structured logging infrastructure (#246)
New global flags:
* `--log-file FILE`: can be literal `stdout`, `stderr`, or a file name (default `stderr`)
* `--log-level LEVEL`: can be `error`, `warn`, `info`, `debug`, `trace`, or `disabled` (default `disabled`)
* `--log-format TYPE`: can be `text` or `json` (default `text`)
New functions in the `log` package take a `context.Context` and retrieve
the logger from said context.
Because we carry the logger in a context, adding
[attributes](https://pkg.go.dev/golang.org/x/exp/slog#hdr-Attrs_and_Values)
to the logger can be done as follows:
```go
ctx = log.NewContext(ctx, log.GetLogger(ctx).With("foo", "bar"))
```
2023-03-16 13:46:53 +00:00
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"golang.org/x/exp/maps"
|
|
|
|
"golang.org/x/exp/slog"
|
|
|
|
)
|
|
|
|
|
|
|
|
var levels = map[string]slog.Level{
|
|
|
|
"trace": log.LevelTrace,
|
|
|
|
"debug": log.LevelDebug,
|
|
|
|
"info": log.LevelInfo,
|
|
|
|
"warn": log.LevelWarn,
|
|
|
|
"error": log.LevelError,
|
|
|
|
"disabled": log.LevelDisabled,
|
|
|
|
}
|
|
|
|
|
|
|
|
type LogLevelFlag struct {
|
|
|
|
l slog.Level
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewLogLevelFlag() LogLevelFlag {
|
|
|
|
return LogLevelFlag{
|
2023-04-05 13:37:09 +00:00
|
|
|
l: log.LevelDisabled,
|
Add structured logging infrastructure (#246)
New global flags:
* `--log-file FILE`: can be literal `stdout`, `stderr`, or a file name (default `stderr`)
* `--log-level LEVEL`: can be `error`, `warn`, `info`, `debug`, `trace`, or `disabled` (default `disabled`)
* `--log-format TYPE`: can be `text` or `json` (default `text`)
New functions in the `log` package take a `context.Context` and retrieve
the logger from said context.
Because we carry the logger in a context, adding
[attributes](https://pkg.go.dev/golang.org/x/exp/slog#hdr-Attrs_and_Values)
to the logger can be done as follows:
```go
ctx = log.NewContext(ctx, log.GetLogger(ctx).With("foo", "bar"))
```
2023-03-16 13:46:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *LogLevelFlag) Level() slog.Level {
|
|
|
|
return f.l
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *LogLevelFlag) String() string {
|
|
|
|
for name, l := range levels {
|
|
|
|
if f.l == l {
|
|
|
|
return name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "(unknown)"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *LogLevelFlag) Set(s string) error {
|
|
|
|
l, ok := levels[strings.ToLower(s)]
|
|
|
|
if !ok {
|
|
|
|
return fmt.Errorf("accepted arguments are %s", strings.Join(maps.Keys(levels), ", "))
|
|
|
|
}
|
|
|
|
|
|
|
|
f.l = l
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *LogLevelFlag) Type() string {
|
|
|
|
return "format"
|
|
|
|
}
|
|
|
|
|
|
|
|
// Complete is the Cobra compatible completion function for this flag.
|
|
|
|
func (f *LogLevelFlag) Complete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
|
|
return maps.Keys(levels), cobra.ShellCompDirectiveNoFileComp
|
|
|
|
}
|