Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Structured Fields

Events and contexts support typed field methods. All methods are safe to call on a nil receiver (disabled events are no-ops).

Event Fields

MethodSignatureDescription
AnErrAnErr(key string, err error)Error as keyed field (no-op if nil); unlike Err, no special Send/Msg behavior
AnyAny(key string, val any)Arbitrary value
AnysAnys(key string, vals []any)Arbitrary value slice
Base64Base64(key string, val []byte)Byte slice as base64 string
BoolBool(key string, val bool)Boolean field
BoolsBools(key string, vals []bool)Boolean slice field
BytesBytes(key string, val []byte)Byte slice - auto-detected as JSON with highlighting, otherwise string
ColumnColumn(key, path string, line, column int)Clickable file:line:column hyperlink
DiscardDiscard()Disables the event; returns nil to short-circuit subsequent methods
DictDict(key string, dict *Event)Nested fields with dot-notation keys
DurationDuration(key string, val time.Duration)Duration field
DurationsDurations(key string, vals []time.Duration)Duration slice field
EnabledEnabled() boolReturns true if the event is enabled (non-nil)
DisabledDisabled() boolReturns true if the event is disabled (nil)
ErrErr(err error)Attach error; Send uses it as message, Msg/Msgf add "error" field
ErrsErrs(key string, vals []error)Error slice as string slice (nil errors render as <nil>)
Float32Float32(key string, val float32)32-bit float field
Float64Float64(key string, val float64)64-bit float field
Floats32Floats32(key string, vals []float32)32-bit float slice field
Floats64Floats64(key string, vals []float64)64-bit float slice field
FractionFraction(key string, current, total int, ...Option)Current/total field with gradient color (e.g. 3/10)
FuncFunc(fn func(*Event))Lazy field builder; callback skipped on nil (disabled) events
HexHex(key string, val []byte)Byte slice as hex string
IntInt(key string, val int)Integer field
Int8Int8(key string, val int8)8-bit integer field
Int16Int16(key string, val int16)16-bit integer field
Int32Int32(key string, val int32)32-bit integer field
Int64Int64(key string, val int64)64-bit integer field
IntsInts(key string, vals []int)Integer slice field
Ints8Ints8(key string, vals []int8)8-bit integer slice field
Ints16Ints16(key string, vals []int16)16-bit integer slice field
Ints32Ints32(key string, vals []int32)32-bit integer slice field
Ints64Ints64(key string, vals []int64)64-bit integer slice field
JSONJSON(key string, val any)Marshals val to JSON with syntax highlighting
LineLine(key, path string, line int)Clickable file:line hyperlink
LinkLink(key, url, text string)Clickable URL hyperlink
LinksLinks(key string, links []Link)Clickable URL hyperlink slice
MsgFuncMsgFunc(createMsg func() string)Finalise with lazily-computed message; fn skipped on nil events
PathPath(key, path string)Clickable file/directory hyperlink
PercentPercent(key string, val float64, opts ...percent.Option)Percentage with gradient color; accepts [percent.Option] values
QuantitiesQuantities(key string, vals []string)Quantity slice field
QuantityQuantity(key, val string)Quantity field (e.g. "10GB")
RawJSONRawJSON(key string, val []byte)Pre-serialized JSON bytes, emitted verbatim with syntax highlighting
StrStr(key, val string)String field
StringerStringer(key string, val fmt.Stringer)Calls String() (nil-safe)
StringersStringers(key string, vals []fmt.Stringer)Slice of fmt.Stringer values
StrsStrs(key string, vals []string)String slice field
TimeTime(key string, val time.Time)Time field
TimeDiffTimeDiff(key string, t, start time.Time)Duration between two times (zero if t is not after start)
TimesTimes(key string, vals []time.Time)Time slice field
UintUint(key string, val uint)Unsigned integer field
Uint8Uint8(key string, val uint8)8-bit unsigned integer field
Uint16Uint16(key string, val uint16)16-bit unsigned integer field
Uint32Uint32(key string, val uint32)32-bit unsigned integer field
Uint64Uint64(key string, val uint64)64-bit unsigned integer field
UintsUints(key string, vals []uint)Unsigned integer slice field
Uints8Uints8(key string, vals []uint8)8-bit unsigned integer slice field
Uints16Uints16(key string, vals []uint16)16-bit unsigned integer slice field
Uints32Uints32(key string, vals []uint32)32-bit unsigned integer slice field
Uints64Uints64(key string, vals []uint64)64-bit unsigned integer slice field
URLURL(key, url string)Clickable URL hyperlink (URL as text)
URLsURLs(key string, urls []string)Clickable URL hyperlink slice (URLs as text)
WhenWhen(condition bool, fn func(*Event))Conditional field builder; fn called only when condition is true

Slice Formatting

Slice fields render as [a, b, c] by default. The brackets and separator are configurable:

clog.SetSliceSeparator(" ")        // [a b c]
clog.SetSliceBrackets('(', ')')    // (a, b, c)
clog.SetSliceBrackets('«', '»')    // «a, b, c»
clog.SetSliceBracket('|')          // |a, b, c| - same char for open and close

Duration Formatting

By default, Duration fields use Go’s built-in time.Duration.String() (e.g. 3.2s, 1m30s). Use SetDurationFormatFunc to apply a custom formatter globally:

clog.SetDurationFormatFunc(commonutil.FormatDuration)

clog.Info().Duration("took", time.Since(start)).Msg("done")
// INF ℹ️ done took=2.3s

SetDurationFormatFunc also applies as a fallback for Elapsed fields. See Elapsed Configuration for details.

Duration Gradient

Duration fields support the same green → yellow → red gradient as Elapsed fields. Enable it by setting a max duration:

clog.SetDurationGradientMax(20 * time.Second)

clog.Info().Duration("duration", 500*time.Millisecond).Msg("fast")  // green
clog.Info().Duration("duration", 10*time.Second).Msg("medium")       // yellow
clog.Info().Duration("duration", 25*time.Second).Msg("slow")         // red (clamped)

When active, the gradient overrides FieldDurationNumber / FieldDurationUnit. See Duration Gradient in the styles reference for gradient mode and custom stop configuration.

Nested Fields (Dict)

Group related fields under a common key prefix using dot notation:

clog.Info().Dict("request", clog.Dict().
  Str("method", "GET").
  Int("status", 200),
).Msg("Handled")
// INF ℹ️ Handled request.method=GET request.status=200

Works with sub-loggers too:

logger := clog.With().Dict("db", clog.Dict().
  Str("host", "localhost").
  Int("port", 5432),
).Logger()

Finalising Events

clog.Info().Str("k", "v").Msg("message")  // Log with message
clog.Info().Str("k", "v").Msgf("n=%d", 5) // Log with formatted message
clog.Info().Str("k", "v").Send()           // Log with empty message
clog.Error().Err(err).Send()               // Log with error as message (no error= field)
clog.Error().Err(err).Msg("failed")        // Log with message + error= field

// Lazy message - fn only called when event is enabled:
clog.Debug().MsgFunc(func() string { return expensiveString() })