core

package
v0.11.17 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 5, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package core provides shared value types used by both the root clog package and subpackages like fx/. It lives under internal/ to prevent external consumers from depending on it directly.

Index

Constants

View Source
const ErrorKey = "error"

ErrorKey is the default field key used by Err methods.

View Source
const Nil = "<nil>"

Nil is the string representation used for nil values.

Variables

This section is empty.

Functions

func AppendRepaint added in v0.11.0

func AppendRepaint(buf *strings.Builder, lines []string, prevRows, width int) int

AppendRepaint appends an overwrite-in-place repaint of lines over the previously rendered block of prevRows physical rows, bracketed by DEC 2026 synchronized-output markers. The block is not erased up front - that would flash blank on terminals without synchronized output - instead each line clears only the rows it touches, and rows the new frame no longer covers are erased at the end. Returns the physical row count of the new frame.

func BlockRows added in v0.11.0

func BlockRows(lines []string, termWidth int) int

BlockRows returns the total number of physical terminal rows a block of lines occupies once wrapping at termWidth is accounted for.

func ClampPercent

func ClampPercent(val, r float64) float64

ClampPercent restricts val to the [0, r] range. NaN and negative infinity clamp to 0; positive infinity clamps to r.

func ErrSliceToStrings

func ErrSliceToStrings(errs []error) []string

ErrSliceToStrings converts a slice of errors to a slice of strings. Nil errors are rendered as Nil ("<nil>").

func FrameRows added in v0.11.0

func FrameRows(line string, termWidth int) int

FrameRows returns the number of physical terminal rows the rendered line occupies once wrapping at termWidth is accounted for. ANSI escape codes are stripped before measuring. Falls back to 1 when the width is unknown (e.g. Output.Width() == 0).

func IsNilStringer

func IsNilStringer(val fmt.Stringer) bool

IsNilStringer reports whether val is nil, either as an untyped nil interface or as a typed nil whose underlying kind supports IsNil.

func SyncFrame added in v0.11.0

func SyncFrame(s string) string

SyncFrame brackets s with DEC 2026 synchronized-output markers so supporting terminals apply the whole sequence atomically (no tearing); terminals without support ignore the markers.

Types

type ElapsedField

type ElapsedField time.Duration

ElapsedField wraps a time.Duration so formatValue can identify it for elapsed-time styling.

type Field

type Field struct {
	Key   string `json:"key"`
	Value any    `json:"value"`
}

Field is a typed key-value pair attached to a log entry.

func MergeFields

func MergeFields(base, overrides []Field) []Field

MergeFields merges base fields with overrides, replacing existing keys. Keys in overrides replace matching keys in base while preserving order.

type FieldBuilder

type FieldBuilder[T any] struct {
	Fields []Field
	Self   *T
}

FieldBuilder provides common field-appending methods for fluent builders. Embed it and call InitSelf in the constructor to enable method chaining.

func (*FieldBuilder[T]) AnErr added in v0.7.0

func (fb *FieldBuilder[T]) AnErr(key string, err error) *T

AnErr adds an error as a keyed field. No-op if err is nil.

func (*FieldBuilder[T]) Any

func (fb *FieldBuilder[T]) Any(key string, val any) *T

Any adds a field with an arbitrary value.

func (*FieldBuilder[T]) Anys

func (fb *FieldBuilder[T]) Anys(key string, vals []any) *T

Anys adds a slice of arbitrary values.

func (*FieldBuilder[T]) Base64

func (fb *FieldBuilder[T]) Base64(key string, val []byte) *T

Base64 adds a []byte field encoded as a base64 string.

func (*FieldBuilder[T]) Bool

func (fb *FieldBuilder[T]) Bool(key string, val bool) *T

Bool adds a bool field.

func (*FieldBuilder[T]) Bools

func (fb *FieldBuilder[T]) Bools(key string, vals []bool) *T

Bools adds a bool slice field.

func (*FieldBuilder[T]) Bytes

