Help us shape the future of Go! Take the 2026 Go Developer Survey

logging

package
v0.37.1 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package logging builds bentoo's diagnostics logger on log/slog.

One logger is built per invocation by the root command and handed to every component that emits diagnostics — through the command's context (NewContext/FromContext) or a component's constructor options — never through package-level state. It writes key=value lines to stderr and JSON lines to $XDG_STATE_HOME/bentoo/logs/bentoo.log, and every value secrets.Lookup resolved is scrubbed from both by NewRedactingHandler.

Index

Constants

View Source
const FileName = "bentoo.log"

FileName is the log file's name inside the log directory.

Variables

This section is empty.

Functions

func DefaultLogDir

func DefaultLogDir() (string, error)

DefaultLogDir returns $XDG_STATE_HOME/bentoo/logs, or ~/.local/state/bentoo/logs when XDG_STATE_HOME is unset or empty.

func FileLevel

func FileLevel(terminal slog.Level) slog.Level

FileLevel returns the log file's level for a terminal level: info, or debug when the terminal is debug, so --quiet and a raised BENTOO_LOG_LEVEL never remove info diagnostics from the file.

func FromContext

func FromContext(ctx context.Context) *slog.Logger

FromContext returns the logger NewContext stored in ctx, or a logger that discards everything when none was stored.

func Hold added in v0.36.0

func Hold(l *slog.Logger) (held *slog.Logger, release func())

Hold returns a logger that keeps back the terminal copy of every record it receives, and a release func that hands the kept records, in the order they were logged, to the terminal sink and makes the logger write through from then on.

A caller holds the invocation logger while something else draws on the terminal the logger writes to: a line written under bubbletea's inline frame moves the cursor without the renderer knowing, so its next redraw lands on the wrong rows and leaves the old frame behind.

Only the terminal is held: on a logger New built with a log file, the file still gets each record at once, redacted as an unheld logger redacts it. A logger of any other shape is held whole. The queue keeps the newest maxHeldRecords records, and the release first writes one WARN line counting any it dropped.

Loggers derived from the held one with With or WithGroup share its hold. A record the terminal sink would drop is not kept. release may be called more than once; only the first call replays.

func New

func New(opts Options) (*slog.Logger, func() error, error)

New builds the invocation logger: a text handler on opts.Stderr at opts.Level without the top-level time attribute and, when opts.LogDir is not empty, a JSON handler appending to LogDir/bentoo.log at FileLevel(Level), both behind one redacting handler. The returned func closes the log file; it may be called more than once.

When the directory or file cannot be created or opened, New still returns a usable stderr-only logger and a no-op close func, together with an error naming the path and the cause; the caller reports it.

func NewContext

func NewContext(ctx context.Context, l *slog.Logger) context.Context

NewContext returns a copy of ctx carrying l.

func NewRedactingHandler

func NewRedactingHandler(next slog.Handler, resolved func() []string) slog.Handler

NewRedactingHandler wraps next so that every value resolved returns is replaced with "***" in the message and in every attribute value — string, error, any other kind rendered as text, at any group depth, including attributes bound with With/WithGroup — and the value of every credential-named key is written as "***". resolved is called once per record, so a secret resolved after the handler was built is still redacted. A nil resolved means no resolved values.

func OrDiscard

func OrDiscard(l *slog.Logger) *slog.Logger

OrDiscard returns l, or a logger that discards everything when l is nil.

func ResolveLevel

func ResolveLevel(verbose, quiet bool, env string) (slog.Level, error)

ResolveLevel returns the terminal level: error under quiet, debug under verbose, else the level env names (BENTOO_LOG_LEVEL's value), else info. The flags are checked first, so an invalid env next to a flag is no error. An env value other than the four accepted words returns info and an error naming it; ResolveLevel itself never writes anything — the caller reports it.

Types

type Options

type Options struct {
	// Stderr receives the key=value lines at Level and above.
	Stderr io.Writer
	// LogDir is the directory holding FileName; "" writes no file.
	LogDir string
	// Level is the terminal level; the file level is FileLevel(Level).
	Level slog.Level
	// Resolved returns the secret values to scrub; nil means none.
	Resolved func() []string
}

Options configures New.

Jump to

Keyboard shortcuts

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