mirror of
https://github.com/apricote/hcloud-upload-image.git
synced 2026-01-13 13:21:01 +00:00
feat(cli): hide redundant log attributes
This commit is contained in:
parent
c9ab40b539
commit
9e654521ae
3 changed files with 63 additions and 15 deletions
28
cmd/root.go
28
cmd/root.go
|
|
@ -37,13 +37,7 @@ var rootCmd = &cobra.Command{
|
||||||
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
|
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
ctx := cmd.Context()
|
ctx := cmd.Context()
|
||||||
|
|
||||||
logLevel := slog.LevelInfo
|
slog.SetDefault(initLogger())
|
||||||
if verbose >= 1 {
|
|
||||||
logLevel = slog.LevelDebug
|
|
||||||
}
|
|
||||||
slog.SetDefault(slog.New(ui.NewHandler(os.Stdout, &ui.HandlerOptions{
|
|
||||||
Level: logLevel,
|
|
||||||
})))
|
|
||||||
|
|
||||||
// Add logger to command context
|
// Add logger to command context
|
||||||
logger := slog.Default()
|
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 {
|
func newClient(ctx context.Context) *hcloudimages.Client {
|
||||||
logger := contextlogger.From(ctx)
|
logger := contextlogger.From(ctx)
|
||||||
// Build hcloud-go client
|
// Build hcloud-go client
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Developed with guidance from golang docs:
|
||||||
|
// https://github.com/golang/example/blob/32022caedd6a177a7717aa8680cbe179e1045935/slog-handler-guide/README.md
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ansiClear = "\033[0m"
|
ansiClear = "\033[0m"
|
||||||
ansiBold = "\033[1m"
|
ansiBold = "\033[1m"
|
||||||
|
|
@ -23,8 +26,41 @@ type Handler struct {
|
||||||
out io.Writer
|
out io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandlerOptions are a subset of [slog.HandlerOptions] that are implemented for the UI handler.
|
||||||
type HandlerOptions struct {
|
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
|
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].
|
// 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 {
|
func (h *Handler) appendAttr(buf []byte, group string, a slog.Attr) []byte {
|
||||||
a.Value = a.Value.Resolve()
|
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{}) {
|
if a.Equal(slog.Attr{}) {
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
main.go
8
main.go
|
|
@ -1,17 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log/slog"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/apricote/hcloud-upload-image/cmd"
|
"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() {
|
func main() {
|
||||||
cmd.Execute()
|
cmd.Execute()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue