logging

package
v2.13.0 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ServiceLogger = "service.logger"
)

Variables

This section is empty.

Functions

func CloseEmergencyLogger

func CloseEmergencyLogger()

func EmergencyLogger

func EmergencyLogger() loggingcontract.Logger

func EnsureLogger

func EnsureLogger(logger loggingcontract.Logger) loggingcontract.Logger

func GenerateProcessId

func GenerateProcessId() string

func IsValidLevel

func IsValidLevel(value loggingcontract.Level) bool

func LevelEnabled added in v2.13.0

func LevelEnabled(logger loggingcontract.Logger, level loggingcontract.Level) bool
LevelEnabled asks a logger whether a record at this level would survive its threshold, and answers true for one that cannot be asked. It is the single door onto loggingcontract.LevelReporter, so the "absent means enabled" rule lives in one place rather than being restated at each caller — a site that spelled the fallback the other way would silently stop recording against every logger that does not implement the capability, which is most of them.

Ask it only where the answer saves work that is otherwise thrown away: a context map assembled at the call site, a name resolved through reflection. A record whose arguments already exist costs nothing to hand over, and gating it here would only add a second place where a level decision is made.

func LogError

func LogError(logger loggingcontract.Logger, err error)

LogError writes one record for the error it is given, or none when the error is nil — including a typed nil, which would otherwise panic on the very lines that render it — or when the error was already logged. The mark is read at the depth exception.MarkLogged writes it, the nearest AlreadyLogged implementer in the chain, so marking a wrapping http exception suppresses this record the way the mark promises; the previous read searched for the nearest *exception.Error instead and disagreed with the writer on every chain whose markable link is not that type. The record is anchored on the error the caller handed over: a top-level *exception.Error contributes its own level, message and enriched context, while any other error — a wrapper included — is logged at error level under its full message, with the context of the nearest provider and the cause chain walked from its own wrap link; anchoring on the nearest *exception.Error buried in the chain logged that error's message at that error's level, which dropped the wrapper's framing entirely and let a low-level cause file the whole record below the logger's threshold. A nil logger falls back to the process default logger under the same rules.

func LogOnRecover

func LogOnRecover(
	logger loggingcontract.Logger,
	panicAgain bool,
)

LogOnRecover recovers the panic in flight, logs it, and panics again when panicAgain is set. It never terminates the process: installed with defer it sits above the container teardown, the scope closes and the shutdown hooks, which an exit taken here would skip. A recovered *exception.ExitError is therefore re-panicked unchanged so its code reaches the owner of the process boundary — LogOnRecoverAndExit is the helper that takes the exit.

func LogOnRecoverAndExit

func LogOnRecoverAndExit(
	logger loggingcontract.Logger,
	recovered any,
	exitCode int,
)

func LogOnRecoverAndExitAfter added in v2.13.0

func LogOnRecoverAndExitAfter(
	logger loggingcontract.Logger,
	recovered any,
	exitCode int,
	beforeExit func(),
)

LogOnRecoverAndExitAfter logs the recovered value like LogOnRecoverAndExit and runs beforeExit between the record and the process exit. It is the one place that is both after the record and before the exit: a teardown deferred below never runs, because os.Exit skips it, and one run before closes the logger the final record must travel through.

func LoggerFromContainer

func LoggerFromContainer(serviceContainer containercontract.Container) (loggingcontract.Logger, error)

func LoggerFromResolver

func LoggerFromResolver(resolver containercontract.Resolver) (loggingcontract.Logger, error)

func LoggerFromRuntime

func LoggerFromRuntime(runtimeInstance runtimecontract.Runtime) loggingcontract.Logger

LoggerFromRuntime resolves the logger and answers nil when it cannot, with the failure recorded through the emergency logger, because the caller's nil check silently skips its own record next. The typed-nil branch is latent defense: the container refuses a provider-returned typed nil with an error today, so the branch is reachable only through a resolution path that does not — but a typed nil that did slip through would pass the plain comparison and panic on the first method call, inside the listener reporting somebody else's failure.

