Documentation
¶
Overview ¶
Package logger provides structured logging with automatic PII redaction.
Package logger provides structured logging with automatic PII redaction.
This package wraps Go's standard log/slog with convenience functions for:
- LLM API call logging (requests, responses, errors)
- Tool execution logging
- Automatic API key and sensitive data redaction
- Contextual logging with request tracing
- Level-based verbosity control
All exported functions use the global DefaultLogger which can be configured for different output formats and log levels.
Index ¶
- Constants
- Variables
- func APIRequest(provider, method, url string, headers map[string]string, body interface{})
- func APIResponse(provider string, statusCode int, body string, err error)
- func Configure(cfg *LoggingConfigSpec) error
- func Debug(msg string, args ...any)
- func DebugContext(ctx context.Context, msg string, args ...any)
- func Error(msg string, args ...any)
- func ErrorContext(ctx context.Context, msg string, args ...any)
- func Info(msg string, args ...any)
- func InfoContext(ctx context.Context, msg string, args ...any)
- func LLMCall(provider, role string, messages int, temperature float64, attrs ...any)
- func LLMError(provider, role string, err error, attrs ...any)
- func LLMResponse(provider, role string, tokensIn, tokensOut int, cost float64, attrs ...any)
- func ParseLevel(s string) slog.Level
- func RedactSensitiveData(input string) string
- func SetLevel(level slog.Level)
- func SetOutput(w io.Writer)
- func SetVerbose(verbose bool)
- func ToolCall(provider string, messages, tools int, choice string, attrs ...any)
- func ToolResponse(provider string, tokensIn, tokensOut, toolCalls int, cost float64, ...)
- func Warn(msg string, args ...any)
- func WarnContext(ctx context.Context, msg string, args ...any)
- func WithCorrelationID(ctx context.Context, correlationID string) context.Context
- func WithEnvironment(ctx context.Context, environment string) context.Context
- func WithLoggingContext(ctx context.Context, fields *LoggingFields) context.Context
- func WithModel(ctx context.Context, model string) context.Context
- func WithProvider(ctx context.Context, provider string) context.Context
- func WithRequestID(ctx context.Context, requestID string) context.Context
- func WithScenario(ctx context.Context, scenario string) context.Context
- func WithScenarioVersion(ctx context.Context, version string) context.Context
- func WithSessionID(ctx context.Context, sessionID string) context.Context
- func WithStage(ctx context.Context, stage string) context.Context
- func WithTurnID(ctx context.Context, turnID string) context.Context
- type ContextHandler
- func (h *ContextHandler) Enabled(ctx context.Context, level slog.Level) bool
- func (h *ContextHandler) Handle(ctx context.Context, r slog.Record) error
- func (h *ContextHandler) Unwrap() slog.Handler
- func (h *ContextHandler) WithAttrs(attrs []slog.Attr) slog.Handler
- func (h *ContextHandler) WithGroup(name string) slog.Handler
- type LoggingConfigSpec
- type LoggingFields
- type ModuleConfig
- type ModuleHandler
- type ModuleLoggingSpec
Constants ¶
const ( FormatJSON = "json" FormatText = "text" )
Log format constants
const ( // ContextKeyTurnID identifies the current conversation turn. ContextKeyTurnID contextKey = "turn_id" // ContextKeyScenario identifies the scenario being executed. ContextKeyScenario contextKey = "scenario" // ContextKeyScenarioVersion identifies the version of the scenario. ContextKeyScenarioVersion contextKey = "scenario_version" // ContextKeyProvider identifies the LLM provider (e.g., "openai", "anthropic"). ContextKeyProvider contextKey = "provider" // ContextKeyModel identifies the specific model being used. ContextKeyModel contextKey = "model" // ContextKeyStage identifies the pipeline stage (e.g., "init", "execution", "streaming"). ContextKeyStage contextKey = "stage" // ContextKeySessionID identifies the user session. ContextKeySessionID contextKey = "session_id" // ContextKeyRequestID identifies the individual request. ContextKeyRequestID contextKey = "request_id" // ContextKeyCorrelationID is used for distributed tracing. ContextKeyCorrelationID contextKey = "correlation_id" // ContextKeyEnvironment identifies the deployment environment. ContextKeyEnvironment contextKey = "environment" )
Context keys for common logging fields. These keys are used to store values in context.Context that will be automatically extracted and added to log entries.
Variables ¶
var ( // DefaultLogger is the global structured logger instance. // It is safe for concurrent use and initialized with slog.LevelInfo by default. DefaultLogger *slog.Logger )
Functions ¶
func APIRequest ¶
APIRequest logs HTTP API request details at debug level with automatic PII redaction. This function is a no-op when debug logging is disabled for performance.
Parameters:
- provider: The API provider name (e.g., "OpenAI", "Anthropic")
- method: HTTP method (GET, POST, etc.)
- url: Request URL (will be redacted for sensitive data)
- headers: HTTP headers map (will be redacted)
- body: Request body (will be marshaled to JSON and redacted)
Sensitive data in URL, headers, and body are automatically redacted.
func APIResponse ¶
APIResponse logs HTTP API response details at debug level with automatic PII redaction. This function is a no-op when debug logging is disabled for performance.
Parameters:
- provider: The API provider name
- statusCode: HTTP status code
- body: Response body as string (will be redacted)
- err: Error if the request failed (takes precedence over body logging)
Response bodies are attempted to be parsed as JSON for pretty formatting. Status codes are logged with emoji indicators: 🟢 (2xx), 🟡 (3xx), 🔴 (4xx/5xx).
func Configure ¶ added in v1.1.6
func Configure(cfg *LoggingConfigSpec) error
Configure applies a LoggingConfigSpec to the global logger. This reconfigures the logger with the new settings.
func Debug ¶
Debug logs a debug-level message with structured attributes. Debug messages are only output when the log level is set to LevelDebug or lower.
func DebugContext ¶
DebugContext logs a debug message with context and structured attributes.
func Error ¶
Error logs an error message with structured attributes. Use for errors that affect operation but don't cause complete failure.
func ErrorContext ¶
ErrorContext logs an error message with context and structured attributes.
func Info ¶
Info logs an informational message with structured key-value attributes. Args should be provided in key-value pairs: key1, value1, key2, value2, ...
func InfoContext ¶
InfoContext logs an informational message with context and structured attributes. The context can be used for request tracing and cancellation.
func LLMCall ¶
LLMCall logs an LLM API call with structured fields for observability. Additional attributes can be passed as key-value pairs after the required parameters.
func LLMResponse ¶
LLMResponse logs an LLM API response with token usage and cost tracking. Cost should be provided in USD (e.g., 0.0001 for $0.0001).
func ParseLevel ¶ added in v1.1.6
ParseLevel converts a string log level to slog.Level. Supported values: "trace", "debug", "info", "warn", "warning", "error". Unknown values default to LevelInfo.
func RedactSensitiveData ¶
RedactSensitiveData removes API keys and other sensitive information from strings. It replaces matched patterns with a redacted form that preserves the first few characters for debugging while hiding the sensitive portion.
Supported patterns:
- OpenAI keys (sk-...): Shows first 4 chars
- Google keys (AIza...): Shows first 4 chars
- Bearer tokens: Shows only "Bearer [REDACTED]"
This function is safe for concurrent use as it only reads from the compiled patterns.
func SetLevel ¶
SetLevel changes the logging level for all subsequent log operations. This is safe for concurrent use as it replaces the entire logger instance.
func SetOutput ¶ added in v1.1.6
SetOutput changes the log output destination and reinitializes the logger. This is primarily for testing. Pass nil to reset to os.Stderr.
func SetVerbose ¶
func SetVerbose(verbose bool)
SetVerbose enables debug-level logging when verbose is true, otherwise sets info-level. This is a convenience wrapper around SetLevel for command-line verbose flags.
func ToolCall ¶
ToolCall logs a tool execution request with context about available tools. The choice parameter indicates the tool selection mode (e.g., "auto", "required", "none").
func ToolResponse ¶
ToolResponse logs the result of tool executions with token usage and cost.
func Warn ¶
Warn logs a warning message with structured attributes. Use for recoverable errors or unexpected but non-critical situations.
func WarnContext ¶
WarnContext logs a warning message with context and structured attributes.
func WithCorrelationID ¶ added in v1.1.6
WithCorrelationID returns a new context with the correlation ID set.
func WithEnvironment ¶ added in v1.1.6
WithEnvironment returns a new context with the environment set.
func WithLoggingContext ¶ added in v1.1.6
func WithLoggingContext(ctx context.Context, fields *LoggingFields) context.Context
WithLoggingContext returns a new context with multiple logging fields set at once. This is a convenience function for setting multiple fields in one call. Only non-empty values are set.
func WithProvider ¶ added in v1.1.6
WithProvider returns a new context with the provider name set.
func WithRequestID ¶ added in v1.1.6
WithRequestID returns a new context with the request ID set.
func WithScenario ¶ added in v1.1.6
WithScenario returns a new context with the scenario name set.
func WithScenarioVersion ¶ added in v1.1.6
WithScenarioVersion returns a new context with the scenario version set.
func WithSessionID ¶ added in v1.1.6
WithSessionID returns a new context with the session ID set.
Types ¶
type ContextHandler ¶ added in v1.1.6
type ContextHandler struct {
// contains filtered or unexported fields
}
ContextHandler is a slog.Handler that automatically extracts logging fields from context and adds them to log records. It wraps an inner handler and delegates all actual logging to it after enriching records with context data.
func NewContextHandler ¶ added in v1.1.6
func NewContextHandler(inner slog.Handler, commonFields ...slog.Attr) *ContextHandler
NewContextHandler creates a new ContextHandler wrapping the given handler. The commonFields are added to every log record (useful for environment, service name, etc.).
func (*ContextHandler) Enabled ¶ added in v1.1.6
Enabled reports whether the handler handles records at the given level. It delegates to the inner handler.
func (*ContextHandler) Handle ¶ added in v1.1.6
Handle processes the log record by extracting context fields and adding them to the record before delegating to the inner handler.
func (*ContextHandler) Unwrap ¶ added in v1.1.6
func (h *ContextHandler) Unwrap() slog.Handler
Unwrap returns the inner handler. This is useful for handler chains that need to inspect or replace the underlying handler.
type LoggingConfigSpec ¶ added in v1.1.6
type LoggingConfigSpec struct {
DefaultLevel string
Format string // "json" or "text"
CommonFields map[string]string
Modules []ModuleLoggingSpec
}
LoggingConfigSpec defines the logging configuration for the Configure function. This mirrors the config.LoggingConfigSpec to avoid import cycles.
type LoggingFields ¶ added in v1.1.6
type LoggingFields struct {
TurnID string
Scenario string
ScenarioVersion string
Provider string
Model string
Stage string
SessionID string
RequestID string
CorrelationID string
Environment string
}
LoggingFields holds all standard logging context fields. This struct is used with WithLoggingContext for bulk field setting.
func ExtractLoggingFields ¶ added in v1.1.6
func ExtractLoggingFields(ctx context.Context) LoggingFields
ExtractLoggingFields extracts all logging fields from a context. Returns a LoggingFields struct with all values found in the context.
type ModuleConfig ¶ added in v1.1.6
type ModuleConfig struct {
// contains filtered or unexported fields
}
ModuleConfig manages per-module logging configuration. It supports hierarchical module names where more specific modules override less specific ones (e.g., "runtime.pipeline" overrides "runtime").
func GetModuleConfig ¶ added in v1.1.6
func GetModuleConfig() *ModuleConfig
GetModuleConfig returns the global module configuration. This is primarily for testing.
func NewModuleConfig ¶ added in v1.1.6
func NewModuleConfig(defaultLevel slog.Level) *ModuleConfig
NewModuleConfig creates a new ModuleConfig with the given default level.
func (*ModuleConfig) LevelFor ¶ added in v1.1.6
func (m *ModuleConfig) LevelFor(module string) slog.Level
LevelFor returns the log level for the given module. It checks for exact match first, then walks up the hierarchy. For example, for "runtime.pipeline.stage":
- Check "runtime.pipeline.stage" (exact match)
- Check "runtime.pipeline" (parent)
- Check "runtime" (grandparent)
- Return default level
func (*ModuleConfig) SetDefaultLevel ¶ added in v1.1.6
func (m *ModuleConfig) SetDefaultLevel(level slog.Level)
SetDefaultLevel sets the default log level.
func (*ModuleConfig) SetModuleLevel ¶ added in v1.1.6
func (m *ModuleConfig) SetModuleLevel(module string, level slog.Level)
SetModuleLevel sets the log level for a specific module. Module names use dot notation (e.g., "runtime.pipeline").
type ModuleHandler ¶ added in v1.1.6
type ModuleHandler struct {
ContextHandler
// contains filtered or unexported fields
}
ModuleHandler extends ContextHandler with per-module log level filtering. It determines the module name from the call stack and applies the appropriate log level from the module configuration.
func NewModuleHandler ¶ added in v1.1.6
func NewModuleHandler(inner slog.Handler, moduleConfig *ModuleConfig, commonFields ...slog.Attr) *ModuleHandler
NewModuleHandler creates a new ModuleHandler with per-module log level filtering.
func (*ModuleHandler) Enabled ¶ added in v1.1.6
Enabled reports whether the handler handles records at the given level. It uses the module configuration to determine the level for the calling module.
func (*ModuleHandler) Handle ¶ added in v1.1.6
Handle processes the log record, adding the module name as an attribute.