func (fb *FieldBuilder[T]) Bytes(key string, val []byte) *T

Bytes adds a []byte field. If val is valid JSON it is stored as RawJSON with syntax highlighting; otherwise it is stored as a plain string.

func (*FieldBuilder[T]) Duration

func (fb *FieldBuilder[T]) Duration(key string, val time.Duration) *T

Duration adds a time.Duration field.

func (*FieldBuilder[T]) Durations

func (fb *FieldBuilder[T]) Durations(key string, vals []time.Duration) *T

Durations adds a time.Duration slice field.

func (*FieldBuilder[T]) Err

func (fb *FieldBuilder[T]) Err(err error) *T

Err adds an error field with key "error". No-op if err is nil.

func (*FieldBuilder[T]) Errs

func (fb *FieldBuilder[T]) Errs(key string, vals []error) *T

Errs adds an error slice field. Each error is converted to its message string; nil errors are rendered as Nil ("<nil>").

func (*FieldBuilder[T]) Float32 added in v0.7.0

func (fb *FieldBuilder[T]) Float32(key string, val float32) *T

Float32 adds a float32 field.

func (*FieldBuilder[T]) Float64

func (fb *FieldBuilder[T]) Float64(key string, val float64) *T

Float64 adds a float64 field.

func (*FieldBuilder[T]) Floats32 added in v0.7.0

func (fb *FieldBuilder[T]) Floats32(key string, vals []float32) *T

Floats32 adds a float32 slice field.

func (*FieldBuilder[T]) Floats64

func (fb *FieldBuilder[T]) Floats64(key string, vals []float64) *T

Floats64 adds a float64 slice field.

func (*FieldBuilder[T]) Fraction added in v0.7.26

func (fb *FieldBuilder[T]) Fraction(key string, current, total int, opts ...func(*Fraction)) *T

Fraction adds a current/total field with gradient color styling. The color is interpolated based on current/total progress.

func (*FieldBuilder[T]) Hex

func (fb *FieldBuilder[T]) Hex(key string, val []byte) *T

Hex adds a []byte field encoded as a hex string.

func (*FieldBuilder[T]) InitSelf

func (fb *FieldBuilder[T]) InitSelf(s *T)

InitSelf sets the self-pointer for method chaining.

func (*FieldBuilder[T]) Int

func (fb *FieldBuilder[T]) Int(key string, val int) *T

Int adds an int field.

func (*FieldBuilder[T]) Int8 added in v0.7.0

func (fb *FieldBuilder[T]) Int8(key string, val int8) *T

Int8 adds an int8 field.

func (*FieldBuilder[T]) Int16 added in v0.7.0

func (fb *FieldBuilder[T]) Int16(key string, val int16) *T

Int16 adds an int16 field.

func (*FieldBuilder[T]) Int32 added in v0.7.0

func (fb *FieldBuilder[T]) Int32(key string, val int32) *T

Int32 adds an int32 field.

func (*FieldBuilder[T]) Int64

func (fb *FieldBuilder[T]) Int64(key string, val int64) *T

Int64 adds an int64 field.

func (*FieldBuilder[T]) Ints

func (fb *FieldBuilder[T]) Ints(key string, vals []int) *T

Ints adds an int slice field.

func (*FieldBuilder[T]) Ints8 added in v0.7.0

func (fb *FieldBuilder[T]) Ints8(key string, vals []int8) *T

Ints8 adds an int8 slice field.

func (*FieldBuilder[T]) Ints16 added in v0.7.0

func (fb *FieldBuilder[T]) Ints16(key string, vals []int16) *T

Ints16 adds an int16 slice field.

func (*FieldBuilder[T]) Ints32 added in v0.7.0

func (fb *FieldBuilder[T]) Ints32(key string, vals []int32) *T

Ints32 adds an int32 slice field.

func (*FieldBuilder[T]) Ints64

func (fb *FieldBuilder[T]) Ints64(key string, vals []int64) *T

Ints64 adds an int64 slice field.

