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

JSON

JSON marshals any Go value to JSON; RawJSON accepts pre-serialized bytes. Both emit the result with syntax highlighting.

JSON highlighting

// Marshal a Go value
clog.Info().JSON("user", userStruct).Msg("ok")
clog.Info().JSON("config", map[string]any{"port": 8080, "debug": true}).Msg("started")

// Pre-serialized bytes (no marshal overhead)
clog.Error().
  Str("batch", "1/1").
  RawJSON("error", []byte(`{"status":"unprocessable_entity","detail":"validation failed","code":null}`)).
  Msg("Batch failed")
// ERR ❌ Batch failed batch=1/1 error={"status":"unprocessable_entity","detail":"validation failed","code":null}

Use JSON when you have a Go value to log; use RawJSON when you already have bytes (HTTP response bodies, json.RawMessage, database JSON columns) to avoid an unnecessary marshal/unmarshal round-trip. JSON logs the error string as the field value if marshalling fails.

Pretty-printed JSON is automatically flattened to a single line. Highlighting uses a Dracula-inspired colour scheme by default (space after commas included). Disable or customise it via FieldJSON in Styles:

// Disable highlighting
styles := clog.DefaultStyles()
styles.FieldJSON = nil
clog.SetStyles(styles)

// Custom colours
custom := clog.DefaultJSONStyles()
custom.Key = new(lipgloss.NewStyle().Foreground(lipgloss.Color("#50fa7b")))
styles.FieldJSON = custom
clog.SetStyles(styles)

Number is the base fallback for all numeric tokens. Five sub-styles allow finer control and fall back to Number when nil:

FieldApplies to
NumberPositivePositive numbers (with or without explicit +)
NumberNegativeNegative numbers
NumberZeroZero (falls back to NumberPositive, then Number)
NumberFloatFloating-point values
NumberIntegerInteger values
custom := clog.DefaultJSONStyles()
custom.NumberNegative = new(lipgloss.NewStyle().Foreground(lipgloss.Color("1"))) // red
custom.NumberZero = new(lipgloss.NewStyle().Foreground(lipgloss.Color("8")))     // grey
styles.FieldJSON = custom
clog.SetStyles(styles)

Rendering Modes

Set JSONStyles.Mode to control how JSON structure is rendered:

ModeDescriptionExample
JSONModeJSONStandard JSON (default){"status":"ok","count":42}
JSONModeHumanUnquote keys and simple string values{status:ok, count:42}
JSONModeFlatFlatten nested object keys with dot notation; arrays kept intact{status:ok, meta.region:us-east-1}

JSONModeHuman - keys are unquoted unless they contain ,{}[]\s:#"' or start with ////*. String values are unquoted unless they start with a forbidden character, end with whitespace, are ambiguous as a JSON keyword (true, false, null), or look like a number. Empty strings always render as "".

styles.FieldJSON = clog.DefaultJSONStyles()
styles.FieldJSON.Mode = clog.JSONModeHuman

clog.Info().
  RawJSON("response", []byte(`{"status":"ok","count":42,"active":true,"deleted_at":null}`)).
  Msg("Fetched")
// INF ℹ️ Fetched response={status:ok, count:42, active:true, deleted_at:null}

JSONModeFlat - nested objects are recursed into and their keys joined with .; arrays are kept intact as values:

styles.FieldJSON.Mode = clog.JSONModeFlat

clog.Info().
  RawJSON("resp", []byte(`{"user":{"name":"alice","role":"admin"},"tags":["a","b"]}`)).
  Msg("Auth")
// INF ℹ️ Auth resp={user.name:alice, user.role:admin, tags:[a, b]}

Spacing

JSONStyles.Spacing is a bitmask controlling where spaces are inserted. The default (DefaultJSONStyles) adds a space after commas.

FlagEffectExample
JSONSpacingAfterColonSpace after :{"key": "value"}
JSONSpacingAfterCommaSpace after ,{"a":1, "b":2}
JSONSpacingBeforeObjectSpace before a nested {{"key": {"n":1}}
JSONSpacingBeforeArraySpace before a nested [{"tags": ["a","b"]}
JSONSpacingAllAll of the above{"key": {"n": 1}, "tags": ["a"]}
// Fluent builder
styles.FieldJSON = clog.DefaultJSONStyles().WithSpacing(clog.JSONSpacingAll)

// Direct assignment
styles.FieldJSON.Spacing = clog.JSONSpacingAfterComma | clog.JSONSpacingBeforeObject

JSONSpacingAfterColon and JSONSpacingBeforeObject/JSONSpacingBeforeArray are independent - combining them produces two spaces before a nested value.

Omitting Commas

Set OmitCommas: true to drop the , separator. Combine with JSONSpacingAfterComma to keep a space in its place:

styles.FieldJSON.OmitCommas = true
styles.FieldJSON.Spacing |= clog.JSONSpacingAfterComma

clog.Info().
  RawJSON("r", []byte(`{"a":1,"b":2,"c":true}`)).
  Msg("ok")
// INF ℹ️ ok r={a:1 b:2 c:true}