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
- func AppendRepaint(buf *strings.Builder, lines []string, prevRows, width int) int
- func BlockRows(lines []string, termWidth int) int
- func ClampPercent(val, r float64) float64
- func ErrSliceToStrings(errs []error) []string
- func FrameRows(line string, termWidth int) int
- func IsNilStringer(val fmt.Stringer) bool
- func SyncFrame(s string) string
- type ElapsedField
- type Field
- type FieldBuilder
- func (fb *FieldBuilder[T]) AnErr(key string, err error) *T
- func (fb *FieldBuilder[T]) Any(key string, val any) *T
- func (fb *FieldBuilder[T]) Anys(key string, vals []any) *T
- func (fb *FieldBuilder[T]) Base64(key string, val []byte) *T
- func (fb *FieldBuilder[T]) Bool(key string, val bool) *T
- func (fb *FieldBuilder[T]) Bools(key string, vals []bool) *T
- func (fb *FieldBuilder[T]) Bytes(key string, val []byte) *T
- func (fb *FieldBuilder[T]) Duration(key string, val time.Duration) *T
- func (fb *FieldBuilder[T]) Durations(key string, vals []time.Duration) *T
- func (fb *FieldBuilder[T]) Err(err error) *T
- func (fb *FieldBuilder[T]) Errs(key string, vals []error) *T
- func (fb *FieldBuilder[T]) Float32(key string, val float32) *T
- func (fb *FieldBuilder[T]) Float64(key string, val float64) *T
- func (fb *FieldBuilder[T]) Floats32(key string, vals []float32) *T
- func (fb *FieldBuilder[T]) Floats64(key string, vals []float64) *T
- func (fb *FieldBuilder[T]) Fraction(key string, current, total int, opts ...func(*Fraction)) *T
- func (fb *FieldBuilder[T]) Hex(key string, val []byte) *T
- func (fb *FieldBuilder[T]) InitSelf(s *T)
- func (fb *FieldBuilder[T]) Int(key string, val int) *T
- func (fb *FieldBuilder[T]) Int8(key string, val int8) *T
- func (fb *FieldBuilder[T]) Int16(key string, val int16) *T
- func (fb *FieldBuilder[T]) Int32(key string, val int32) *T
- func (fb *FieldBuilder[T]) Int64(key string, val int64) *T
- func (fb *FieldBuilder[T]) Ints(key string, vals []int) *T
- func (fb *FieldBuilder[T]) Ints8(key string, vals []int8) *T
- func (fb *FieldBuilder[T]) Ints16(key string, vals []int16) *T
- func (fb *FieldBuilder[T]) Ints32(key string, vals []int32) *T
- func (fb *FieldBuilder[T]) Ints64(key string, vals []int64) *T
- func (fb *FieldBuilder[T]) JSON(key string, val any) *T
- func (fb *FieldBuilder[T]) Percent(key string, val float64, opts ...func(*Percent)) *T
- func (fb *FieldBuilder[T]) Quantities(key string, vals []string) *T
- func (fb *FieldBuilder[T]) Quantity(key, val string) *T
- func (fb *FieldBuilder[T]) RawJSON(key string, val []byte) *T
- func (fb *FieldBuilder[T]) Str(key, val string) *T
- func (fb *FieldBuilder[T]) Stringer(key string, val fmt.Stringer) *T
- func (fb *FieldBuilder[T]) Stringers(key string, vals []fmt.Stringer) *T
- func (fb *FieldBuilder[T]) Strs(key string, vals []string) *T
- func (fb *FieldBuilder[T]) Time(key string, val time.Time) *T
- func (fb *FieldBuilder[T]) TimeDiff(key string, t, start time.Time) *T
- func (fb *FieldBuilder[T]) Times(key string, vals []time.Time) *T
- func (fb *FieldBuilder[T]) Uint(key string, val uint) *T
- func (fb *FieldBuilder[T]) Uint8(key string, val uint8) *T
- func (fb *FieldBuilder[T]) Uint16(key string, val uint16) *T
- func (fb *FieldBuilder[T]) Uint32(key string, val uint32) *T
- func (fb *FieldBuilder[T]) Uint64(key string, val uint64) *T
- func (fb *FieldBuilder[T]) Uints(key string, vals []uint) *T
- func (fb *FieldBuilder[T]) Uints8(key string, vals []uint8) *T
- func (fb *FieldBuilder[T]) Uints16(key string, vals []uint16) *T
- func (fb *FieldBuilder[T]) Uints32(key string, vals []uint32) *T
- func (fb *FieldBuilder[T]) Uints64(key string, vals []uint64) *T
- func (fb *FieldBuilder[T]) When(condition bool, fn func(*T)) *T
- type Fraction
- type Level
- type LiveRegion
- func (r *LiveRegion) Active() bool
- func (r *LiveRegion) Register(render func(now time.Time) string, tick time.Duration) uint64
- func (r *LiveRegion) RenderFrame(now time.Time)
- func (r *LiveRegion) Resume()
- func (r *LiveRegion) Suspend(showCursor bool)
- func (r *LiveRegion) Unregister(id uint64)
- func (r *LiveRegion) WriteLines(s string)
- type NumberFormat
- type Part
- type Percent
- type QuantityField
- type Quote
- type RawJSON
- type Sort
- type TreeChars
- type TreePos
Constants ¶
const ErrorKey = "error"
ErrorKey is the default field key used by Err methods.
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
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
BlockRows returns the total number of physical terminal rows a block of lines occupies once wrapping at termWidth is accounted for.
func ClampPercent ¶
ClampPercent restricts val to the [0, r] range. NaN and negative infinity clamp to 0; positive infinity clamps to r.
func ErrSliceToStrings ¶
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
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 ¶
IsNilStringer reports whether val is nil, either as an untyped nil interface or as a typed nil whose underlying kind supports IsNil.
Types ¶
type ElapsedField ¶
ElapsedField wraps a time.Duration so formatValue can identify it for elapsed-time styling.
type Field ¶
Field is a typed key-value pair attached to a log entry.
func MergeFields ¶
MergeFields merges base fields with overrides, replacing existing keys. Keys in overrides replace matching keys in base while preserving order.
type FieldBuilder ¶
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 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
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 ¶
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.
type RawJSON ¶
type RawJSON []byte
RawJSON wraps pre-serialized JSON bytes so formatValue can emit them verbatim without quoting or escaping.
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.