func (*FieldBuilder[T]) JSON

func (fb *FieldBuilder[T]) JSON(key string, val any) *T

JSON marshals val to JSON and adds it as a highlighted field. On marshal error the field value is the error string.

func (*FieldBuilder[T]) Percent

func (fb *FieldBuilder[T]) Percent(key string, val float64, opts ...func(*Percent)) *T

Percent adds a percentage field with gradient color styling. The value is stored as-is; use [Event.Percent] for clamped input.

func (*FieldBuilder[T]) Quantities

func (fb *FieldBuilder[T]) Quantities(key string, vals []string) *T

Quantities adds a quantity string slice field.

func (*FieldBuilder[T]) Quantity

func (fb *FieldBuilder[T]) Quantity(key, val string) *T

Quantity adds a quantity string field where numeric and unit segments are styled independently (e.g. "5m", "5.1km", "100MB").

func (*FieldBuilder[T]) RawJSON

func (fb *FieldBuilder[T]) RawJSON(key string, val []byte) *T

RawJSON adds a field with pre-serialized JSON bytes, emitted verbatim without quoting or escaping.

func (*FieldBuilder[T]) Str

func (fb *FieldBuilder[T]) Str(key, val string) *T

Str adds a string field.

func (*FieldBuilder[T]) Stringer

func (fb *FieldBuilder[T]) Stringer(key string, val fmt.Stringer) *T

Stringer adds a field by calling the value's String method. No-op if val is nil.

func (*FieldBuilder[T]) Stringers

func (fb *FieldBuilder[T]) Stringers(key string, vals []fmt.Stringer) *T

Stringers adds a field with a slice of fmt.Stringer values.

func (*FieldBuilder[T]) Strs

func (fb *FieldBuilder[T]) Strs(key string, vals []string) *T

Strs adds a string slice field.

func (*FieldBuilder[T]) Time

func (fb *FieldBuilder[T]) Time(key string, val time.Time) *T

Time adds a time.Time field.

func (*FieldBuilder[T]) TimeDiff added in v0.7.0

func (fb *FieldBuilder[T]) TimeDiff(key string, t, start time.Time) *T

TimeDiff adds the field key with the duration between t and start. If t is not after start, the duration is zero.

func (*FieldBuilder[T]) Times

func (fb *FieldBuilder[T]) Times(key string, vals []time.Time) *T

Times adds a time.Time slice field.

func (*FieldBuilder[T]) Uint

func (fb *FieldBuilder[T]) Uint(key string, val uint) *T

Uint adds a uint field.

func (*FieldBuilder[T]) Uint8 added in v0.7.0

func (fb *FieldBuilder[T]) Uint8(key string, val uint8) *T

Uint8 adds a uint8 field.

func (*FieldBuilder[T]) Uint16 added in v0.7.0

func (fb *FieldBuilder[T]) Uint16(key string, val uint16) *T

Uint16 adds a uint16 field.

func (*FieldBuilder[T]) Uint32 added in v0.7.0

func (fb *FieldBuilder[T]) Uint32(key string, val uint32) *T

Uint32 adds a uint32 field.

func (*FieldBuilder[T]) Uint64

func (fb *FieldBuilder[T]) Uint64(key string, val uint64) *T

Uint64 adds a uint64 field.

func (*FieldBuilder[T]) Uints

func (fb *FieldBuilder[T]) Uints(key string, vals []uint) *T

Uints adds a uint slice field.

func (*FieldBuilder[T]) Uints8 added in v0.7.0

func (fb *FieldBuilder[T]) Uints8(key string, vals []uint8) *T

Uints8 adds a uint8 slice field.

func (*FieldBuilder[T]) Uints16 added in v0.7.0

func (fb *FieldBuilder[T]) Uints16(key string, vals []uint16) *T

Uints16 adds a uint16 slice field.

func (*FieldBuilder[T]) Uints32 added in v0.7.0

func (fb *FieldBuilder[T]) Uints32(key string, vals []uint32) *T

