log

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: GPL-3.0 Imports: 10 Imported by: 0

Documentation

Overview

Package log provides the reeflective/team console logging system, so that applications embedding a teamclient/teamserver can reuse and restyle the exact same logging their team core uses.

The heart is ConsoleHandler, an slog.Handler rendering aligned, colored lines of the form "<time> <LEVEL> <package> <message>", with every column (level markers and colors, package/time/message colors, column widths, timestamp) configurable through ConsoleOptions and LevelStyle.

Typical uses:

  • Log in your own code with the team console style: NewConsole(opts), then Named(logger, pkg, stream) to get the aligned package column.
  • Replace the team core's logging entirely: pass a handler to server.WithLogger / client.WithLogger.
  • Only restyle the built-in console while keeping the core's file logger: server.WithConsoleOptions / client.WithConsoleOptions.

Because the core's filesystem is an afero.Afero (returned by Server.Filesystem() / Client.Filesystem()), a consumer running fully in-memory can build a Logger with New against that same ephemeral filesystem.

Index

Constants

View Source
const (
	LevelTrace = slog.LevelDebug - 4 // -8
	LevelFatal = slog.LevelError + 4 // 12
	LevelPanic = slog.LevelError + 8 // 16
)

Custom slog levels. slog only defines Debug/Info/Warn/Error; the teamserver logging additionally uses a lower Trace level and higher Fatal/Panic levels (the latter two abort the program, and are only meant for unrecoverable failures such as the certificate infrastructure).

View Source
const (
	// ClientLogFileExt is used as extension by all main teamclients log files by default.
	ClientLogFileExt = "teamclient.log"
	// ServerLogFileExt is used as extension by all teamservers core log files by default.
	ServerLogFileExt = "teamserver.log"
)
View Source
const PackageKey = "teamserver_pkg"

PackageKey is the attribute key identifying the name of the package (domain) specified by teamclients and teamservers named loggers.

View Source
const StreamKey = "stream"

StreamKey is the attribute key identifying the more precise flow/stream within a named logger's package/domain.

Variables

This section is empty.

Functions

func DefaultLevelStyles

func DefaultLevelStyles() map[slog.Level]LevelStyle

DefaultLevelStyles returns the built-in level markers: the level word, colored per severity. They are padded to a uniform column (see defaultLevelWidth) so messages stay aligned and the output reads calmly.

Restyling is meant to be trivial: copy this map, change the labels and/or colors you want (eg. to terse bracket markers like "[i]"/"[!]"), and set the result on ConsoleOptions.Levels — missing entries fall back to these defaults.

func Fatal

func Fatal(l *slog.Logger, msg string, args ...any)

Fatal logs a message at the custom Fatal level and then exits the program with status 1. It is reserved for unrecoverable failures (eg. the certificate infrastructure) where continuing would be unsafe.

func FileName

func FileName(name string, server bool) string

FileName takes a filename without extension and adds the corresponding teamserver/teamclient logfile extension.

func LevelFrom

func LevelFrom(level int) slog.Level

LevelFrom returns an slog.Level from an int, clamped to the [Trace, Panic] range.

func Named

func Named(logger *slog.Logger, pkg, stream string) *slog.Logger

Named tags a *slog.Logger with a package/domain and a more precise flow/stream, so the ConsoleHandler renders the aligned package column. It is sugar over logger.With(PackageKey, ...) / logger.With(StreamKey, ...).

func NewAudit

func NewAudit(w io.Writer) *slog.Logger

NewAudit returns a JSON-encoded audit logger writing to the given writer (eg. an opened audit.json file), at Debug level so every request is recorded.

func NewConsole

func NewConsole(opts ConsoleOptions) *slog.Logger

NewConsole returns a ready-to-use console *slog.Logger from the given options. It is the simplest way for a consumer to log with the team console style in its own code. Tag records with Named to get the aligned package column.

func NewFormatHandler

func NewFormatHandler(f Format, w io.Writer, level slog.Leveler, style *ConsoleOptions) slog.Handler

