Zerolog - Zero Allocation JSON Logger
Zerolog provides high-performance structured logging with zero allocations for most operations. Use this skill when implementing logging in Go applications that require speed, structured output, or JSON compatibility.
Quick Start
import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
func main() {
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Info().Str("key", "value").Msg("hello world")
}
Log Levels
From highest to lowest: panic, fatal, error, warn, info, debug, trace
zerolog.SetGlobalLevel(zerolog.InfoLevel)
if e := log.Debug(); e.Enabled() {
e.Str("computed", expensiveValue()).Msg("debug info")
}
Structured Fields
Standard Types
log.Info().
Str("string", "value").
Int("count", 42).
Float64("ratio", 3.14).
Bool("enabled", true).
Msg("message")
Advanced Fields
log.Error().
Err(err).
Stack().
Dur("duration", time.Since(start)).
Time("timestamp", time.Now()).
Msg("operation failed")
log.Info().
Dict("user", log.Info().CreateDict().
Str("name", "John").
Int("id", 123)).
Msg("user action")
Logger Configuration
Basic Logger
logger := zerolog.New(os.Stderr).With().Timestamp().Logger()
Sub-loggers with Context
sublogger := log.With().Str("component", "api").Logger()
sublogger.Info().Msg("request handled")
Custom Field Names
zerolog.TimestampFieldName = "t"
zerolog.LevelFieldName = "l"
zerolog.MessageFieldName = "m"
zerolog.ErrorFieldName = "err"
Output Writers
ConsoleWriter (Human-Readable)
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
log.Info().Str("foo", "bar").Msg("Hello World")
MultiLevelWriter
console := zerolog.ConsoleWriter{Out: os.Stdout}
multi := zerolog.MultiLevelWriter(console, os.Stdout)
logger := zerolog.New(multi).With().Timestamp().Logger()
File Output
file, _ := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
logger := zerolog.New(file).With().Timestamp().Logger()
Non-Blocking Diode Writer
wr := diode.NewWriter(os.Stdout, 1000, 10*time.Millisecond, func(missed int) {
fmt.Printf("Dropped %d messages\n", missed)
})
logger := zerolog.New(wr)
Context Integration
Attach Logger to Context
ctx := logger.WithContext(ctx)
logger := zerolog.Ctx(ctx)
logger.Info().Msg("from context")
Pass Context to Events (for hooks)
type TracingHook struct{}
func (h TracingHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
ctx := e.GetCtx()
spanID := getSpanID(ctx)
e.Str("span_id", spanID)
}
logger.Hook(TracingHook{}).Info().Ctx(ctx).Msg("traced")
Error Logging with Stack Traces
import "github.com/rs/zerolog/pkgerrors"
zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack
err := errors.New("something failed")
log.Error().Stack().Err(err).Msg("")
Hooks
type SeverityHook struct{}
func (h SeverityHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
if level != zerolog.NoLevel {
e.Str("severity", level.String())
}
}
hooked := log.Hook(SeverityHook{})
hooked.Warn().Msg("alert")
Log Sampling
Basic Sampling
sampled := log.Sample(&zerolog.BasicSampler{N: 10})
sampled.Info().Msg("logs every 10th message")
Burst Sampling
sampled := log.Sample(zerolog.LevelSampler{
DebugSampler: &zerolog.BurstSampler{
Burst: 5,
Period: 1*time.Second,
NextSampler: &zerolog.BasicSampler{N: 100},
},
})
Predefined Samplers
log.Sample(zerolog.Often) // ~1 in 10
log.Sample(zerolog.Sometimes) // ~1 in 100
log.Sample(zerolog.Rarely) // ~1 in 1000
HTTP Integration (hlog)
import "github.com/rs/zerolog/hlog"
log := zerolog.New(os.Stdout).With().Timestamp().Logger()
handler := hlog.NewHandler(log)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
hlog.FromRequest(r).Info().Str("path", r.URL.Path).Msg("request")
}))
handler = hlog.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) {
hlog.FromRequest(r).Info().
Int("status", status).
Dur("duration", duration).
Msg("access")
})(handler)
Custom Object Marshaling
type User struct {
Name string
ID int
}
func (u User) MarshalZerologObject(e *zerolog.Event) {
e.Str("name", u.Name).Int("id", u.ID)
}
log.Info().Object("user", User{Name: "Alice", ID: 1}).Msg("action")
Important Patterns
Always Call Msg or Send
log.Info().Str("key", "val").Msg("done")
log.Info().Str("key", "val").Send()
Conditional Logging
if e := log.Debug(); e.Enabled() {
e.Str("expensive", compute()).Msg("debug")
}
Concurrency Safety
func handler(w http.ResponseWriter, r *http.Request) {
logger := log.Logger.With().Logger()
logger.UpdateContext(func(c zerolog.Context) zerolog.Context {
return c.Str("request_id", id)
})
}
References
See references/_examples/ for complete working examples demonstrating all features.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.