Uints32 adds a uint32 slice field.

func (*FieldBuilder[T]) Uints64

func (fb *FieldBuilder[T]) Uints64(key string, vals []uint64) *T

Uints64 adds a uint64 slice field.

func (*FieldBuilder[T]) When

func (fb *FieldBuilder[T]) When(condition bool, fn func(*T)) *T

When calls fn with the builder if condition is true.

type Fraction added in v0.7.26

type Fraction struct {
	Format  *NumberFormat
	Current int
	Total   int
	Reverse bool
}

Fraction holds a current/total pair rendered as "current/total" with gradient color styling based on current/total progress. When Reverse is true, the gradient is flipped (useful for countdowns). Format overrides the logger's numeric formatting for this field when non-nil.

type Level

type Level = level.Level

Level represents a log level.

type LiveRegion added in v0.11.0

type LiveRegion struct {
	// contains filtered or unexported fields
}

LiveRegion coordinates a single repaintable block of animation lines with regular log writes on the same terminal. All concurrent animations on one output - standalone spinners and bars as single-line slots, whole groups as multi-line slots - register here and are painted as one stacked block (in registration order) by a single shared render loop, so they never clobber each other. Log lines written through LiveRegion.WriteLines while the block is on screen displace it: the block is erased, the log line lands above, and the block is repainted below - all inside one synchronized-output frame so nothing tears or gets lost.

Single-writer discipline: while slots exist, every write to the terminal must go through this mutex - the render loop, slot registration, and log displacement all serialize here.

func NewLiveRegion added in v0.11.0

func NewLiveRegion(out io.Writer, width func() int) *LiveRegion

NewLiveRegion creates a LiveRegion writing to out. width is queried at every paint so wrapped-line row accounting tracks terminal resizes.

func (*LiveRegion) Active added in v0.11.0

func (r *LiveRegion) Active() bool

Active reports whether any animation slots are currently registered.

func (*LiveRegion) Register added in v0.11.0

func (r *LiveRegion) Register(render func(now time.Time) string, tick time.Duration) uint64

Register adds an animation slot rendered by render at the given tick rate and returns its id for LiveRegion.Unregister. The first registration hides the cursor and starts the shared render loop; the new slot is painted immediately rather than waiting for the next tick. render is only ever invoked under the region lock, so it needs no synchronization of its own beyond not calling back into the region. render may return a newline-separated multi-row block (e.g. a group of animations) or an empty string to contribute no rows this tick.

func (*LiveRegion) RenderFrame added in v0.11.0

func (r *LiveRegion) RenderFrame(now time.Time)

