Documentation
¶
Overview ¶
Package logging constructs application-owned structured loggers with safe defaults. It never changes slog.Default or installs a global subscriber.
Index ¶
- Constants
- func AttrsFromContext(ctx context.Context) []slog.Attr
- func ChannelSettingsConfigSchema() (*config.Schema[ChannelSettings], error)
- func Correlate(handler slog.Handler) slog.Handler
- func JSON(writer io.Writer, options Options) *slog.Logger
- func WithAttrs(ctx context.Context, attrs ...slog.Attr) context.Context
- type AsyncConfig
- type ChannelName
- type ChannelOption
- type ChannelSet
- func (s *ChannelSet) Channels() *Channels
- func (s *ChannelSet) Close() error
- func (s *ChannelSet) FileSink(name ChannelName) (*Sink, error)
- func (ChannelSet) Format(s fmt.State, _ rune)
- func (ChannelSet) LogValue() slog.Value
- func (s *ChannelSet) Start(ctx context.Context) error
- func (s *ChannelSet) Stats() []ChannelStats
- type ChannelSettings
- type ChannelSettingsConfigKeySet
- type ChannelSettingsSinkAsyncConfigKeySet
- type ChannelSettingsSinkConfigKeySet
- type ChannelSettingsSinkRotationConfigKeySet
- type ChannelSettingsSinkSyslogConfigKeySet
- type ChannelStats
- type Channels
- type ContextFields
- type FileChunk
- type FileID
- type FileInfo
- type FileRead
- type NamedChannel
- type Options
- type RotationConfig
- type Sink
- func (s *Sink) ClearFile(ctx context.Context, expected FileID) error
- func (s *Sink) Close() error
- func (s *Sink) DeleteArchive(ctx context.Context, id FileID) error
- func (s *Sink) Files(ctx context.Context) (files []FileInfo, err error)
- func (s *Sink) Logger() *slog.Logger
- func (s *Sink) ReadFile(ctx context.Context, request FileRead) (chunk FileChunk, err error)
- func (s *Sink) RotateFile(ctx context.Context, expected FileID) error
- func (s *Sink) Start(ctx context.Context) error
- func (s *Sink) Stats() SinkStats
- func (s *Sink) Write(data []byte) (int, error)
- type SinkConfig
- type SinkDriver
- type SinkStats
- type SyslogConfig
- type SyslogFacility
Constants ¶
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.
const MaxFallbackBytes = 256 << 10
MaxFallbackBytes bounds one record rewritten to stderr after its configured destination failed. Larger records are counted as dropped instead.
const MaxFileReadBytes = 1 << 20
Variables ¶
This section is empty.
Functions ¶
func AttrsFromContext ¶
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 ¶
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 ¶
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 ¶
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 ¶
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) 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 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 ¶
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 ¶
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 ¶
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 ¶
Close drains accepted async records, stops owned cleanup work and releases the destination. Stream sinks never close process stdout/stderr.
func (*Sink) DeleteArchive ¶
DeleteArchive removes only a selected, closed archive of this owner.
func (*Sink) Logger ¶
Logger returns a correlated logger for the sink, or nil for an uninitialized sink.
func (*Sink) ReadFile ¶
ReadFile reads a bounded file chunk; offset -1 reads the tail and an offset beyond the file returns a conflict fault.
func (*Sink) RotateFile ¶
RotateFile preserves the old file as an archive and installs a fresh active descriptor. expected must identify the current active generation.
func (*Sink) Start ¶
Start opens the sink and starts asynchronous processing when configured. A closed sink cannot restart.
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" )