or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced-types.mdcontextual-logging.mdcore-logging.mddiode-writer.mdfield-methods.mdglobal-configuration.mdglobal-logger.mdhooks.mdhttp-middleware.mdindex.mdjournald-integration.mdpkgerrors-integration.mdsampling.mdwriters-and-output.md
tile.json

global-configuration.mddocs/

Global Configuration

Zerolog provides extensive global configuration through package-level variables. These settings affect all loggers and allow you to customize field names, formats, marshalers, and behavior across your entire application.

Imports

import (
    "time"
    "github.com/rs/zerolog"
)

Field Name Configuration

Customize the field names used in JSON output.

// Timestamp field name (default: "time")
var TimestampFieldName = "time"

// Level field name (default: "level")
var LevelFieldName = "level"

// Message field name (default: "message")
var MessageFieldName = "message"

// Error field name (default: "error")
var ErrorFieldName = "error"

// Caller field name (default: "caller")
var CallerFieldName = "caller"

// Error stack field name (default: "stack")
var ErrorStackFieldName = "stack"

Example:

func init() {
    zerolog.TimestampFieldName = "ts"
    zerolog.LevelFieldName = "severity"
    zerolog.MessageFieldName = "msg"
}

logger := zerolog.New(os.Stdout).With().Timestamp().Logger()
logger.Info().Msg("hello")
// Output: {"severity":"info","ts":"2024-01-15T10:30:00Z","msg":"hello"}

Level String Values

Customize the string representation of log levels.

// Level string values
var LevelTraceValue = "trace"
var LevelDebugValue = "debug"
var LevelInfoValue = "info"
var LevelWarnValue = "warn"
var LevelErrorValue = "error"
var LevelFatalValue = "fatal"
var LevelPanicValue = "panic"

Example:

func init() {
    zerolog.LevelInfoValue = "information"
    zerolog.LevelErrorValue = "err"
}

logger := zerolog.New(os.Stdout)
logger.Info().Msg("hello")
// Output: {"level":"information","message":"hello"}

logger.Error().Msg("failed")
// Output: {"level":"err","message":"failed"}

Level Marshaling

Customize how levels are marshaled to strings.

// Customize level field marshaling
var LevelFieldMarshalFunc = func(l Level) string {
    return l.String()
}

Example:

func init() {
    // Use numeric levels
    zerolog.LevelFieldMarshalFunc = func(l zerolog.Level) string {
        return strconv.Itoa(int(l))
    }
}

logger := zerolog.New(os.Stdout)
logger.Info().Msg("hello")
// Output: {"level":"1","message":"hello"}

Example with uppercase:

func init() {
    zerolog.LevelFieldMarshalFunc = func(l zerolog.Level) string {
        return strings.ToUpper(l.String())
    }
}

logger.Info().Msg("hello")
// Output: {"level":"INFO","message":"hello"}

Time Configuration

Control how timestamps and durations are formatted.

Time Field Format

// Time field format (default: time.RFC3339)
var TimeFieldFormat = time.RFC3339

Standard time formats:

func init() {
    // RFC3339 with milliseconds
    zerolog.TimeFieldFormat = time.RFC3339Nano

    // Custom format
    zerolog.TimeFieldFormat = "2006-01-02 15:04:05"
}

Unix timestamp formats:

// Time format constants for Unix timestamps
const (
    TimeFormatUnix      = ""          // Unix seconds
    TimeFormatUnixMs    = "UNIXMS"    // Unix milliseconds
    TimeFormatUnixMicro = "UNIXMICRO" // Unix microseconds
    TimeFormatUnixNano  = "UNIXNANO"  // Unix nanoseconds
)

Example:

func init() {
    // Use Unix milliseconds
    zerolog.TimeFieldFormat = zerolog.TimeFormatUnixMs
}

logger := zerolog.New(os.Stdout).With().Timestamp().Logger()
logger.Info().Msg("hello")
// Output: {"level":"info","time":1705318200000,"message":"hello"}

Timestamp Function

// Function to generate timestamps (default: time.Now)
var TimestampFunc = time.Now

Example with frozen time (testing):

func init() {
    // Freeze time for testing
    frozenTime := time.Date(2024, 1, 15, 10, 30, 0, 0, time.UTC)
    zerolog.TimestampFunc = func() time.Time {
        return frozenTime
    }
}

Example with custom time source:

func init() {
    // Use monotonic clock
    start := time.Now()
    zerolog.TimestampFunc = func() time.Time {
        return start.Add(time.Since(start))
    }
}

Duration Configuration

// Duration field unit (default: time.Millisecond)
var DurationFieldUnit = time.Millisecond

// Render durations as integers (default: false)
var DurationFieldInteger = false

Example:

func init() {
    // Use seconds for durations
    zerolog.DurationFieldUnit = time.Second
    zerolog.DurationFieldInteger = true
}

logger := zerolog.New(os.Stdout)
logger.Info().Dur("elapsed", 5*time.Second).Msg("completed")
// Output: {"level":"info","elapsed":5,"message":"completed"}

With milliseconds (default):

func init() {
    zerolog.DurationFieldUnit = time.Millisecond
    zerolog.DurationFieldInteger = false
}

logger.Info().Dur("elapsed", 1234*time.Millisecond).Msg("completed")
// Output: {"level":"info","elapsed":1234,"message":"completed"}

Error Configuration

Customize error handling and formatting.

Error Marshaling

// Customize error marshaling (default: returns error as-is)
var ErrorMarshalFunc = func(err error) interface{} {
    return err
}

Example with custom error format:

func init() {
    zerolog.ErrorMarshalFunc = func(err error) interface{} {
        if err == nil {
            return nil
        }
        return map[string]interface{}{
            "message": err.Error(),
            "type":    fmt.Sprintf("%T", err),
        }
    }
}

err := errors.New("connection failed")
logger.Error().Err(err).Msg("operation failed")
// Output: {"level":"error","error":{"message":"connection failed","type":"*errors.errorString"},...}

Stack Trace Marshaling

// Extract stack trace from error (default: nil)
var ErrorStackMarshaler func(err error) interface{}

Example:

import "github.com/rs/zerolog/pkgerrors"

func init() {
    zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack
}

logger.Error().Stack().Err(err).Msg("error with stack")
// Includes stack trace if error has one

See Package Errors Integration for details.

Error Handler

// Handle write errors (default: print to stderr)
var ErrorHandler func(err error)

Example:

func init() {
    zerolog.ErrorHandler = func(err error) {
        fmt.Fprintf(os.Stderr, "Logging error: %v\n", err)
        // Could also send to monitoring system
    }
}

Caller Configuration

Customize caller file and line formatting.

// Number of stack frames to skip (default: 2)
var CallerSkipFrameCount = 2

// Customize caller format (default: "file:line")
var CallerMarshalFunc = func(pc uintptr, file string, line int) string {
    return file + ":" + strconv.Itoa(line)
}

Example with short file names:

func init() {
    zerolog.CallerMarshalFunc = func(pc uintptr, file string, line int) string {
        // Use only filename, not full path
        return filepath.Base(file) + ":" + strconv.Itoa(line)
    }
}

logger.Info().Caller().Msg("hello")
// Output: {"caller":"main.go:42",...}

Example with function name:

func init() {
    zerolog.CallerMarshalFunc = func(pc uintptr, file string, line int) string {
        fn := runtime.FuncForPC(pc)
        if fn == nil {
            return file + ":" + strconv.Itoa(line)
        }
        return fn.Name() + " " + file + ":" + strconv.Itoa(line)
    }
}

logger.Info().Caller().Msg("hello")
// Output: {"caller":"main.main /path/to/main.go:42",...}

Interface Marshaling

Customize how interface{} values are marshaled.

// Customize interface marshaling (default: json.Marshal without HTML escaping)
var InterfaceMarshalFunc = func(v interface{}) ([]byte, error) {
    // Default implementation
}

Example with custom marshaler:

import "encoding/json"

func init() {
    zerolog.InterfaceMarshalFunc = func(v interface{}) ([]byte, error) {
        // Use standard JSON marshaling with indentation (for debugging)
        return json.MarshalIndent(v, "", "  ")
    }
}

Float Precision

Control floating-point number formatting.

// Float formatting precision (default: -1, no limit)
var FloatingPointPrecision = -1

Example:

func init() {
    // Limit to 2 decimal places
    zerolog.FloatingPointPrecision = 2
}

logger.Info().Float64("value", 3.14159).Msg("pi")
// Output: {"level":"info","value":3.14,"message":"pi"}

Context Configuration

Set default logger for context operations.

// Default logger from Ctx() when none in context (default: nil, returns disabled logger)
var DefaultContextLogger *Logger

Example:

func init() {
    logger := zerolog.New(os.Stdout).With().
        Str("app", "myapp").
        Logger()
    zerolog.DefaultContextLogger = &logger
}

// Now Ctx() returns the default logger if none in context
logger := zerolog.Ctx(context.Background())
logger.Info().Msg("using default logger")

Console Writer Configuration

Customize console writer appearance.

// ANSI color codes per level
var LevelColors = map[Level]int{
    TraceLevel: colorBlue,
    DebugLevel: 0,
    InfoLevel:  colorGreen,
    WarnLevel:  colorYellow,
    ErrorLevel: colorRed,
    FatalLevel: colorRed,
    PanicLevel: colorRed,
}

// Short level names for console output
var FormattedLevels = map[Level]string{
    TraceLevel: "TRC",
    DebugLevel: "DBG",
    InfoLevel:  "INF",
    WarnLevel:  "WRN",
    ErrorLevel: "ERR",
    FatalLevel: "FTL",
    PanicLevel: "PNC",
}

Example:

func init() {
    // Custom colors
    zerolog.LevelColors[zerolog.InfoLevel] = 36 // Cyan

    // Custom level abbreviations
    zerolog.FormattedLevels[zerolog.InfoLevel] = "INFO"
}

