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

logging

package
v0.5.3 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 37 Imported by: 0

Documentation

Overview

Package logging constructs application-owned structured loggers with safe defaults. It never changes slog.Default or installs a global subscriber.

Index

Constants

View Source
const (
	MaxContextFields     = 32
	MaxContextGroupItems = 16
	MaxContextKeyBytes   = 64
	MaxContextValueBytes = 1024
)

Request-scoped context field bounds. Excess fields are ignored; oversized string values are truncated at a UTF-8 boundary.

View Source
const MaxFallbackBytes = 256 << 10

MaxFallbackBytes bounds one record rewritten to stderr after its configured destination failed. Larger records are counted as dropped instead.

View Source
const MaxFileReadBytes = 1 << 20

Variables

This section is empty.

Functions

func AttrsFromContext

func AttrsFromContext(ctx context.Context) []slog.Attr

AttrsFromContext returns an owned copy of the context's log fields.

func ChannelSettingsConfigSchema

func ChannelSettingsConfigSchema() (*config.Schema[ChannelSettings], error)

ChannelSettingsConfigSchema reuses the shared file/environment/override loader.

func Correlate

func Correlate(handler slog.Handler) slog.Handler

Correlate adds a reserved correlation group from the context of each log call, plus a reserved "context" group holding fields attached with WithAttrs. JSON uses it by default. Custom application loggers can wrap their handler explicitly. It retains no context between calls and never includes vendor state, request bodies, subject identities or arbitrary context values. Pass a non-nil handler and keep application fields outside both reserved groups.

func JSON

func JSON(writer io.Writer, options Options) *slog.Logger

JSON uses slog's structured JSON handler, redacting common credential keys and respecting typed slog.LogValuer values such as secret.String. Unknown nested application objects must still use explicit safe logging contracts.

func WithAttrs

func WithAttrs(ctx context.Context, attrs ...slog.Attr) context.Context

WithAttrs returns a child context carrying request-scoped log fields. The JSON/Correlate handlers add them to every record logged with that context under the reserved "context" group. A later field replaces an earlier field with the same key. Only scalar values (string, integers, floats, bool, duration, time) and one level of groups are retained; LogValuer values are resolved first, credential-like keys are redacted and other values (maps, structs, errors, models) are ignored so they cannot leak into every record. ctx must be non-nil.

Types

type AsyncConfig

type AsyncConfig struct {
	Enabled  bool
	Queue    int
	MaxBytes int64
}

AsyncConfig enables one owned writer per sink. Records are copied into a bounded queue; a full queue drops the newest record and counts it rather than blocking the logging caller. Close drains every accepted record. Zero limits select 1,024 records and 4 MiB of pending record bytes.

func (AsyncConfig) Validate

func (c AsyncConfig) Validate() error

Validate checks asynchronous queue limits and rejects options on a disabled queue.

type ChannelName

type ChannelName string

ChannelName selects an instance, distinct from names of other service families.

func (ChannelName) Validate

func (n ChannelName) Validate() error

Validate validates the logging channel name.

type ChannelOption

type ChannelOption func(*channelOptions) error

ChannelOption supplies typed Go values for configured channels.

func WithHandler

func WithHandler(name ChannelName, handler slog.Handler) ChannelOption

WithHandler binds a custom slog.Handler to a channel. A channel absent from settings is added with the custom driver; a configured channel must select the custom driver, whose Level is applied as a minimum before the handler. The handler keeps its own ownership and receives records unchanged; wrap it with Correlate to add correlation and context fields.

type ChannelSet

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

ChannelSet owns configured sinks, never a borrowed default logger. Prepare is pure; Start acquires files and Close releases them after all borrowers drain. Copying the handle keeps one lifetime owner.

func PrepareChannels

func PrepareChannels(selected ChannelName, settings map[ChannelName]ChannelSettings, borrowedDefault *slog.Logger, options ...ChannelOption) (*ChannelSet, error)

PrepareChannels snapshots and validates named channels and stack dependencies, then prepares their sinks. The optional default logger is borrowed.