RenderFrame renders every slot at now and repaints the block in place, skipping the write entirely when neither the rendered lines nor the terminal width changed. Exported so animation owners can force an out-of-band frame (e.g. a progress bar's final 100% frame before unregistering) and so tests can drive the renderer deterministically.

func (*LiveRegion) Resume added in v0.11.14

func (r *LiveRegion) Resume()

Resume restores a previously suspended live region. It repaints the current slot state immediately and restarts the render loop. It is idempotent and does nothing when the region is not suspended or no slots are active.

func (*LiveRegion) Suspend added in v0.11.14

func (r *LiveRegion) Suspend(showCursor bool)

Suspend temporarily releases the terminal while keeping registered slots. It stops the render loop and erases the current live block. When showCursor is true it also shows the cursor for the released period. It is idempotent and does nothing when no slots are active.

func (*LiveRegion) Unregister added in v0.11.0

func (r *LiveRegion) Unregister(id uint64)

Unregister removes the slot with the given id, erases its line from the block, and repaints the remaining slots before returning. The last unregistration erases the whole block, stops the render loop, and shows the cursor again, leaving the cursor at the block's former top row so subsequent log lines land where the block used to start.

func (*LiveRegion) WriteLines added in v0.11.0

func (r *LiveRegion) WriteLines(s string)

WriteLines writes s (one or more fully formatted log lines) to the output. With no block on screen it is a plain write. While the block is live, the write displaces it: one synchronized frame erases the block, writes s where the block's top row was, and repaints the block below - so log lines scroll up naturally above the animations instead of being overpainted by the next frame. s should end with a newline; one is added if missing while a block is live, because the repaint must start at the beginning of a fresh row. While suspended, writes pass through without repainting the live block.

type NumberFormat added in v0.11.10

type NumberFormat int

NumberFormat controls how numeric field values (plain integers and both halves of a Fraction) are rendered.

NumberFormat implements encoding.TextMarshaler and encoding.TextUnmarshaler, so it works directly with flag.TextVar and most flag libraries.

const (
	// NumberPlain renders numbers verbatim with no grouping (the default),
	// e.g. "1234567".
	NumberPlain NumberFormat = iota // plain
	// NumberGrouped inserts a separator every three digits, e.g.
	// "1,234,567". The separator is configurable.
	NumberGrouped // grouped
	// NumberCompact renders an abbreviated form using K/M/B/T suffixes,
	// e.g. "1.2M". Values below the configured minimum render with digit
	// grouping instead (e.g. "9,999" before "10K").
	NumberCompact // compact
)

func (NumberFormat) MarshalText added in v0.11.10

func (f NumberFormat) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (NumberFormat) String added in v0.11.10

func (i NumberFormat) String() string

func (*NumberFormat) UnmarshalText added in v0.11.10

func (f *NumberFormat) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

type Part

type Part int

Part identifies a component of a formatted log line.

const (
	// PartTimestamp is the timestamp component.
	PartTimestamp Part = iota
	// PartLevel is the level label component.
	PartLevel
	// PartSymbol is the emoji symbol component.
	PartSymbol
	// PartMessage is the log message component.
	PartMessage
	// PartFields is the structured fields component.
	PartFields
)

type Percent

type Percent struct {
	Value   float64
	Reverse bool
	Maximum *float64
}

Percent holds a percentage value (0–100) with an optional reverse gradient flag. When Reverse is true, the gradient is flipped relative to the logger's default direction. Maximum overrides the global maximum for this field when non-nil.

type QuantityField

type QuantityField string

QuantityField wraps a string value with numeric and unit segments (e.g. "5m", "5.1km", "100MB") so formatValue can identify it for quantity styling.

type Quote added in v0.9.0

type Quote int

Quote controls how field values are quoted in log output.

const (
	// QuoteAuto quotes values only when they contain spaces, unprintable
	// characters, or embedded quotes. This is the default.
	QuoteAuto Quote = iota
	// QuoteAlways quotes all string, error, and default-kind values.
	QuoteAlways
	// QuoteNever disables quoting entirely.
	QuoteNever
)

type RawJSON

type RawJSON []byte

RawJSON wraps pre-serialized JSON bytes so formatValue can emit them verbatim without quoting or escaping.

type Sort

type Sort int

Sort controls how fields are sorted in output.

const (
	// SortNone preserves the insertion order of fields (default).
	SortNone Sort = iota
	// SortAscending sorts fields by key A→Z.
	SortAscending
	// SortDescending sorts fields by key Z→A.
	SortDescending
)

type TreeChars

type TreeChars struct {
	First    string // connector for TreeFirst  (default "├── ")
	Middle   string // connector for TreeMiddle (default "├── ")
	Last     string // connector for TreeLast   (default "└── ")
	Continue string // ancestor line when parent is First/Middle (default "│   ")
	Blank    string // ancestor line when parent is Last         (default "    ")
}

TreeChars defines the box-drawing characters used by tree indentation.

type TreePos

type TreePos int

TreePos identifies a node's position among its siblings in a tree.

const (
	// TreeFirst marks the first sibling.
	TreeFirst TreePos = iota
	// TreeMiddle marks a middle sibling (more siblings follow).
	TreeMiddle
	// TreeLast marks the last sibling (no more siblings follow).
	TreeLast
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL