Documentation
¶
Overview ¶
Package logging provides structured logging with distributed tracing support.
FinFocus uses zerolog for high-performance structured logging with automatic trace ID propagation through contexts.
Log Levels ¶
- TRACE: Property extraction, detailed calculations
- DEBUG: Function entry/exit, retries, intermediate values
- INFO: High-level operations (command start/end)
- WARN: Recoverable issues (fallbacks, deprecations)
- ERROR: Failures needing attention
Trace ID Management ¶
Trace IDs are automatically generated or extracted from context:
traceID := logging.GetOrGenerateTraceID(ctx) ctx = logging.ContextWithTraceID(ctx, traceID)
Component Loggers ¶
Create sub-loggers for components:
logger = logging.ComponentLogger(logger, "registry")
Configuration ¶
Logging can be configured via:
- CLI flags (--debug)
- Environment variables (FINFOCUS_LOG_LEVEL, FINFOCUS_LOG_FORMAT)
- Config file (~/.finfocus/config.yaml)
Index ¶
- func ComponentLogger(logger zerolog.Logger, component string) zerolog.Logger
- func ContextWithAuditLogger(ctx context.Context, logger AuditLogger) context.Context
- func ContextWithPluginLogPath(ctx context.Context, path string) context.Context
- func ContextWithPluginLogWriter(ctx context.Context, w io.Writer) context.Context
- func ContextWithTraceID(ctx context.Context, traceID string) context.Context
- func FromContext(ctx context.Context) *zerolog.Logger
- func GenerateTraceID() string
- func GetOrGenerateTraceID(ctx context.Context) string
- func IsSensitiveKey(key string) bool
- func NewLogger(cfg Config) zerolog.Logger
- func NewLoggerWithWriter(cfg Config, writer io.Writer) zerolog.Logger
- func PluginLogPathFromContext(ctx context.Context) string
- func PluginLogWriterFromContext(ctx context.Context) io.Writer
- func PrintFallbackWarning(w io.Writer, reason string)
- func PrintLogPathMessage(w io.Writer, path string)
- func SafeParams(params map[string]string) map[string]string
- func SafeStr(e *zerolog.Event, key, value string) *zerolog.Event
- func TraceIDFromContext(ctx context.Context) string
- type AuditEntry
- type AuditLogger
- type AuditLoggerConfig
- type CategorizedError
- func DeveloperError(message, solution string, cause error) *CategorizedError
- func FileSystemError(operation, path string, cause error) *CategorizedError
- func InvalidArgumentError(arg string, cause error) *CategorizedError
- func InvalidPulumiJSONError(path string, cause error) *CategorizedError
- func MissingConfigError(configKey string, cause error) *CategorizedError
- func NetworkError(operation string, cause error) *CategorizedError
- func PluginBugError(pluginName, operation string, cause error) *CategorizedError
- func PluginCommunicationError(pluginName string, cause error) *CategorizedError
- func PluginNotFoundError(pluginName string, cause error) *CategorizedError
- func ProtocolMismatchError(pluginName, expectedVersion, actualVersion string) *CategorizedError
- func SystemError(message, solution string, cause error) *CategorizedError
- func UserError(message, solution string, cause error) *CategorizedError
- type Config
- type ErrorCategory
- type LogPathResult
- type LoggingConfig
- type PhaseTimer
- type TracingHook
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ComponentLogger ¶
ComponentLogger creates a logger derived from the provided logger with the `component` field set to the given component name. It returns the derived logger that will include `component` in all emitted entries.
func ContextWithAuditLogger ¶
func ContextWithAuditLogger(ctx context.Context, logger AuditLogger) context.Context
ContextWithAuditLogger returns a copy of ctx that carries the provided AuditLogger under an internal package key.
func ContextWithPluginLogPath ¶ added in v0.3.0
ContextWithPluginLogPath stores the plugin log file path in the context. This path is propagated to plugin processes via FINFOCUS_LOG_FILE so that well-behaved plugins can configure their own structured logging to the same file.
func ContextWithPluginLogWriter ¶ added in v0.3.0
ContextWithPluginLogWriter stores a writer for plugin log output in the context. This writer is used by plugin launchers to redirect plugin stderr/stdout to the core log file instead of the terminal.
func ContextWithTraceID ¶
ContextWithTraceID stores a trace ID in the context.
func FromContext ¶
FromContext returns a logger from context, creating a default if none exists. FromContext returns a pointer to a zerolog.Logger associated with ctx, or a new default logger if none is present.
If no logger exists in the context, a default logger is created that writes to stderr, includes timestamps, and has the TracingHook applied so trace IDs from context are injected into log events. The default log level is taken from the environment variable named by pluginsdk.EnvLogLevel when valid; otherwise the level defaults to info. This function never returns nil.
func GenerateTraceID ¶
func GenerateTraceID() string
GenerateTraceID creates a new OpenTelemetry-format trace identifier. This uses the pluginsdk's GenerateTraceID which produces a 32-character lowercase hexadecimal string, compatible with OpenTelemetry and W3C Trace Context.
func GetOrGenerateTraceID ¶
GetOrGenerateTraceID returns a trace ID from environment, context, or generates a new one. Priority: FINFOCUS_TRACE_ID env var > context > generate new.
func IsSensitiveKey ¶
IsSensitiveKey checks if a key name contains sensitive patterns. IsSensitiveKey reports whether the provided parameter key is considered sensitive and should be redacted. It returns true if the key identifies sensitive data (for example, passwords, tokens, or keys), false otherwise.
func NewLogger ¶
NewLogger creates a logger configured according to cfg. The logger includes timestamps and trace ID injection, respects cfg.Level, cfg.Format, cfg.Caller and cfg.StackTrace, and writes to the destination specified by cfg.Output (file, stdout, or stderr). If a file destination is selected but cannot be opened, the logger falls back to stderr.
func NewLoggerWithWriter ¶
NewLoggerWithWriter creates a logger writing to the specified writer. This is primarily used for testing to capture log output.
func PluginLogPathFromContext ¶ added in v0.3.0
PluginLogPathFromContext extracts the plugin log file path from context. Returns empty string if no path is stored.
func PluginLogWriterFromContext ¶ added in v0.3.0
PluginLogWriterFromContext extracts the plugin log writer from context. Returns nil if no writer is stored, indicating that plugin output should use the default behavior (stderr).
func PrintFallbackWarning ¶
PrintFallbackWarning writes a single-line warning to w indicating that logging has fallen back to stderr. If reason is non-empty it is appended in parentheses after the message. The function ignores any write error.
func PrintLogPathMessage ¶
PrintLogPathMessage writes a "Logging to: <path>" message to the writer. PrintLogPathMessage writes "Logging to: <path>" followed by a newline to w. If path is empty, PrintLogPathMessage does nothing.
func SafeParams ¶
SafeParams returns a shallow copy of params where values for keys identified as sensitive are replaced with "[REDACTED]". The returned map preserves all original keys; non-sensitive values are copied unchanged.
func SafeStr ¶
SafeStr adds a string field to the event, redacting sensitive values. Use this when logging potentially sensitive key-value pairs.
func TraceIDFromContext ¶
TraceIDFromContext extracts the trace ID from context. Returns empty string if no trace ID is stored.
Types ¶
type AuditEntry ¶
type AuditEntry struct {
Timestamp time.Time // When the operation occurred
TraceID string // Request correlation ID
Command string // CLI command name (e.g., "cost projected")
Parameters map[string]string // Relevant parameters (file path, dates, etc.)
Duration time.Duration // How long the operation took
Success bool // Whether operation succeeded
ResultCount int // Number of results returned
TotalCost float64 // Total cost calculated (if applicable)
Error string // Error message if failed
}
AuditEntry represents an audit log record for cost operations.
func NewAuditEntry ¶
func NewAuditEntry(command, traceID string) *AuditEntry
NewAuditEntry creates a new AuditEntry with the given command and trace ID. NewAuditEntry creates a new AuditEntry with Timestamp set to the current UTC time and the provided command and traceID. It initializes Parameters as an empty map so callers can populate additional fields; use the With* builder methods to set duration, success, error, or parameters.
func (*AuditEntry) WithDuration ¶
func (e *AuditEntry) WithDuration(start time.Time) *AuditEntry
WithDuration calculates and sets the duration from the given start time.
func (*AuditEntry) WithError ¶
func (e *AuditEntry) WithError(errMsg string) *AuditEntry
WithError marks the entry as failed with the given error message.
func (*AuditEntry) WithParameters ¶
func (e *AuditEntry) WithParameters(params map[string]string) *AuditEntry
WithParameters adds parameters to the audit entry.
func (*AuditEntry) WithSuccess ¶
func (e *AuditEntry) WithSuccess(resultCount int, totalCost float64) *AuditEntry
WithSuccess marks the entry as successful with result count and total cost.
type AuditLogger ¶
type AuditLogger interface {
// Log writes an audit entry.
Log(ctx context.Context, entry AuditEntry)
// Enabled returns whether audit logging is active.
Enabled() bool
// Close releases any resources held by the logger (e.g., file handles).
Close() error
}
AuditLogger writes audit entries.
func AuditLoggerFromContext ¶
func AuditLoggerFromContext(ctx context.Context) AuditLogger
AuditLoggerFromContext extracts the AuditLogger from context. AuditLoggerFromContext retrieves the AuditLogger stored in ctx. It returns the AuditLogger found in the context, or a no-op AuditLogger if none is present.
func NewAuditLogger ¶
func NewAuditLogger(cfg AuditLoggerConfig) AuditLogger
NewAuditLogger creates a new AuditLogger with the given configuration.
NewAuditLogger creates an AuditLogger according to cfg. If cfg.Enabled is false, NewAuditLogger returns a no-op logger. If cfg.Writer is provided it is used as the destination; otherwise, if cfg.File is set the file is opened for append and used as the destination. If opening cfg.File fails or neither Writer nor File are provided, stderr is used as the destination. The returned logger emits structured audit records and reports Enabled() == true when auditing is active. Callers should call Close() when done to release any file handles.
func NoOpAuditLogger ¶
func NoOpAuditLogger() AuditLogger
NoOpAuditLogger returns an AuditLogger that performs no operations. The returned logger's Log method is a no-op and Enabled reports false.
type AuditLoggerConfig ¶
type AuditLoggerConfig struct {
Enabled bool // Enable audit logging
Writer io.Writer // Where to write audit logs (nil uses os.Stderr)
File string // Optional: separate audit file path
}
AuditLoggerConfig holds configuration for creating an AuditLogger.
type CategorizedError ¶
type CategorizedError struct {
Category ErrorCategory
Message string
Solution string
Context map[string]string
Cause error
}
CategorizedError represents an error with category, solution, and context.
func DeveloperError ¶
func DeveloperError(message, solution string, cause error) *CategorizedError
DeveloperError creates a developer error with debugging information.
func FileSystemError ¶
func FileSystemError(operation, path string, cause error) *CategorizedError
FileSystemError creates an error for filesystem operations.
func InvalidArgumentError ¶
func InvalidArgumentError(arg string, cause error) *CategorizedError
InvalidArgumentError creates an error for invalid CLI arguments.
func InvalidPulumiJSONError ¶
func InvalidPulumiJSONError(path string, cause error) *CategorizedError
InvalidPulumiJSONError creates an error for invalid Pulumi JSON.
func MissingConfigError ¶
func MissingConfigError(configKey string, cause error) *CategorizedError
MissingConfigError creates an error for missing configuration.
func NetworkError ¶
func NetworkError(operation string, cause error) *CategorizedError
NetworkError creates an error for network connectivity issues.
func PluginBugError ¶
func PluginBugError(pluginName, operation string, cause error) *CategorizedError
PluginBugError creates an error for plugin implementation bugs.
func PluginCommunicationError ¶
func PluginCommunicationError(pluginName string, cause error) *CategorizedError
PluginCommunicationError creates an error for plugin communication failures.
func PluginNotFoundError ¶
func PluginNotFoundError(pluginName string, cause error) *CategorizedError
PluginNotFoundError creates an error for missing plugins.
func ProtocolMismatchError ¶
func ProtocolMismatchError(pluginName, expectedVersion, actualVersion string) *CategorizedError
ProtocolMismatchError creates an error for protocol version mismatches.
func SystemError ¶
func SystemError(message, solution string, cause error) *CategorizedError
SystemError creates a system error with troubleshooting guidance.
func UserError ¶
func UserError(message, solution string, cause error) *CategorizedError
UserError creates a user-facing error with helpful guidance.
func (*CategorizedError) Error ¶
func (e *CategorizedError) Error() string
Error implements the error interface.
func (*CategorizedError) Unwrap ¶
func (e *CategorizedError) Unwrap() error
Unwrap returns the cause error for error wrapping.
func (*CategorizedError) WithContext ¶
func (e *CategorizedError) WithContext(key, value string) *CategorizedError
WithContext adds contextual information to the error. It returns a new error with the additional context to maintain immutability.
type Config ¶
type Config struct {
Level string // Log level: trace, debug, info, warn, error
Format string // Output format: json, console, text
Output string // Output destination: stderr, stdout, file
File string // File path when Output is "file"
Caller bool // Include file:line in output
StackTrace bool // Include stack trace on errors
}
Config holds logging configuration settings.
type ErrorCategory ¶
type ErrorCategory string
ErrorCategory represents the type of error for better user guidance.
const ( // ErrorCategoryUser indicates user-facing errors (invalid input, configuration). ErrorCategoryUser ErrorCategory = "USER" // ErrorCategorySystem indicates system errors (network, filesystem, permissions). ErrorCategorySystem ErrorCategory = "SYSTEM" // ErrorCategoryDeveloper indicates developer errors (bugs, protocol mismatches). ErrorCategoryDeveloper ErrorCategory = "DEVELOPER" )
type LogPathResult ¶
type LogPathResult struct {
Logger zerolog.Logger // The created logger
FilePath string // Path to log file (empty if not using file)
UsingFile bool // True if logging to file
FallbackUsed bool // True if fallback to stderr occurred
FallbackReason string // Reason for fallback (if any)
// contains filtered or unexported fields
}
LogPathResult contains the result of logger creation with file path information. This allows the CLI to communicate log file location to operators. Callers should call Close() when done to release any file handles.
func NewLoggerWithPath ¶
func NewLoggerWithPath(cfg Config) LogPathResult
NewLoggerWithPath creates a zerolog logger according to cfg and reports the chosen log destination.
If cfg.Output is "file" and cfg.File is non-empty, NewLoggerWithPath attempts to open or create the specified file and, on success, returns a logger that writes to that file and sets LogPathResult.FilePath and LogPathResult.UsingFile = true. If opening the file fails, the function falls back to stderr, sets LogPathResult.FallbackUsed = true and LogPathResult.FallbackReason to the error string, and returns a logger that writes to stderr. If cfg.File is empty the function uses stderr.
If cfg.Output is "stdout" the returned logger writes to stdout. For any other cfg.Output value the returned logger writes to stderr.
The returned LogPathResult contains the constructed Logger and metadata describing whether a file was used, the file path (if any), and whether a fallback to stderr occurred with its reason.
func (*LogPathResult) Close ¶
func (r *LogPathResult) Close() error
Close releases any resources held by the logger (e.g., file handles).
func (*LogPathResult) SetPluginLogFile ¶ added in v0.3.0
func (r *LogPathResult) SetPluginLogFile(f *os.File)
SetPluginLogFile stores a separate file handle for plugin I/O redirection. This handle is closed when Close() is called.
type LoggingConfig ¶
type LoggingConfig = Config
LoggingConfig is an alias for Config for backward compatibility.
type PhaseTimer ¶ added in v0.3.1
type PhaseTimer struct {
// contains filtered or unexported fields
}
PhaseTimer tracks elapsed time for named phases within a multi-step operation. Use StartPhase to begin timing a phase, then call Done on the returned PhaseTimer to log the phase completion with duration_ms.
func StartPhase ¶ added in v0.3.1
func StartPhase(ctx context.Context, component, operation, phase string) PhaseTimer
StartPhase begins timing a named phase within an operation. Call Done on the returned PhaseTimer to log completion with duration_ms. The phase start is logged at Debug level; completion is logged at Info level.
func (PhaseTimer) Done ¶ added in v0.3.1
func (t PhaseTimer) Done(ctx context.Context)
Done logs the phase completion at Info level with the elapsed time in milliseconds.
func (PhaseTimer) Elapsed ¶ added in v0.3.1
func (t PhaseTimer) Elapsed() time.Duration
Elapsed returns the duration since the phase started.
type TracingHook ¶
type TracingHook struct{}
TracingHook implements zerolog.Hook to automatically inject trace_id from context.