Skip to content

Commit

Permalink
Allow for custom level mapping between logrus and slog
Browse files Browse the repository at this point in the history
  • Loading branch information
flimzy committed Nov 9, 2023
1 parent e3f17e5 commit 486d0ec
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
16 changes: 13 additions & 3 deletions hooks/slog/slog.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,16 @@ import (
"github.com/sirupsen/logrus"
)

// LevelMapper maps a [github.com/sirupsen/logrus.Level] value to a
// [slog.Leveler] value. To change the default level mapping, for instance
// to allow mapping to custom or dynamic slog levels in your application, set
// [SlogHook.LevelMapper] to your own implementation of this function.
type LevelMapper func(logrus.Level) slog.Leveler

// SlogHook sends logs to slog.
type SlogHook struct {
logger *slog.Logger
logger *slog.Logger
LevelMapper LevelMapper
}

var _ logrus.Hook = (*SlogHook)(nil)
Expand All @@ -31,7 +38,10 @@ func NewSlogHook(logger *slog.Logger) *SlogHook {
}
}

func (*SlogHook) toSlogLevel(level logrus.Level) slog.Level {
func (h *SlogHook) toSlogLevel(level logrus.Level) slog.Leveler {
if h.LevelMapper != nil {
return h.LevelMapper(level)
}
switch level {
case logrus.PanicLevel, logrus.FatalLevel, logrus.ErrorLevel:
return slog.LevelError
Expand Down Expand Up @@ -62,7 +72,7 @@ func (h *SlogHook) Fire(entry *logrus.Entry) error {
}
h.logger.Log(
entry.Context,
h.toSlogLevel(entry.Level),
h.toSlogLevel(entry.Level).Level(),
entry.Message,
attrs...,
)
Expand Down
25 changes: 21 additions & 4 deletions hooks/slog/slog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import (

func TestSlogHook(t *testing.T) {
tests := []struct {
name string
fn func(*logrus.Logger)
want []string
name string
mapper LevelMapper
fn func(*logrus.Logger)
want []string
}{
{
name: "defaults",
Expand All @@ -39,6 +40,20 @@ func TestSlogHook(t *testing.T) {
"level=ERROR msg=error chicken=cluck",
},
},
{
name: "level mapper",
mapper: func(logrus.Level) slog.Leveler {
return slog.LevelInfo
},
fn: func(log *logrus.Logger) {
log.WithFields(logrus.Fields{
"chicken": "cluck",
}).Error("error")
},
want: []string{
"level=INFO msg=error chicken=cluck",
},
},
}

for _, tt := range tests {
Expand All @@ -55,7 +70,9 @@ func TestSlogHook(t *testing.T) {
}))
log := logrus.New()
log.Out = io.Discard
log.AddHook(NewSlogHook(slogLogger))
hook := NewSlogHook(slogLogger)
hook.LevelMapper = tt.mapper
log.AddHook(hook)
tt.fn(log)
got := strings.Split(strings.TrimSpace(buf.String()), "\n")
if len(got) != len(tt.want) {
Expand Down

0 comments on commit 486d0ec

Please sign in to comment.