NewFormatHandler builds a standalone slog.Handler rendering the given format to w at the given level. For FormatConsole it uses ConsoleHandler with the given style (nil for defaults); text/json use the stdlib handlers and ignore style.

This is a convenience for consumers wiring their own logger; the team core builds its console/file handlers itself.

func NewJSON

func NewJSON(w io.Writer, level slog.Level) *slog.Logger

NewJSON returns a JSON-encoded logger writing to the given writer at the given level. The caller opens the destination (eg. a `<name>.json` file).

func Trace

func Trace(l *slog.Logger, msg string, args ...any)

Trace logs a message at the custom Trace level.

Types

type ConsoleHandler

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

ConsoleHandler is a slog.Handler rendering aligned, colored log lines of the form:

[HH:MM:SS] <level-marker> <package> <message> [key=value ...]

The timestamp is optional, the level marker and its color are configurable (see ConsoleOptions.Levels / LevelStyle), and the package column is padded so messages line up. Records are routed to stdout or stderr depending on their level (>= Warn goes to stderr), or to a single writer when one is set (used for file logging, in which case coloring is disabled and the caller is shown).

func NewConsoleHandler

func NewConsoleHandler(opts ConsoleOptions) *ConsoleHandler

NewConsoleHandler returns a ConsoleHandler ready to use.

func (*ConsoleHandler) Enabled

func (h *ConsoleHandler) Enabled(_ context.Context, level slog.Level) bool

Enabled implements slog.Handler.

func (*ConsoleHandler) Handle

func (h *ConsoleHandler) Handle(_ context.Context, rec slog.Record) error

Handle implements slog.Handler: it formats and writes a single record.

func (*ConsoleHandler) WithAttrs