func (*ChannelSet) Channels

func (s *ChannelSet) Channels() *Channels

Channels returns the channel registry, or nil for an uninitialized set.

func (*ChannelSet) Close

func (s *ChannelSet) Close() error

Close closes owned sinks once and retains the close result for later calls.

func (*ChannelSet) FileSink

func (s *ChannelSet) FileSink(name ChannelName) (*Sink, error)

FileSink borrows an existing rotating file sink. Stacks, streams, borrowed loggers and file sinks without rotation are deliberately not file owners.

func (ChannelSet) Format

func (ChannelSet) Format(s fmt.State, _ rune)

Format writes a fixed label without exposing channel configuration.

func (ChannelSet) LogValue

func (ChannelSet) LogValue() slog.Value

LogValue returns a fixed log label without exposing channel configuration.

func (*ChannelSet) Start

func (s *ChannelSet) Start(ctx context.Context) error

Start starts owned sinks once. A startup failure closes all owned sinks and permanently closes the set.

func (*ChannelSet) Stats

func (s *ChannelSet) Stats() []ChannelStats

Stats reports owned leaf channels in name order. Counters remain readable after Close.

type ChannelSettings

type ChannelSettings struct {
	Sink  SinkConfig
	Stack []ChannelName `config:",json"`
}

ChannelSettings composes existing JSON sinks. Stack children are named channels; repeated leaves are written once per record, in declaration order.

func DefaultChannelSettings

func DefaultChannelSettings() ChannelSettings

DefaultChannelSettings returns channel settings with the default sink configuration.

func (ChannelSettings) Validate

func (s ChannelSettings) Validate() error

Validate checks sink options and stack children, rejecting unsupported combinations and duplicate children.

type ChannelSettingsConfigKeySet

type ChannelSettingsConfigKeySet struct {
	Sink ChannelSettingsSinkConfigKeySet
	// Stack selects stack. Set accepts []ChannelName.
	Stack config.Key[ChannelSettings, []ChannelName]
}

ChannelSettingsConfigKeySet exposes compiler-checked configuration overrides.

func ChannelSettingsConfigKeys

func ChannelSettingsConfigKeys() ChannelSettingsConfigKeySet

ChannelSettingsConfigKeys derives keys from the handwritten settings declaration.

type ChannelSettingsSinkAsyncConfigKeySet

type ChannelSettingsSinkAsyncConfigKeySet struct {
	// Enabled selects sink.async.enabled. Set accepts bool.
	Enabled config.Key[ChannelSettings, bool]
	// Queue selects sink.async.queue. Set accepts int.
	Queue config.Key[ChannelSettings, int]
	// MaxBytes selects sink.async.max_bytes. Set accepts int64.
	MaxBytes config.Key[ChannelSettings, int64]
}

ChannelSettingsSinkAsyncConfigKeySet exposes compiler-checked configuration overrides.

type ChannelSettingsSinkConfigKeySet

type ChannelSettingsSinkConfigKeySet struct {
	// Driver selects sink.driver. Set accepts SinkDriver.
	Driver config.Key[ChannelSettings, SinkDriver]
	// Path selects sink.path. Set accepts string.
	Path config.Key[ChannelSettings, string]
	// Level selects sink.level. Set accepts slog.Level.
	Level config.Key[ChannelSettings, slog.Level]
	// AddSource selects sink.add_source. Set accepts bool.
	AddSource config.Key[ChannelSettings, bool]
	Rotation  ChannelSettingsSinkRotationConfigKeySet
	// TimeZone selects sink.time_zone. Set accepts temporal.ZoneName.
	//
	// TimeZone controls timestamps and daily rotation; empty means UTC for direct
	// sinks and inherits the application timezone during configured assembly.
	//
	TimeZone config.Key[ChannelSettings, temporal.ZoneName]
	//
	// Async optionally moves destination writes to one owned bounded writer.
	//
	Async ChannelSettingsSinkAsyncConfigKeySet
	//
	// Syslog selects the daemon used by the syslog driver.
	//
	Syslog ChannelSettingsSinkSyslogConfigKeySet
}

