From 6f9e098632e34073c049b44102a3358c65ecb8a4 Mon Sep 17 00:00:00 2001 From: hz Date: Sat, 19 Oct 2024 07:39:33 +0800 Subject: [PATCH] BREAK for v1: WithXXX() make a child logger and apply settings, SetXXX() just apply settings simply --- slog/entry.go | 123 ++++++++++++++++++++++++++++++++++++++++++-------- slog/funcs.go | 55 +++++++++++----------- slog/i.go | 15 ++++++ 3 files changed, 146 insertions(+), 47 deletions(-) diff --git a/slog/entry.go b/slog/entry.go index 216d317..7a52564 100644 --- a/slog/entry.go +++ b/slog/entry.go @@ -180,11 +180,12 @@ func WithJSONMode(b ...bool) Opt { } } -func (s *Entry) WithJSONMode(b ...bool) *Entry { +func (s *Entry) SetJSONMode(b ...bool) *Entry { mode := true for _, bb := range b { mode = bb } + if mode { s.useColor = false } @@ -192,13 +193,19 @@ func (s *Entry) WithJSONMode(b ...bool) *Entry { return s } +func (s *Entry) WithJSONMode(b ...bool) *Entry { + child := s.newChildLogger() + child.SetJSONMode(b...) + return child +} + func WithColorMode(b ...bool) Opt { return func(s *Entry) { s.WithColorMode(b...) } } -func (s *Entry) WithColorMode(b ...bool) *Entry { +func (s *Entry) SetColorMode(b ...bool) *Entry { mode := true for _, bb := range b { mode = bb @@ -210,13 +217,19 @@ func (s *Entry) WithColorMode(b ...bool) *Entry { return s } +func (s *Entry) WithColorMode(b ...bool) *Entry { + child := s.newChildLogger() + child.SetColorMode(b...) + return child +} + func WithUTCMode(b ...bool) Opt { return func(s *Entry) { s.WithUTCMode(b...) } } -func (s *Entry) WithUTCMode(b ...bool) *Entry { +func (s *Entry) SetUTCMode(b ...bool) *Entry { mode := 2 for _, bb := range b { if bb { @@ -229,13 +242,19 @@ func (s *Entry) WithUTCMode(b ...bool) *Entry { return s } +func (s *Entry) WithUTCMode(b ...bool) *Entry { + child := s.newChildLogger() + child.SetUTCMode(b...) + return child +} + func WithTimeFormat(layout ...string) Opt { return func(s *Entry) { s.WithTimeFormat(layout...) } } -func (s *Entry) WithTimeFormat(layout ...string) *Entry { +func (s *Entry) SetTimeFormat(layout ...string) *Entry { var lay = time.RFC3339Nano for _, ll := range layout { if ll != "" { @@ -246,17 +265,39 @@ func (s *Entry) WithTimeFormat(layout ...string) *Entry { return s } +func (s *Entry) WithTimeFormat(layout ...string) *Entry { + child := s.newChildLogger() + child.SetTimeFormat(layout...) + return child +} + func WithLevel(lvl Level) Opt { return func(s *Entry) { s.WithLevel(lvl) } } -func (s *Entry) WithLevel(lvl Level) *Entry { +func (s *Entry) SetLevel(lvl Level) *Entry { s.level = lvl + switch lvl { + case DebugLevel: + if !is.DebugMode() { + is.SetDebugMode(true) + } + case TraceLevel: + if !is.TraceMode() { + is.SetTraceMode(true) + } + } return s } +func (s *Entry) WithLevel(lvl Level) *Entry { + child := s.newChildLogger() + child.SetLevel(lvl) + return child +} + func (s *Entry) Level() (lvl Level) { // if s.level >= lvlCurrent { // return s.level @@ -289,15 +330,15 @@ func WithAttrs(attrs ...Attr) Opt { } } -// WithAttrs declares some common attributes bound to the +// SetAttrs declares some common attributes bound to the // logger. // // When logging, attributes of the logger and its parents // will be merged together. If duplicated attr found, the // parent's will be overwritten. // -// lc1 := l.New("c1").WithAttrs(NewAttr("lc1", true)) -// lc3 := lc1.New("c3").WithAttrs(NewAttr("lc3", true), NewAttr("lc1", 1)) +// lc1 := l.New("c1").SetAttrs(NewAttr("lc1", true)) +// lc3 := lc1.New("c3").SetAttrs(NewAttr("lc3", true), NewAttr("lc1", 1)) // lc3.Warn("lc3 warn msg", "local", false) // // In above case, attr 'lc1' will be rewritten while lc3.Warn, it looks like: @@ -307,11 +348,18 @@ func WithAttrs(attrs ...Attr) Opt { // You can initialize attributes with different forms, try // using WithAttrs1(attrs Attrs) or With(args ...any) for // instead. -func (s *Entry) WithAttrs(attrs ...Attr) *Entry { +func (s *Entry) SetAttrs(attrs ...Attr) *Entry { s.attrs = append(s.attrs, attrs...) return s } +func (s *Entry) WithAttrs(attrs ...Attr) *Entry { + child := s.newChildLogger() + child.SetAttrs(attrs...) + return child + return s +} + // WithAttrs1 allows an Attrs passed into New. Sample is: // // lc1 := l.New("c1").WithAttrs1(NewAttrs("a1", 1, "a2", 2.7, NewAttr("a3", "string"))) @@ -325,18 +373,24 @@ func WithAttrs1(attrs Attrs) Opt { } } -// WithAttrs1 allows an Attrs passed into New. Sample is: +// SetAttrs1 allows an Attrs passed into New. Sample is: // -// lc1 := l.New("c1").WithAttrs1(NewAttrs("a1", 1, "a2", 2.7, NewAttr("a3", "string"))) +// lc1 := l.New("c1").SetAttrs1(NewAttrs("a1", 1, "a2", 2.7, NewAttr("a3", "string"))) // // NewAttrs receives a freeform args list. // // You can use With(...) to simplify WithAttrs1+NewAttrs1 calling. -func (s *Entry) WithAttrs1(attrs Attrs) *Entry { +func (s *Entry) SetAttrs1(attrs Attrs) *Entry { s.attrs = append(s.attrs, attrs...) return s } +func (s *Entry) WithAttrs1(attrs Attrs) *Entry { + child := s.newChildLogger() + child.SetAttrs1(attrs) + return child +} + // With allows an freeform arg list passed into New. Sample is: // // lc1 := l.New("c1").With("a1", 1, "a2", 2.7, NewAttr("a3", "string")) @@ -348,26 +402,38 @@ func With(args ...any) Opt { } } -// With allows an freeform arg list passed into New. Sample is: +// Set allows an freeform arg list passed into New. Sample is: // -// lc1 := l.New("c1").With("a1", 1, "a2", 2.7, NewAttr("a3", "string")) +// lc1 := l.New("c1").Set("a1", 1, "a2", 2.7, NewAttr("a3", "string")) // // More samples can be found at New. -func (s *Entry) With(args ...any) *Entry { // key1,val1,key2,val2,.... Of course, Attr, Attrs in args will be recognized as is +func (s *Entry) Set(args ...any) *Entry { // key1,val1,key2,val2,.... Of course, Attr, Attrs in args will be recognized as is s.attrs = append(s.attrs, argsToAttrs(nil, args...)...) return s } +func (s *Entry) With(args ...any) *Entry { // key1,val1,key2,val2,.... Of course, Attr, Attrs in args will be recognized as is + child := s.newChildLogger() + child.Set(args...) + return child +} + type ValueStringer interface { SetWriter(w io.Writer) WriteValue(value any) } -func (s *Entry) WithValueStringer(vs ValueStringer) *Entry { +func (s *Entry) SetValueStringer(vs ValueStringer) *Entry { s.valueStringer = vs return s } +func (s *Entry) WithValueStringer(vs ValueStringer) *Entry { + child := s.newChildLogger() + child.SetValueStringer(vs) + return child +} + func GetDefaultWriter() (wr io.Writer) { return defaultWriter } // return package-level default writer func GetDefaultLoggersWriter() (wr io.Writer) { return defaultLog.GetWriter() } // return package-level default logger's writer @@ -392,7 +458,7 @@ func WithWriter(wr io.Writer) Opt { } } -func (s *Entry) WithWriter(wr io.Writer) *Entry { +func (s *Entry) SetWriter(wr io.Writer) *Entry { if s.writer == nil { s.writer = newDualWriter() } @@ -401,6 +467,12 @@ func (s *Entry) WithWriter(wr io.Writer) *Entry { return s } +func (s *Entry) WithWriter(wr io.Writer) *Entry { + child := s.newChildLogger() + child.SetWriter(wr) + return child +} + // AddWriter adds a stdout writers to Default logger. // It is a Opt functor so you have to invoke it at New(,,,). // @@ -426,7 +498,7 @@ func WithErrorWriter(wr io.Writer) Opt { } } -func (s *Entry) WithErrorWriter(wr io.Writer) *Entry { +func (s *Entry) SetErrorWriter(wr io.Writer) *Entry { if s.writer == nil { s.writer = newDualWriter() } @@ -435,6 +507,12 @@ func (s *Entry) WithErrorWriter(wr io.Writer) *Entry { return s } +func (s *Entry) WithErrorWriter(wr io.Writer) *Entry { + child := s.newChildLogger() + child.SetErrorWriter(wr) + return child +} + // AddErrorWriter adds a stderr writers to Default logger. // It is a Opt functor so you have to invoke it at New(,,,). // @@ -574,8 +652,13 @@ func (s *Entry) withSkip(extraFrames int) *Entry { return s } -func (s *Entry) SetSkip(extraFrames int) { s.extraFrames = extraFrames } // set extra frames ignored -func (s *Entry) Skip() int { return s.extraFrames } // return extra frames ignored +// SetSkip sets the extra ignoring frames +func (s *Entry) SetSkip(extraFrames int) { + s.extraFrames = extraFrames + // return s +} + +func (s *Entry) Skip() int { return s.extraFrames } // return extra frames ignored // // diff --git a/slog/funcs.go b/slog/funcs.go index 9dc1c02..45043f1 100644 --- a/slog/funcs.go +++ b/slog/funcs.go @@ -68,30 +68,31 @@ func Println(args ...any) { func logctx(lvl Level, msg string, args ...any) { ctx := context.Background() - switch s := defaultLog.(type) { - case *logimp: - if s.EnabledContext(ctx, lvl) { - pc := getpc(3, s.extraFrames) // caller -> slog.Info -> logctx (this func) - s.logContext(ctx, lvl, pc, msg, args...) - } - case *Entry: - if s.EnabledContext(ctx, lvl) { - pc := getpc(3, s.extraFrames) // caller -> slog.Info -> logctx (this func) - s.logContext(ctx, lvl, pc, msg, args...) - } - } + logctxctx(ctx, 1, lvl, msg, args...) + // switch s := defaultLog.(type) { + // case *logimp: + // if s.EnabledContext(ctx, lvl) { + // pc := getpc(3, s.extraFrames) // caller -> slog.Info -> logctx (this func) + // s.logContext(ctx, lvl, pc, msg, args...) + // } + // case *Entry: + // if s.EnabledContext(ctx, lvl) { + // pc := getpc(3, s.extraFrames) // caller -> slog.Info -> logctx (this func) + // s.logContext(ctx, lvl, pc, msg, args...) + // } + // } } -func logctxctx(ctx context.Context, lvl Level, msg string, args ...any) { +func logctxctx(ctx context.Context, inc int, lvl Level, msg string, args ...any) { switch s := defaultLog.(type) { case *logimp: if s.EnabledContext(ctx, lvl) { - pc := getpc(3, s.extraFrames) // caller -> slog.Info -> logctx (this func) + pc := getpc(3+inc, s.extraFrames) // caller -> slog.Info -> logctx (this func) s.logContext(ctx, lvl, pc, msg, args...) } case *Entry: if s.EnabledContext(ctx, lvl) { - pc := getpc(3, s.extraFrames) // caller -> slog.Info -> logctx (this func) + pc := getpc(3+inc, s.extraFrames) // caller -> slog.Info -> logctx (this func) s.logContext(ctx, lvl, pc, msg, args...) } } @@ -101,62 +102,62 @@ func logctxctx(ctx context.Context, lvl Level, msg string, args ...any) { // PanicContext with Default Logger. func PanicContext(ctx context.Context, msg string, args ...any) { - logctxctx(ctx, PanicLevel, msg, args...) + logctxctx(ctx, 0, PanicLevel, msg, args...) } // FatalContext with Default Logger. func FatalContext(ctx context.Context, msg string, args ...any) { - logctxctx(ctx, FatalLevel, msg, args...) + logctxctx(ctx, 0, FatalLevel, msg, args...) } // ErrorContext with Default Logger. func ErrorContext(ctx context.Context, msg string, args ...any) { - logctxctx(ctx, ErrorLevel, msg, args...) + logctxctx(ctx, 0, ErrorLevel, msg, args...) } // WarnContext with Default Logger. func WarnContext(ctx context.Context, msg string, args ...any) { - logctxctx(ctx, WarnLevel, msg, args...) + logctxctx(ctx, 0, WarnLevel, msg, args...) } // InfoContext with Default Logger. func InfoContext(ctx context.Context, msg string, args ...any) { - logctxctx(ctx, InfoLevel, msg, args...) + logctxctx(ctx, 0, InfoLevel, msg, args...) } // DebugContext with Default Logger. func DebugContext(ctx context.Context, msg string, args ...any) { - logctxctx(ctx, DebugLevel, msg, args...) + logctxctx(ctx, 0, DebugLevel, msg, args...) } // TraceContext with Default Logger. func TraceContext(ctx context.Context, msg string, args ...any) { - logctxctx(ctx, TraceLevel, msg, args...) + logctxctx(ctx, 0, TraceLevel, msg, args...) } // PrintContext with Default Logger. func PrintContext(ctx context.Context, msg string, args ...any) { - logctxctx(ctx, AlwaysLevel, msg, args...) + logctxctx(ctx, 0, AlwaysLevel, msg, args...) } // PrintlnContext with Default Logger. func PrintlnContext(ctx context.Context, msg string, args ...any) { - logctxctx(ctx, AlwaysLevel, msg, args...) + logctxctx(ctx, 0, AlwaysLevel, msg, args...) } // OKContext with Default Logger. func OKContext(ctx context.Context, msg string, args ...any) { - logctxctx(ctx, OKLevel, msg, args...) + logctxctx(ctx, 0, OKLevel, msg, args...) } // SuccessContext with Default Logger. func SuccessContext(ctx context.Context, msg string, args ...any) { - logctxctx(ctx, SuccessLevel, msg, args...) + logctxctx(ctx, 0, SuccessLevel, msg, args...) } // FailContext with Default Logger. func FailContext(ctx context.Context, msg string, args ...any) { - logctxctx(ctx, FailLevel, msg, args...) + logctxctx(ctx, 0, FailLevel, msg, args...) } // diff --git a/slog/i.go b/slog/i.go index 08e9331..e698c19 100644 --- a/slog/i.go +++ b/slog/i.go @@ -43,9 +43,15 @@ type ( } // BuilderI is used for building a new logger + // + // // WithXXX apis: make a child logger and apply the new settings. + // _ + // // SetXXX apis: apply the new settings on this logger + // _ BuilderI interface { New(args ...any) *Entry // 1st of args is name, the rest are k, v pairs + // WithJSONMode and WithColorMode sets output format to json or logfmt(+color). WithJSONMode(b ...bool) *Entry // entering JSON mode, the output are json format WithColorMode(b ...bool) *Entry // entering Colorful mode for the modern terminal. false means using logfmt format. WithUTCMode(b ...bool) *Entry // default is local mode, true will switch to UTC mode @@ -55,6 +61,15 @@ type ( WithAttrs1(attrs Attrs) *Entry // With(args ...any) *Entry // key1,val1,key2,val2,.... Of course, Attr, Attrs in args will be recognized as is + SetJSONMode(b ...bool) *Entry // entering JSON mode, the output are json format + SetColorMode(b ...bool) *Entry // entering Colorful mode for the modern terminal. false means using logfmt format. + SetUTCMode(b ...bool) *Entry // default is local mode, true will switch to UTC mode + SetTimeFormat(layout ...string) *Entry // specify your timestamp format layout string + SetLevel(lvl Level) *Entry // + SetAttrs(attrs ...Attr) *Entry // + SetAttrs1(attrs Attrs) *Entry // + Set(args ...any) *Entry // key1,val1,key2,val2,.... Of course, Attr, Attrs in args will be recognized as is + WithContextKeys(keys ...any) *Entry // given keys will be tried extracting from context.Context automatically WithWriter(wr io.Writer) *Entry // use the given writer