-
Notifications
You must be signed in to change notification settings - Fork 87
Implement use slog.Leveler and slog.LevelVar. And adding custom log level #180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| "bytes" | ||
| "fmt" | ||
| "io" | ||
| "log/slog" | ||
| "os" | ||
| "runtime" | ||
| "strings" | ||
|
|
@@ -30,7 +31,7 @@ | |
|
|
||
| isDiscard uint32 | ||
|
|
||
| level int64 | ||
| level *slog.LevelVar | ||
| prefix string | ||
| timeFunc TimeFunction | ||
| timeFormat string | ||
|
|
@@ -48,18 +49,18 @@ | |
| } | ||
|
|
||
| // Logf logs a message with formatting. | ||
| func (l *Logger) Logf(level Level, format string, args ...interface{}) { | ||
| func (l *Logger) Logf(level slog.Leveler, format string, args ...interface{}) { | ||
| l.Log(level, fmt.Sprintf(format, args...)) | ||
| } | ||
|
|
||
| // Log logs the given message with the given keyvals for the given level. | ||
| func (l *Logger) Log(level Level, msg interface{}, keyvals ...interface{}) { | ||
| func (l *Logger) Log(level slog.Leveler, msg interface{}, keyvals ...interface{}) { | ||
| if atomic.LoadUint32(&l.isDiscard) != 0 { | ||
| return | ||
| } | ||
|
|
||
| // check if the level is allowed | ||
| if atomic.LoadInt64(&l.level) > int64(level) { | ||
| if l.level.Level() > level.Level() { | ||
| return | ||
| } | ||
|
|
||
|
|
@@ -81,13 +82,13 @@ | |
| l.handle(level, l.timeFunc(time.Now()), []runtime.Frame{frame}, msg, keyvals...) | ||
| } | ||
|
|
||
| func (l *Logger) handle(level Level, ts time.Time, frames []runtime.Frame, msg interface{}, keyvals ...interface{}) { | ||
| func (l *Logger) handle(level slog.Leveler, ts time.Time, frames []runtime.Frame, msg interface{}, keyvals ...interface{}) { | ||
| var kvs []interface{} | ||
| if l.reportTimestamp && !ts.IsZero() { | ||
| kvs = append(kvs, TimestampKey, ts) | ||
| } | ||
|
|
||
| _, ok := l.styles.Levels[level] | ||
| _, ok := l.styles.Levels[int(level.Level())] | ||
| if ok { | ||
| kvs = append(kvs, LevelKey, level) | ||
| } | ||
|
|
@@ -136,7 +137,7 @@ | |
| } | ||
|
|
||
| // WriteTo will reset the buffer | ||
| l.b.WriteTo(l.w) //nolint: errcheck | ||
|
Check failure on line 140 in logger.go
|
||
| } | ||
|
|
||
| // Helper marks the calling function as a helper | ||
|
|
@@ -226,17 +227,17 @@ | |
| } | ||
|
|
||
| // GetLevel returns the current level. | ||
| func (l *Logger) GetLevel() Level { | ||
| func (l *Logger) GetLevel() slog.Leveler { | ||
| l.mu.RLock() | ||
| defer l.mu.RUnlock() | ||
| return Level(l.level) | ||
| return l.level.Level() | ||
| } | ||
|
|
||
| // SetLevel sets the current level. | ||
| func (l *Logger) SetLevel(level Level) { | ||
| func (l *Logger) SetLevel(level slog.Leveler) { | ||
| l.mu.Lock() | ||
| defer l.mu.Unlock() | ||
|
||
| atomic.StoreInt64(&l.level, int64(level)) | ||
| l.level.Set(level.Level()) | ||
| } | ||
|
|
||
| // GetPrefix returns the current prefix. | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,6 +5,7 @@ import ( | |||||||||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||||||||||
| "io" | ||||||||||||||||||||||||||||||
| "log" | ||||||||||||||||||||||||||||||
| "log/slog" | ||||||||||||||||||||||||||||||
| "os" | ||||||||||||||||||||||||||||||
| "sync" | ||||||||||||||||||||||||||||||
| "sync/atomic" | ||||||||||||||||||||||||||||||
|
|
@@ -52,7 +53,7 @@ func NewWithOptions(w io.Writer, o Options) *Logger { | |||||||||||||||||||||||||||||
| b: bytes.Buffer{}, | ||||||||||||||||||||||||||||||
| mu: &sync.RWMutex{}, | ||||||||||||||||||||||||||||||
| helpers: &sync.Map{}, | ||||||||||||||||||||||||||||||
| level: int64(o.Level), | ||||||||||||||||||||||||||||||
| level: nil, | ||||||||||||||||||||||||||||||
| reportTimestamp: o.ReportTimestamp, | ||||||||||||||||||||||||||||||
| reportCaller: o.ReportCaller, | ||||||||||||||||||||||||||||||
| prefix: o.Prefix, | ||||||||||||||||||||||||||||||
|
|
@@ -65,7 +66,18 @@ func NewWithOptions(w io.Writer, o Options) *Logger { | |||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| l.SetOutput(w) | ||||||||||||||||||||||||||||||
| l.SetLevel(Level(l.level)) | ||||||||||||||||||||||||||||||
| switch o.Level.(type) { | ||||||||||||||||||||||||||||||
| case *slog.LevelVar: | ||||||||||||||||||||||||||||||
| l.level = o.Level.(*slog.LevelVar) | ||||||||||||||||||||||||||||||
| default: | ||||||||||||||||||||||||||||||
| lvl := new(slog.LevelVar) | ||||||||||||||||||||||||||||||
| if o.Level == nil { | ||||||||||||||||||||||||||||||
| lvl.Set(slog.LevelInfo) | ||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||
| lvl.Set(o.Level.Level()) | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| l.level = lvl | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
| l.level = lvl | |
| if o.Level == nil { | |
| lvl := new(slog.LevelVar) | |
| lvl.Set(slog.LevelInfo) | |
| l.level = lvl | |
| } else { | |
| switch lvlVar := o.Level.(type) { | |
| case *slog.LevelVar: | |
| l.level = lvlVar | |
| default: | |
| lvl := new(slog.LevelVar) | |
| lvl.Set(o.Level.Level()) | |
| l.level = lvl | |
| } |
Copilot
AI
Aug 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return type change from Level to slog.Leveler is a breaking API change. Consider adding a deprecation notice or maintaining backward compatibility by providing both functions.
| func GetLevel() slog.Leveler { | |
| // | |
| // Deprecated: Use GetLeveler() instead. This will be removed in a future release. | |
| func GetLevel() Level { | |
| return Default().GetLevel().Level() | |
| } | |
| // GetLeveler returns the slog.Leveler for the default logger. | |
| func GetLeveler() slog.Leveler { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return type change from
Leveltoslog.Leveleris a breaking API change. The method now returnsl.level.Level()instead of the*slog.LevelVaritself, which may not be what callers expect when they need to modify the level dynamically.