ChannelSettingsSinkConfigKeySet exposes compiler-checked configuration overrides.

type ChannelSettingsSinkRotationConfigKeySet

type ChannelSettingsSinkRotationConfigKeySet struct {
	// MaxBytes selects sink.rotation.max_bytes. Set accepts int64.
	MaxBytes config.Key[ChannelSettings, int64]
	// MaxFiles selects sink.rotation.max_files. Set accepts int.
	MaxFiles config.Key[ChannelSettings, int]
	// MaxAge selects sink.rotation.max_age. Set accepts time.Duration.
	MaxAge config.Key[ChannelSettings, time.Duration]
	// Disabled selects sink.rotation.disabled. Set accepts bool.
	Disabled config.Key[ChannelSettings, bool]
}

ChannelSettingsSinkRotationConfigKeySet exposes compiler-checked configuration overrides.

type ChannelSettingsSinkSyslogConfigKeySet

type ChannelSettingsSinkSyslogConfigKeySet struct {
	// Network selects sink.syslog.network. Set accepts string.
	Network config.Key[ChannelSettings, string]
	// Address selects sink.syslog.address. Set accepts string.
	Address config.Key[ChannelSettings, string]
	// Tag selects sink.syslog.tag. Set accepts string.
	Tag config.Key[ChannelSettings, string]
	// Facility selects sink.syslog.facility. Set accepts SyslogFacility.
	Facility config.Key[ChannelSettings, SyslogFacility]
}

ChannelSettingsSinkSyslogConfigKeySet exposes compiler-checked configuration overrides.

type ChannelStats

type ChannelStats struct {
	Channel ChannelName `json:"channel"`
	Sink    SinkStats   `json:"sink"`
}

ChannelStats reports one owned leaf channel. Stacks report through their leaves; a borrowed default logger belongs to its owner and is not reported.

type Channels

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

Channels is immutable; default and named selection alias the same instance.

func NewChannels

func NewChannels(selected ChannelName, entries ...NamedChannel) (*Channels, error)

NewChannels constructs a named logger registry with an explicit default selection.

func (*Channels) Channel

func (r *Channels) Channel(name ChannelName) (*slog.Logger, error)

Channel looks up a named logger through the registry.

func (*Channels) Default

func (r *Channels) Default() (*slog.Logger, error)

Default returns the selected default logger or a registry error.

func (*Channels) DefaultName

func (r *Channels) DefaultName() ChannelName

DefaultName returns the selected default name, or an empty name for a nil registry.

func (*Channels) Names

func (r *Channels) Names() []ChannelName

Names returns channel names, or nil for a nil registry.

type ContextFields

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

ContextFields is an owned, serializable snapshot of request-scoped log fields for crossing an asynchronous boundary, such as a job payload or an outbox record. It stores only its bounded JSON object text, so it is a concrete value accepted by job payload validation. Durations and times serialize as text and decode as strings; integers and floats decode as numbers. Decoding reapplies every bound and redaction rule of WithAttrs. The zero value carries no fields.

func FieldsFromContext

func FieldsFromContext(ctx context.Context) ContextFields

FieldsFromContext snapshots the context's log fields.

func (ContextFields) Attrs

func (f ContextFields) Attrs() []slog.Attr

Attrs returns the snapshot's fields in stable key order.

func (ContextFields) Context

func (f ContextFields) Context(ctx context.Context) context.Context

Context restores the snapshot on ctx; existing fields with the same key are replaced.

func (ContextFields) IsZero

func (f ContextFields) IsZero() bool

IsZero reports whether the context fields are empty.

func (ContextFields) MarshalJSON

func (f ContextFields) MarshalJSON() ([]byte, error)

MarshalJSON returns encoded fields, using an empty JSON object for the zero value.

func (*ContextFields) UnmarshalJSON