func (h *ConsoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs implements slog.Handler.

func (*ConsoleHandler) WithGroup

func (h *ConsoleHandler) WithGroup(name string) slog.Handler

WithGroup implements slog.Handler.

type ConsoleOptions

type ConsoleOptions struct {
	// Level is the minimum level to log. Never nil for a working handler.
	Level slog.Leveler

	// Stdout/Stderr are the streams used for the level split. When Writer is
	// set, it takes precedence and both streams are ignored.
	Stdout io.Writer
	Stderr io.Writer

	// Writer, when set, receives all records (no stdout/stderr split). Used for
	// file logging.
	Writer io.Writer

	// Levels overrides the per-level markers/colors. Missing levels fall back to
	// DefaultLevelStyles(); a nil map uses the defaults entirely.
	Levels map[slog.Level]LevelStyle

	// PackageWidth is the column width the package/domain is padded to. Zero
	// uses defaultPackageWidth.
	PackageWidth int

	// LevelWidth is the column width the level marker is padded to. Zero uses
	// defaultLevelWidth.
	LevelWidth int

	// PackageColor, TimeColor and MessageColor are the carapace/style colors for
	// the package column, the timestamp and the message. Empty uses balanced
	// defaults (a muted/dimmed package, a faint timestamp, a bright message).
	// These make the non-level parts of a line as restyleable as the levels.
	PackageColor string
	TimeColor    string
	MessageColor string

	// DisableColors renders plain (uncolored) output. Automatically implied when
	// writing to a file.
	DisableColors bool

	// ShowTimestamp prepends a formatted timestamp to each line.
	ShowTimestamp bool

	// TimestampFormat is the layout used when ShowTimestamp is true. Empty uses
	// defaultTimeFormat.
	TimestampFormat string

	// AddSource renders the source [file:line] of the log call site.
	AddSource bool
}

ConsoleOptions configures a ConsoleHandler.

type Format

type Format string

Format selects how console/stdio log records are rendered. All three formats are backed by the standard library (or this package) with no extra dependencies.

const (
	// FormatConsole is the default: aligned, colored, human-readable output
	// rendered by ConsoleHandler.
	FormatConsole Format = "console"
	// FormatText is slog's TextHandler: uncolored logfmt "key=value" pairs,
	// friendly to grep/awk and log shippers.
	FormatText Format = "text"
	// FormatJSON is slog's JSONHandler: structured records for ingestion by log
	// pipelines (Loki, ELK, CloudWatch...).
	FormatJSON Format = "json"
)

func Formats

func Formats() []Format

Formats returns all supported log formats, in a stable order. Useful to drive CLI flag validation and shell completion.

func (Format) Describe

func (f Format) Describe() string

Describe returns a one-line description of a format, for completion/help.

func (Format) String

func (f Format) String() string

String implements fmt.Stringer.

func (Format) Valid

func (f Format) Valid() bool

Valid reports whether f is a supported format.

type LevelStyle

type LevelStyle struct {
	Label string
	Color string
}

LevelStyle describes how a single log level is rendered on the console: a short label (eg. "[i]") and the color applied to it. The color is a carapace/style name (see github.com/carapace-sh/carapace/pkg/style).

The whole point of this type is that level markers are trivially changeable: copy DefaultLevelStyles(), tweak the labels/colors you want, and set the result on ConsoleOptions.Levels.

type Logger

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

Logger is the unified logging backend shared by teamclients and teamservers. It wraps a single *slog.Logger whose handler, by default, fans out log records to a colored console (with a stdout/stderr level split) and to a text log file, each with its own runtime-adjustable level. It can also wrap a single user-provided slog.Handler, in which case the console/file split and the level knobs do not apply.

It is exported so that consumers running the core in-memory (server.WithInMemory / client.WithInMemory) can build their OWN ephemeral logger: open a file on the filesystem returned by Server.Filesystem() / Client.Filesystem() and pass it as the io.Writer to New.

func New

func New(logFile io.Writer, stdioLevel, fileLevel slog.Level, style func(*ConsoleOptions)) *Logger

New builds the default teamserver/teamclient logger: a colored console logger (info/debug/trace to stdout, warn and above to stderr), tee'd with a plain-text log file when logFile is non-nil.

logFile is any io.Writer — the caller opens it however it wants (os.OpenFile, an afero file for in-memory use, a buffer...). Pass nil for a console-only logger.

The optional style callback restyles the console/file columns (level markers, colors, timestamp, widths) before the handlers are built; it is applied on top of the built-in defaults (timestamps on), so a nil callback yields the default look. The library controls the level/output fields itself.

func NewFromHandler

func NewFromHandler(handler slog.Handler) *Logger

NewFromHandler wraps a user-provided slog.Handler as the sole logging backend. The console/file split and SetLevel knobs do not apply to such a logger.

func NewStdio

func NewStdio(level slog.Level) *Logger

NewStdio returns a console-only logger (no log file):

  • Info/Debug/Trace records are written to os.Stdout.
  • Warn/Error/Fatal/Panic records are written to os.Stderr.

func (*Logger) Logger

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

Logger returns the underlying *slog.Logger.

func (*Logger) Named

func (l *Logger) Named(pkg, stream string) *slog.Logger

Named returns a logger tagged with a package/domain and a more precise flow/stream, rendered by the console handler and recorded as attributes.

func (*Logger) SetLevel

func (l *Logger) SetLevel(level slog.Level)

SetLevel adjusts the console and file logging levels at runtime. It is a no-op for loggers built from a custom handler (NewFromHandler).

func (*Logger) SetLogFormat

func (l *Logger) SetLogFormat(format Format)

SetLogFormat rebuilds the console/stdio stream in the given format (console, text or json). The file logger always stays plain text. It is meant to be set once at startup (eg. from a --log-format CLI flag); loggers already obtained via Named keep their previous format, so apply it before heavy logging. It is a no-op for a custom-handler logger (NewFromHandler) or an invalid format.

func (*Logger) SetOutput

func (l *Logger) SetOutput(stdout, stderr io.Writer)

SetOutput redirects the console stdout and stderr streams at runtime (eg. onto a cobra command's output streams). A nil stream is left unchanged, and the call is a no-op for loggers built from a custom handler (NewFromHandler).

Jump to

Keyboard shortcuts

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