func LoggerMustFromContainer

func LoggerMustFromContainer(serviceContainer containercontract.Container) loggingcontract.Logger

func LoggerMustFromResolver

func LoggerMustFromResolver(resolver containercontract.Resolver) loggingcontract.Logger

func LoggerMustFromRuntime

func LoggerMustFromRuntime(runtimeInstance runtimecontract.Runtime) loggingcontract.Logger

func LoggingConfigurationFromModules added in v2.2.0

func LoggingConfigurationFromModules(moduleConfigurations map[string]any) loggingcontract.LoggingConfiguration

func NewDefaultLogger

func NewDefaultLogger() loggingcontract.Logger

func NewDefaultLoggerWithLabels added in v2.2.0

func NewDefaultLoggerWithLabels(labels loggingcontract.LevelLabels) loggingcontract.Logger

func NewJsonLogger

func NewJsonLogger(output io.Writer, minLevel loggingcontract.Level) loggingcontract.Logger

func NewJsonLoggerWithLabels added in v2.2.0

func NewJsonLoggerWithLabels(output io.Writer, minLevel loggingcontract.Level, labels loggingcontract.LevelLabels) loggingcontract.Logger

func NewLoggingConfiguration added in v2.2.0

func NewLoggingConfiguration(labels loggingcontract.LevelLabels) loggingcontract.LoggingConfiguration

NewLoggingConfiguration copies the labels on the way in, and LevelLabels hands a copy back out: the map is read lock-free on every Log call of the logger built from it, so a reference kept by the caller turns a later write into a fatal concurrent map access no recover reaches.

func NewNopLogger

func NewNopLogger() loggingcontract.Logger

func NewProcessLogger added in v2.13.0

func NewProcessLogger(logger loggingcontract.Logger, processId string, contextKey string) loggingcontract.Logger

NewProcessLogger decorates the base logger with the console path's correlation rule: the generated id wins the context key on every record, so the correlation never has holes, and a caller's own value under the key is preserved verbatim — any type, not only strings — under the key suffixed "Provided". The console caller is the process's own code, not a client that can forge, so what it wrote is legitimate data displaced by the correlation, not a claim to be suspected.

func NewRequestLogger

func NewRequestLogger(logger loggingcontract.Logger, requestId string, contextKey string) loggingcontract.Logger

NewRequestLogger decorates the base logger with the request path's correlation rule: the real id wins the context key unconditionally, and a different non-empty string claim survives beside it under the key suffixed "Claimed" — the claim frequently originates in an error context assembled from request data, so the suffix says exactly what it is. Console processes use NewProcessLogger, whose caller is trusted.

func NewStandardErrorLogger added in v2.13.0

func NewStandardErrorLogger(logger loggingcontract.Logger, message string) *log.Logger
NewStandardErrorLogger adapts a melody logger to the *log.Logger net/http's Server.ErrorLog wants, so the connection-level failures the http kernel never sees reach the application's journal instead of the standard logger's default output. A tls handshake that fails before any request exists, a malformed request line, a listener degrading while the process stays up, a superfluous WriteHeader, and the one panic no request guard can absorb — the one raised while the request scope is closing — all arrive here. Written to stderr as unstructured text they are invisible to a deployment whose journal is a json file.

The flags are zero: the record carries the logger's own timestamp, and the standard prefix would only repeat it inside the message.

func RunShieldedStep added in v2.13.0

func RunShieldedStep(stepName string, step func()) bool
RunShieldedStep is the exit handler's own shield, offered to the one other caller that stands between a process and its end: the normal return of Run, whose teardown is deferred with no budget at all, so the healthy shutdown was the one without an emergency exit while the panicking one had a ten-second escape. It contains a panic inside the step, echoes it to stderr best-effort, and abandons a step that does not return within the budget, answering whether the step finished. A caller that gets false has a process holding something it cannot release and should end rather than wait.

The step keeps running on its goroutine after abandonment, so anything it writes must not be read by a caller that was told it did not finish.

Types

This section is empty.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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