func (f *ContextFields) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes and canonicalizes context fields, replacing the receiver only on success.

type FileChunk

type FileChunk struct {
	File         FileInfo
	Data         []byte
	Offset, Next int64
	More         bool
}

FileChunk contains a log file chunk and its continuation position.

type FileID

type FileID string

FileID identifies one owned log generation. It is not a filesystem path.

type FileInfo

type FileInfo struct {
	ID       FileID    `json:"id"`
	Name     string    `json:"name"`
	Active   bool      `json:"active"`
	Bytes    int64     `json:"bytes"`
	Modified time.Time `json:"modified"`
}

FileInfo never exposes an absolute server path. IDs expire on owner restart; an active ID also expires on clear or rotation.

type FileRead

type FileRead struct {
	ID     FileID
	Offset int64
	Limit  int
}

FileRead bounds one byte-range read. Offset -1 requests the newest bytes. Consumers parse complete lines and use Next to continue; a range can end in the middle of a record. Data is owned by the caller and must be treated as text.

type NamedChannel

type NamedChannel struct {
	Name  ChannelName
	Value *slog.Logger
}

NamedChannel borrows one existing instance. Selection never creates another owner.

type Options

type Options struct {
	Level     slog.Leveler
	AddSource bool
	// Location selects log timestamps. Nil means UTC. The value is snapshotted.
	Location *time.Location
}

Options configures the standard JSON handler.

type RotationConfig

type RotationConfig struct {
	MaxBytes int64
	MaxFiles int
	MaxAge   time.Duration
	Disabled bool
}

RotationConfig controls file sinks. A nonempty file rolls over before a write on a new day in the sink's timezone or when that write would exceed MaxBytes. Zero limits select defaults; Disabled explicitly opts into externally managed append-only files. MaxFiles counts archives, excluding the active file. Retention uses archive time.

func DefaultRotationConfig

func DefaultRotationConfig() RotationConfig

DefaultRotationConfig returns default rotation size, file count, and age limits.

func (RotationConfig) Validate

func (c RotationConfig) Validate() error

Validate resolves defaults and checks rotation limits are positive and bounded.

type Sink

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

Sink is a prepared writer; it acquires its destination only in Start. Copying the handle retains one owner. It never closes process stdout/stderr.

func PrepareSink

func PrepareSink(c SinkConfig) (*Sink, error)

PrepareSink validates configuration and prepares sink state without opening its target.

func (*Sink) ClearFile

func (s *Sink) ClearFile(ctx context.Context, expected FileID) error

ClearFile truncates the owned descriptor; it never unlinks the active name. Accepted records before the barrier are cleared; later records append normally.

func (*Sink) Close

func (s *Sink) Close() error

Close drains accepted async records, stops owned cleanup work and releases the destination. Stream sinks never close process stdout/stderr.

func (*Sink) DeleteArchive

func (s *Sink) DeleteArchive(ctx context.Context, id FileID) error

DeleteArchive removes only a selected, closed archive of this owner.

func (*Sink) Files

func (s *Sink) Files(ctx context.Context) (files []FileInfo, err error)

Files lists files through the sink's file access operation.

func (*Sink) Logger

func (s *Sink) Logger() *slog.Logger

Logger returns a correlated logger for the sink, or nil for an uninitialized sink.

func (*Sink) ReadFile

func (s *Sink) ReadFile(ctx context.Context, request FileRead) (chunk FileChunk, err error)

ReadFile reads a bounded file chunk; offset -1 reads the tail and an offset beyond the file returns a conflict fault.

func (*Sink) RotateFile

func (s *Sink) RotateFile(ctx context.Context, expected FileID) error

RotateFile preserves the old file as an archive and installs a fresh active descriptor. expected must identify the current active generation.

func (*Sink) Start

func (s *Sink) Start(ctx context.Context) error

Start opens the sink and starts asynchronous processing when configured. A closed sink cannot restart.

func (*Sink) Stats

func (s *Sink) Stats() SinkStats

