Documentation
¶
Index ¶
- Constants
- func ClientIP(addr string, mode IPMode) string
- func ParseLevel(name string) (slog.Level, error)
- func RedactURLUserinfo(raw string) string
- func ReplaceAttrSecretKeys(keys ...string) func(groups []string, a slog.Attr) slog.Attr
- func SecretSet(key, v string) slog.Attr
- type Format
- type IPMode
- type LogConfig
- type Logs
- func (l *Logs) ApplyConfig(cfg LogConfig)
- func (l *Logs) CoreConfigSource() ([]cf.ConfigSourceValue, error)
- func (l *Logs) Format() Format
- func (l *Logs) GetInitOrderStage() cf.Stage
- func (l *Logs) Init(ctx context.Context, fw *cf.CaerusFramework) error
- func (l *Logs) Level() slog.Level
- func (l *Logs) LevelFor(name string) slog.Level
- func (l *Logs) Logger() *slog.Logger
- func (l *Logs) LoggerFor(name string) *slog.Logger
- func (l *Logs) Name() string
- func (l *Logs) OnConfigReload(source string, cfg any)
- func (l *Logs) OnReconfigure(fn func(*slog.Logger)) *Subscription
- func (l *Logs) OnReconfigureFor(name string, fn func(*slog.Logger)) *Subscription
- func (l *Logs) Overrides() map[string]slog.Level
- func (l *Logs) Reconfigure(opts ...Option)
- func (l *Logs) ReportCaller() bool
- func (l *Logs) ResetLevel(name string)
- func (l *Logs) SetLevel(level slog.Level)
- func (l *Logs) SetLevelFor(name string, level slog.Level)
- func (l *Logs) Shutdown(ctx context.Context) error
- func (l *Logs) StackLevel() slog.Level
- func (l *Logs) StackTraces() bool
- type Option
- type RedactedString
- type Subscription
Constants ¶
const ComponentName = "logs"
ComponentName is the framework component name for the logs component. It is the identifier other components use in GetDependencies to require logging.
const RedactedPlaceholder = "[redacted]"
RedactedPlaceholder is what cooperative secret helpers print instead of a credential. Configuration’s `secret:"redact"` tag and RedactedString both resolve to this string. It is not a fingerprint or a hash.
Variables ¶
This section is empty.
Functions ¶
func ClientIP ¶ added in v0.0.7
ClientIP formats an already-chosen client identity for a log record. Pass the address the app trusts (for example r.RemoteAddr after your own proxy policy). Do not pass X-Forwarded-For here: this helper does not decide whether a header is forged.
func ParseLevel ¶
ParseLevel converts a canonical level name ("debug", "info", "warn" or "error") into a slog.Level. It returns an error for unknown names.
func RedactURLUserinfo ¶ added in v0.0.7
RedactURLUserinfo returns a URL string with the password (and only the password) in userinfo replaced by [redacted]. Username stays. If raw is not a URL or has no userinfo, it is returned unchanged. If parsing fails on a string that looks like a URL with userinfo, the function returns a generic placeholder so a bad DSN cannot leak through %w.
func ReplaceAttrSecretKeys ¶ added in v0.0.7
ReplaceAttrSecretKeys returns a slog HandlerOptions.ReplaceAttr function that rewrites matching attribute keys to [redacted] when the value is a non-empty string. Opt in on a handler you own; it does not wrap slog.Default and does not walk structs. Prefer RedactedString / secret tags.
Types ¶
type Format ¶
type Format int
Format selects the slog handler output format.
func ParseFormat ¶
ParseFormat converts a format name ("json", "text") into a Format. Matching is case-insensitive (like ParseLevel); unknown names return an error.
type IPMode ¶ added in v0.0.7
type IPMode string
IPMode selects how ClientIP formats an address for logs.
func ParseIPMode ¶ added in v0.0.7
ParseIPMode maps full|partial|omit (case-insensitive). Unknown names error.
type LogConfig ¶
type LogConfig struct {
// Format is "text" or "json". Empty keeps the current format.
Format string `json:"format,omitempty" yaml:"format,omitempty" env:"FORMAT" flag:"log-format"`
// Level is "debug", "info", "warn" or "error". Empty keeps the current
// process-global level.
Level string `json:"level,omitempty" yaml:"level,omitempty" env:"LEVEL" flag:"log-level"`
// ReportCaller records the source file:line of every log call. Nil keeps
// the current setting; explicit true/false overrides.
ReportCaller *bool `json:"report_caller,omitempty" yaml:"report_caller,omitempty" env:"REPORT_CALLER" flag:"report-caller"`
// StackTraces attaches a stack traceback to records at or above the stack
// level (default error). Nil keeps the current setting; explicit true/false
// overrides.
StackTraces *bool `json:"stack_traces,omitempty" yaml:"stack_traces,omitempty" env:"STACK_TRACES" flag:"stack-traces"`
// StackLevel is the threshold for stack tracebacks ("debug", "info", "warn",
// "error"). Empty keeps the current threshold (default error). Only takes
// effect when stack traces are enabled.
StackLevel string `json:"stack_level,omitempty" yaml:"stack_level,omitempty" env:"STACK_LEVEL" flag:"stack-level"`
// ComponentLevels maps component Name() → level name. Applied via SetLevelFor
// on load/reload. Keys not listed are ResetLevel'd so a removed map entry
// follows the process-global level again. Nil/omitted keeps current overrides
// (API SetLevelFor from code is not wiped). An empty map {} clears all
// config-owned overrides.
ComponentLevels map[string]string `json:"component_levels,omitempty" yaml:"component_levels,omitempty"`
}
LogConfig is the file/env/flag-drivable logging configuration loaded through the configuration component as the "logs" source. The logs component cannot read the configuration component directly (import cycle), so the framework delivers the freshly loaded value through OnConfigReload. Empty / nil fields keep the current value (bool switches are *bool so omit ≠ explicit false).
type Logs ¶
type Logs struct {
// contains filtered or unexported fields
}
Logs is the caerus-framework-logs component. It wraps a *slog.Logger and is registered with the framework as the "logs" component so that every other component can retrieve it via cf.Get[*cf_logs.Logs] or depend on it by name.
The logger is built at construction and can be rebuilt at runtime with Reconfigure. SetLevel changes the process-global minimum; SetLevelFor sets a per-component override used by OnReconfigureFor subscribers. Level changes do not rebuild the logger.
func New ¶
New creates a logs component. Configure it with options; defaults are text format, Info level, os.Stdout, caller reporting off, stack tracebacks off.
func (*Logs) ApplyConfig ¶
ApplyConfig applies a LogConfig to the running component. Non-empty Format and non-nil ReportCaller/StackTraces (and non-empty StackLevel) rebuild the logger (delivering the new logger to every OnReconfigure / OnReconfigureFor subscriber); omitted bool fields keep the current forensic settings. Level is applied through SetLevel so per-component overrides (SetLevelFor) keep working. Invalid format/level/stack_level values are logged and skipped (last-good).
func (*Logs) CoreConfigSource ¶
func (l *Logs) CoreConfigSource() ([]cf.ConfigSourceValue, error)
CoreConfigSource implements cf.CoreConfigSource. It declares the logs component's own configuration source; the logs module cannot import the configuration module (the configuration module imports logs), so the framework discovers it among registered components during argv absorption and registers the declaration on the component's behalf.
The source is owned by the component: default file config/<name>.json, env prefix LOGS_, owner cf_logs. An argv redeclaration wins: the --<name> file-path flag ParseFlags registers overrides where the file is read from, and the loaded value reaches the component through OnConfigReload (see WithConfigSource). No source is declared when WithConfigSource was not given.
func (*Logs) GetInitOrderStage ¶
GetInitOrderStage implements cf.CaerusComponent. Logging is the very first bootstrap stage, so it is available to every other component's Init.
func (*Logs) Init ¶
Init implements cf.CaerusComponent. It is a no-op: the logger is fully configured at construction time.
func (*Logs) LevelFor ¶
LevelFor returns the effective minimum level for name: the SetLevelFor override when present, otherwise the process-global level.
func (*Logs) Logger ¶
Logger returns the process-global slog.Logger (filtered by SetLevel). Prefer OnReconfigureFor from framework components so they honor SetLevelFor.
func (*Logs) LoggerFor ¶
LoggerFor returns a logger filtered by the named component's level override when set, otherwise by the process-global SetLevel. Each call allocates a new wrapper; do not use it on a hot path. Framework components should subscribe once with OnReconfigureFor(Name(), …) and cache that pointer instead — it is rebuilt only on Reconfigure.
func (*Logs) OnConfigReload ¶
OnConfigReload implements cf.ConfigReloader. It applies the freshly loaded LogConfig for the source named by WithConfigSource (see ApplyConfig). The configuration component delivers the value directly because the logs module cannot import it. A wrong payload type is logged and ignored (last-good).
func (*Logs) OnReconfigure ¶
func (l *Logs) OnReconfigure(fn func(*slog.Logger)) *Subscription
OnReconfigure registers fn to receive the process-global logger immediately and again every time Reconfigure rebuilds it. Prefer OnReconfigureFor from framework components so SetLevelFor can isolate verbosity. SetLevel changes are deliberately not delivered, since the logger pointer is unchanged.
func (*Logs) OnReconfigureFor ¶
func (l *Logs) OnReconfigureFor(name string, fn func(*slog.Logger)) *Subscription
OnReconfigureFor is like OnReconfigure but the delivered logger honors SetLevelFor(name) when set, otherwise the process-global SetLevel. Pass the component's Name() (including WithName aliases). An empty name behaves like OnReconfigure.
func (*Logs) Reconfigure ¶
Reconfigure rebuilds the logger from the given construction options and delivers the new logger to every OnReconfigure / OnReconfigureFor subscriber. It applies the handler-affecting options — WithFormat, WithWriter, WithReportCaller, WithStackTraces, WithStackLevel. WithLevel is not applied here: the global level is managed exclusively through SetLevel, and rebuilding preserves the current runtime level and per-component overrides. Subscribers are notified outside the internal lock.
func (*Logs) ReportCaller ¶
ReportCaller returns whether the logger includes caller information.
func (*Logs) ResetLevel ¶
ResetLevel drops the per-component override for name so it follows SetLevel again. No-op when name is empty or has no override.
func (*Logs) SetLevel ¶
SetLevel changes the process-global minimum log level at runtime. Components subscribed with OnReconfigureFor keep any SetLevelFor override; others and Logger() observe the new global immediately. SetLevel does not rebuild the logger, so reconfiguration subscribers are not notified.
func (*Logs) SetLevelFor ¶
SetLevelFor sets a per-component minimum log level. name should be the component's Name() (including WithName aliases). The override applies to LoggerFor and OnReconfigureFor subscribers for that name. It does not notify subscribers (the logger pointer is unchanged).
func (*Logs) Shutdown ¶
Shutdown implements cf.CaerusComponent. The writer is the caller's concern; there is nothing to release. Pending reconfiguration subscribers are dropped so they stop receiving deliveries during teardown.
func (*Logs) StackLevel ¶
StackLevel returns the level at which stack traces are emitted.
func (*Logs) StackTraces ¶
StackTraces returns whether the logger emits stack traces.
type Option ¶
type Option func(*options)
Option configures the logs component at construction time.
func WithConfigSource ¶
WithConfigSource names the configuration source (caerus-framework- configuration) whose LogConfig is applied to the component. The logs module cannot read the configuration component directly (import cycle), so the framework delivers the freshly loaded value through OnConfigReload. The component self-registers the source during argv absorption (default file config/<name>.json, env prefix LOGS_, owner cf_logs); an argv --<name> file-path override wins, and the app may also register its own Source[LogConfig] for a custom default. Until the source loads, construction-time defaults apply.
func WithFormat ¶
WithFormat selects the output format, text or JSON (default FormatText).
func WithLevel ¶
WithLevel sets the process-global minimum level that is emitted (default slog.LevelInfo). The level can still be changed at runtime with Logs.SetLevel. Reconfigure does not apply WithLevel; the global level is always managed via SetLevel. Per-component overrides use SetLevelFor.
func WithReportCaller ¶
WithReportCaller enables the source (file:line) of the log call to be recorded on every record, like logrus's ReportCaller (default false).
func WithStackLevel ¶
WithStackLevel sets the threshold at or above which stack tracebacks are attached (default slog.LevelError). It only takes effect when stack traces are enabled.
func WithStackTraces ¶
WithStackTraces attaches a formatted stack traceback to every record at or above the stack level (default false).
func WithWriter ¶
WithWriter sets the output destination (default os.Stdout).
type RedactedString ¶ added in v0.0.7
type RedactedString string
RedactedString is a secret that may be passed to slog. It implements slog.LogValuer so the cleartext never appears in a record: empty stays empty; any other value becomes [redacted].
This is cooperative. fmt.Sprintf, error strings, and slog.Any on a raw struct still leak. Mark the field, wrap the value, or call configuration’s LogArgs — do not expect a process-wide ReplaceAttr to catch everything.
func (RedactedString) LogValue ¶ added in v0.0.7
func (s RedactedString) LogValue() slog.Value
LogValue implements slog.LogValuer.
type Subscription ¶
type Subscription struct {
// contains filtered or unexported fields
}
Subscription is the handle returned by OnReconfigure. Unsubscribe removes the registered callback so it stops receiving rebuilt loggers. It is idempotent.
func (*Subscription) Unsubscribe ¶
func (s *Subscription) Unsubscribe()
Unsubscribe stops the registered callback from receiving further deliveries.