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
- func DefaultLevelStyles() map[slog.Level]LevelStyle
- func Fatal(l *slog.Logger, msg string, args ...any)
- func FileName(name string, server bool) string
- func LevelFrom(level int) slog.Level
- func Named(logger *slog.Logger, pkg, stream string) *slog.Logger
- func NewAudit(w io.Writer) *slog.Logger
- func NewConsole(opts ConsoleOptions) *slog.Logger
- func NewFormatHandler(f Format, w io.Writer, level slog.Leveler, style *ConsoleOptions) slog.Handler
- func NewJSON(w io.Writer, level slog.Level) *slog.Logger
- func Trace(l *slog.Logger, msg string, args ...any)
- type ConsoleHandler
- type ConsoleOptions
- type Format
- type LevelStyle
- type Logger
Constants ¶
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).
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" )
const PackageKey = "teamserver_pkg"
PackageKey is the attribute key identifying the name of the package (domain) specified by teamclients and teamservers named loggers.
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 ¶
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 ¶
FileName takes a filename without extension and adds the corresponding teamserver/teamclient logfile extension.
func Named ¶
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 ¶
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.
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) Handle ¶
Handle implements slog.Handler: it formats and writes a single record.
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.
type LevelStyle ¶
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 ¶
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 ¶
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 ¶
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) Named ¶
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 ¶
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 ¶
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.