Stats returns the sink's delivery counters. It is safe during concurrent writes and after Close; a prepared, never-started sink reports zeros.

func (*Sink) Write

func (s *Sink) Write(data []byte) (int, error)

Write accepts one complete record. Handlers created by Logger call it once per record; direct callers must also supply whole records.

type SinkConfig

type SinkConfig struct {
	Driver    SinkDriver
	Path      string
	Level     slog.Level
	AddSource bool
	Rotation  RotationConfig
	// TimeZone controls timestamps and daily rotation; empty means UTC for direct
	// sinks and inherits the application timezone during configured assembly.
	TimeZone temporal.ZoneName
	// Async optionally moves destination writes to one owned bounded writer.
	Async AsyncConfig
	// Syslog selects the daemon used by the syslog driver.
	Syslog SyslogConfig
}

SinkConfig selects an application-owned JSON destination. File sinks append with automatic rotation/retention unless Rotation.Disabled is explicit.

func DefaultSinkConfig

func DefaultSinkConfig() SinkConfig

DefaultSinkConfig returns default settings for a stderr sink.

func (SinkConfig) Validate

func (c SinkConfig) Validate() error

Validate checks driver-specific options, log level, time zone, and asynchronous settings.

type SinkDriver

type SinkDriver string

SinkDriver selects a logging sink implementation.

const (
	Stderr SinkDriver = "stderr"
	Stdout SinkDriver = "stdout"
	File   SinkDriver = "file"
	// Syslog writes each JSON record to a local or remote syslog daemon with a
	// severity derived from the record level. It is unavailable on Windows/Plan 9.
	Syslog SinkDriver = "syslog"
)
const Custom SinkDriver = "custom"

Custom selects a typed slog.Handler supplied by Go code through WithHandler. Deployment settings choose only its minimum Level.

const Stack SinkDriver = "stack"

Stack is valid only in ChannelSettings, not as an individual file/stream sink.

type SinkStats

type SinkStats struct {
	Driver           SinkDriver `json:"driver"`
	Records          uint64     `json:"records"`
	Failures         uint64     `json:"failures"`
	Fallbacks        uint64     `json:"fallbacks"`
	Dropped          uint64     `json:"dropped"`
	Queued           int        `json:"queued"`
	RotationFailures uint64     `json:"rotation_failures"`
	PruneFailures    uint64     `json:"prune_failures"`
}

SinkStats is an owned snapshot of one destination's delivery counters. Records counts records the destination accepted. Failures counts rejected destination writes; each such record was either rewritten to stderr (Fallbacks) or lost (Dropped). Dropped also counts records refused by a full async queue. Queued is the current async backlog. Rotation and retention failures never drop a record; they are counted separately.

type SyslogConfig

type SyslogConfig struct {
	Network  string
	Address  string
	Tag      string
	Facility SyslogFacility
}

SyslogConfig selects the daemon for the syslog driver. Network and Address are both empty for the platform's local daemon, or select "udp"/"tcp" with a host:port or "unix"/"unixgram" with an absolute socket path. Tag defaults to the process name; Facility defaults to user. Record severity follows the record level: debug, info, warning or err.

func (SyslogConfig) Validate

func (c SyslogConfig) Validate() error

Validate checks the syslog network, address, tag, and facility.

type SyslogFacility

type SyslogFacility string

SyslogFacility selects the syslog facility for a syslog sink.

const (
	FacilityUser   SyslogFacility = "user"
	FacilityDaemon SyslogFacility = "daemon"
	FacilityLocal0 SyslogFacility = "local0"
	FacilityLocal1 SyslogFacility = "local1"
	FacilityLocal2 SyslogFacility = "local2"
	FacilityLocal3 SyslogFacility = "local3"
	FacilityLocal4 SyslogFacility = "local4"
	FacilityLocal5 SyslogFacility = "local5"
	FacilityLocal6 SyslogFacility = "local6"
	FacilityLocal7 SyslogFacility = "local7"
)

Jump to

Keyboard shortcuts

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