Global Level Control

Set minimum log level globally.

// Set global minimum level
func SetGlobalLevel(l Level)

// Get current global level
func GlobalLevel() Level

Example:

func init() {
    if os.Getenv("DEBUG") == "true" {
        zerolog.SetGlobalLevel(zerolog.DebugLevel)
    } else {
        zerolog.SetGlobalLevel(zerolog.InfoLevel)
    }
}

// All loggers respect global level
logger.Debug().Msg("debug message")  // Only logged if global level allows

Get current level:

currentLevel := zerolog.GlobalLevel()
fmt.Printf("Global level: %s\n", currentLevel)

Sampling Control

Globally disable all sampling.

// Disable sampling globally (for debugging)
func DisableSampling(v bool)

Example:

func TestSomething(t *testing.T) {
    // Disable sampling for tests
    zerolog.DisableSampling(true)
    defer zerolog.DisableSampling(false)

    // All samplers now pass through
    logger.Info().Msg("always logged")
}

Writer Configuration

// Buffer size limit for TriggerLevelWriter pool (default: 64 KiB)
var TriggerLevelWriterBufferReuseLimit = 64 * 1024

Example:

func init() {
    // Increase buffer limit to 128 KiB
    zerolog.TriggerLevelWriterBufferReuseLimit = 128 * 1024
}

Common Configuration Patterns

Production Configuration

func init() {
    // Minimal, efficient settings for production
    zerolog.TimeFieldFormat = zerolog.TimeFormatUnixMs
    zerolog.DurationFieldUnit = time.Millisecond
    zerolog.DurationFieldInteger = true
    zerolog.SetGlobalLevel(zerolog.InfoLevel)
}

Development Configuration

func init() {
    // Readable settings for development
    zerolog.TimeFieldFormat = time.RFC3339
    zerolog.SetGlobalLevel(zerolog.DebugLevel)

    // Custom field names for readability
    zerolog.TimestampFieldName = "timestamp"
    zerolog.MessageFieldName = "msg"
}

Cloud Logging Configuration

func init() {
    // Match Google Cloud Logging format
    zerolog.TimestampFieldName = "timestamp"
    zerolog.LevelFieldName = "severity"
    zerolog.MessageFieldName = "message"

    // Use uppercase levels
    zerolog.LevelFieldMarshalFunc = func(l zerolog.Level) string {
        return strings.ToUpper(l.String())
    }
}

Testing Configuration

func TestMain(m *testing.M) {
    // Configure for testing
    zerolog.SetGlobalLevel(zerolog.DebugLevel)
    zerolog.DisableSampling(true)

    // Use frozen time
    testTime := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
    zerolog.TimestampFunc = func() time.Time { return testTime }

    code := m.Run()
    os.Exit(code)
}

Structured Logging for Kubernetes

func init() {
    // JSON with standard fields
    zerolog.TimestampFieldName = "@timestamp"
    zerolog.TimeFieldFormat = time.RFC3339Nano

    // Add pod info in application code via context
}

Best Practices

1. Configure Early

Set global configuration in init() or early in main():

func init() {
    zerolog.TimeFieldFormat = zerolog.TimeFormatUnixMs
    zerolog.SetGlobalLevel(zerolog.InfoLevel)
}

2. Environment-Based Configuration

Use environment variables for configuration:

func init() {
    if env := os.Getenv("LOG_LEVEL"); env != "" {
        if level, err := zerolog.ParseLevel(env); err == nil {
            zerolog.SetGlobalLevel(level)
        }
    }

    if os.Getenv("LOG_FORMAT") == "text" {
        zerolog.TimeFieldFormat = "2006-01-02 15:04:05"
    }
}

3. Document Custom Field Names

If you customize field names, document them:

// Log field names (customized for our infrastructure)
// - "ts": timestamp
// - "lvl": log level
// - "msg": message
func init() {
    zerolog.TimestampFieldName = "ts"
    zerolog.LevelFieldName = "lvl"
    zerolog.MessageFieldName = "msg"
}

4. Keep Marshalers Fast

Custom marshalers run for every event. Keep them fast:

// Good - fast
zerolog.CallerMarshalFunc = func(pc uintptr, file string, line int) string {
    return filepath.Base(file) + ":" + strconv.Itoa(line)
}

// Avoid - slow
zerolog.ErrorMarshalFunc = func(err error) interface{} {
    // Don't do expensive operations here
    details := fetchErrorDetails(err)  // BAD: database/API call
    return details
}

5. Use Standard Field Names

Unless you have specific requirements, use default field names:

// Good - standard names
// zerolog.TimestampFieldName = "time"  // default
// zerolog.LevelFieldName = "level"      // default

// Only customize when required by infrastructure
zerolog.LevelFieldName = "severity"  // Required by Google Cloud Logging

Thread Safety

  • All global configuration variables can be set during initialization
  • Changing configuration after loggers are created may have undefined behavior
  • SetGlobalLevel() and DisableSampling() use atomic operations and are thread-safe
  • Other global variables should only be set during initialization

See Also