Skip to content

Commit

Permalink
[zerolog] Increase performance
Browse files Browse the repository at this point in the history
By default, all fields are passed to zerolog Event as `Event.Interface`. Unfortunately it ads significant overhead for basic primitives (such as string, int etc.), because internally json.Marshal is used.
  • Loading branch information
elgopher committed Jan 27, 2022
1 parent 9f78a73 commit b248514
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
25 changes: 25 additions & 0 deletions adapter/internal/benchmark/benchmark.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package benchmark
import (
"context"
"testing"
"time"

"github.com/elgopher/yala/logger"
)
Expand Down Expand Up @@ -37,4 +38,28 @@ func Adapter(b *testing.B, adapter logger.Adapter) {
localLogger.Info(ctx, "msg")
}
})

fields := map[string]interface{}{
"string": "str",
"int": 1,
"int64": int64(64), // nolint
"float64": 1.64, // nolint
"float32": float32(1.32), // nolint
"time": time.Time{},
}

for fieldType, fieldValue := range fields {
b.Run(fieldType, func(b *testing.B) {
b.Run("local logger with field", func(b *testing.B) {
localLogger := logger.Local{Adapter: adapter}

b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
localLogger.With(ctx, "a", fieldValue).Info("msg")
}
})
})
}
}
24 changes: 23 additions & 1 deletion adapter/zerologadapter/zerolog.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package zerologadapter

import (
"context"
"time"

"github.com/elgopher/yala/logger"
"github.com/rs/zerolog"
Expand All @@ -19,7 +20,7 @@ func (l Adapter) Log(ctx context.Context, entry logger.Entry) {
event := l.Logger.WithLevel(convertLevel(entry.Level))

for _, field := range entry.Fields {
event = event.Interface(field.Key, field.Value)
event = eventWithField(event, field)
}

if entry.Error != nil {
Expand All @@ -43,3 +44,24 @@ func convertLevel(level logger.Level) zerolog.Level {
return zerolog.InfoLevel
}
}

func eventWithField(event *zerolog.Event, field logger.Field) *zerolog.Event {
switch value := field.Value.(type) {
case string:
event = event.Str(field.Key, value)
case int:
event = event.Int(field.Key, value)
case int64:
event = event.Int64(field.Key, value)
case float64:
event = event.Float64(field.Key, value)
case float32:
event = event.Float32(field.Key, value)
case time.Time:
event = event.Time(field.Key, value)
default:
event = event.Interface(field.Key, field.Value)
}

return event
}

0 comments on commit b248514

Please sign in to comment.