Documentation
¶
Overview ¶
Package logging provides structured logging utilities for the inboxfewer application.
This package centralizes logging patterns to ensure consistent, structured logging throughout the codebase using the standard library's slog package.
Key Features ¶
- Structured logging with slog
- PII sanitization (email anonymization)
- Consistent attribute naming across the codebase
- Logger adapter interface for flexibility
Usage Patterns ¶
Create a logger with standard attributes:
logger := logging.WithOperation(slog.Default(), "gmail.list")
logger.Info("listing emails",
logging.Status("success"))
Sanitize sensitive data before logging:
logger.Info("user operation",
logging.UserHash(email))
Security Considerations ¶
This package is designed with security in mind:
- User emails are hashed to prevent PII leakage while allowing correlation
- Tokens are never logged directly
Index ¶
- Constants
- func Account(account string) slog.Attr
- func AnonymizeEmail(email string) string
- func Domain(email string) slog.Attr
- func Err(err error) slog.Attr
- func ExtractDomain(email string) string
- func Operation(op string) slog.Attr
- func SanitizeToken(token string) string
- func Service(svc string) slog.Attr
- func Status(status string) slog.Attr
- func Tool(tool string) slog.Attr
- func UserHash(email string) slog.Attr
- func WithAccount(logger *slog.Logger, account string) *slog.Logger
- func WithOperation(logger *slog.Logger, operation string) *slog.Logger
- func WithService(logger *slog.Logger, service string) *slog.Logger
- func WithTool(logger *slog.Logger, tool string) *slog.Logger
- type Logger
- type SlogAdapter
Constants ¶
const ( KeyOperation = "operation" KeyService = "service" KeyAccount = "account" KeyUserHash = "user_hash" KeyDuration = "duration" KeyStatus = "status" KeyError = "error" KeyTool = "tool" )
Common log attribute keys for consistent naming across the codebase.
const ( StatusSuccess = "success" StatusError = "error" )
Status values for consistent logging. Note: These are intentionally duplicated from instrumentation package to avoid circular dependencies (instrumentation imports logging).
Variables ¶
This section is empty.
Functions ¶
func AnonymizeEmail ¶
AnonymizeEmail returns a hashed representation of an email for logging purposes. This allows correlation of log entries without exposing PII.
func Domain ¶
Domain returns a slog attribute for the email domain (lower cardinality than full email).
func Err ¶
Err returns a slog attribute for an error. If err is nil, returns an empty Group attribute that will be omitted from output. This allows safely passing Err(maybeNilErr) without adding empty attributes.
Usage:
logger.Info("operation", logging.Err(err)) // Safe even if err is nil
func ExtractDomain ¶
ExtractDomain extracts the domain part from an email address. This is useful for lower-cardinality logging where the full email would create too many unique values.
func SanitizeToken ¶
SanitizeToken returns a masked version of a token for logging. It returns a length indicator without exposing any token content, as even partial token prefixes (like JWT headers) can aid attacks.
func UserHash ¶
UserHash returns a slog attribute with the anonymized user email. This is a convenience function to reduce repetition in logging calls and ensure consistent attribute naming across the codebase.
Usage:
logger.Info("operation completed", logging.UserHash(user.Email))
func WithAccount ¶
WithAccount returns a logger with the account attribute set.
func WithOperation ¶
WithOperation returns a logger with the operation attribute set.
func WithService ¶
WithService returns a logger with the service attribute set.
Types ¶
type Logger ¶
type Logger interface {
Debug(msg string, args ...interface{})
Info(msg string, args ...interface{})
Warn(msg string, args ...interface{})
Error(msg string, args ...interface{})
}
Logger is the canonical interface for structured logging throughout the application. It provides a simple, level-based logging API compatible with slog.
type SlogAdapter ¶
type SlogAdapter struct {
// contains filtered or unexported fields
}
SlogAdapter adapts an slog.Logger to the Logger interface. This allows slog to be used with code that expects the simpler Logger interface.
func DefaultLogger ¶
func DefaultLogger() *SlogAdapter
DefaultLogger returns a Logger using the default slog.Logger.
func NewSlogAdapter ¶
func NewSlogAdapter(logger *slog.Logger) *SlogAdapter
NewSlogAdapter creates a new SlogAdapter wrapping the given slog.Logger. If logger is nil, slog.Default() is used.
func (*SlogAdapter) Debug ¶
func (a *SlogAdapter) Debug(msg string, args ...interface{})
Debug logs a debug message with key-value pairs. Arguments should be provided as alternating key-value pairs: key1, value1, key2, value2, ...
func (*SlogAdapter) Error ¶
func (a *SlogAdapter) Error(msg string, args ...interface{})
Error logs an error message with key-value pairs. Arguments should be provided as alternating key-value pairs: key1, value1, key2, value2, ...
func (*SlogAdapter) Info ¶
func (a *SlogAdapter) Info(msg string, args ...interface{})
Info logs an info message with key-value pairs. Arguments should be provided as alternating key-value pairs: key1, value1, key2, value2, ...
func (*SlogAdapter) Logger ¶
func (a *SlogAdapter) Logger() *slog.Logger
Logger returns the underlying slog.Logger for direct access when needed.
func (*SlogAdapter) Warn ¶
func (a *SlogAdapter) Warn(msg string, args ...interface{})
Warn logs a warning message with key-value pairs. Arguments should be provided as alternating key-value pairs: key1, value1, key2, value2, ...