feat(cli): hide redundant log attributes

This commit is contained in:
Julian Tölle 2024-05-04 23:45:58 +02:00
parent c9ab40b539
commit 9e654521ae
3 changed files with 63 additions and 15 deletions

View file

@ -37,13 +37,7 @@ var rootCmd = &cobra.Command{
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
ctx := cmd.Context()
logLevel := slog.LevelInfo
if verbose >= 1 {
logLevel = slog.LevelDebug
}
slog.SetDefault(slog.New(ui.NewHandler(os.Stdout, &ui.HandlerOptions{
Level: logLevel,
})))
slog.SetDefault(initLogger())
// Add logger to command context
logger := slog.Default()
@ -54,6 +48,26 @@ var rootCmd = &cobra.Command{
},
}
func initLogger() *slog.Logger {
logLevel := slog.LevelInfo
if verbose >= 1 {
logLevel = slog.LevelDebug
}
return slog.New(ui.NewHandler(os.Stdout, &ui.HandlerOptions{
Level: logLevel,
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
// Remove attributes that are unnecessary for the cli context
if a.Key == "library" || a.Key == "method" {
return slog.Attr{}
}
return a
},
}))
}
func newClient(ctx context.Context) *hcloudimages.Client {
logger := contextlogger.From(ctx)
// Build hcloud-go client

View file

@ -8,6 +8,9 @@ import (
"sync"
)
// Developed with guidance from golang docs:
// https://github.com/golang/example/blob/32022caedd6a177a7717aa8680cbe179e1045935/slog-handler-guide/README.md
const (
ansiClear = "\033[0m"
ansiBold = "\033[1m"
@ -23,8 +26,41 @@ type Handler struct {
out io.Writer
}
// HandlerOptions are a subset of [slog.HandlerOptions] that are implemented for the UI handler.
type HandlerOptions struct {
// Level reports the minimum record level that will be logged.
// The handler discards records with lower levels.
// If Level is nil, the handler assumes LevelInfo.
// The handler calls Level.Level for each record processed;
// to adjust the minimum level dynamically, use a LevelVar.
Level slog.Leveler
// ReplaceAttr is called to rewrite each non-group attribute before it is logged.
// The attribute's value has been resolved (see [Value.Resolve]).
// If ReplaceAttr returns a zero Attr, the attribute is discarded.
//
// The built-in attributes with keys "time", "level", "source", and "msg"
// are passed to this function, except that time is omitted
// if zero, and source is omitted if AddSource is false.
//
// The first argument is a list of currently open groups that contain the
// Attr. It must not be retained or modified. ReplaceAttr is never called
// for Group attributes, only their contents. For example, the attribute
// list
//
// Int("a", 1), Group("g", Int("b", 2)), Int("c", 3)
//
// results in consecutive calls to ReplaceAttr with the following arguments:
//
// nil, Int("a", 1)
// []string{"g"}, Int("b", 2)
// nil, Int("c", 3)
//
// ReplaceAttr can be used to change the default keys of the built-in
// attributes, convert types (for example, to replace a `time.Time` with the
// integer seconds since the Unix epoch), sanitize personal information, or
// remove attributes from the output.
ReplaceAttr func(groups []string, a slog.Attr) slog.Attr
}
// groupOrAttrs holds either a group name or a list of [slog.Attr].
@ -108,6 +144,12 @@ func (h *Handler) Handle(_ context.Context, record slog.Record) error {
func (h *Handler) appendAttr(buf []byte, group string, a slog.Attr) []byte {
a.Value = a.Value.Resolve()
if h.opts.ReplaceAttr != nil {
a = h.opts.ReplaceAttr([]string{group}, a)
}
// No-op if null attr
if a.Equal(slog.Attr{}) {
return buf
}

View file

@ -1,17 +1,9 @@
package main
import (
"log/slog"
"os"
"github.com/apricote/hcloud-upload-image/cmd"
"github.com/apricote/hcloud-upload-image/internal/ui"
)
func init() {
slog.SetDefault(slog.New(ui.NewHandler(os.Stdout, &ui.HandlerOptions{Level: slog.LevelDebug})))
}
func main() {
cmd.Execute()
}