log

package
v0.54.7 Latest Latest
Warning

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

Go to latest
Published: Jan 27, 2026 License: MIT Imports: 21 Imported by: 4

Documentation

Index

Constants

View Source
const (
	// LevelTrace is the lowest priority (most verbose) log level.
	LevelTrace = "trace"
	// LevelDebug indicates information useful for developers.
	LevelDebug = "debug"
	// LevelInfo is the default level for operational logs.
	LevelInfo = "info"
	// LevelWarn indicates recoverable issues.
	LevelWarn = "warn"
	// LevelError indicates failures requiring attention.
	LevelError = "error"
	// LevelNone disables logging.
	LevelNone = "none"

	// PriorityTrace is the numeric priority for trace logs (0).
	PriorityTrace = 0
	// PriorityDebug is the numeric priority for debug logs (1).
	PriorityDebug = 1
	// PriorityInfo is the numeric priority for info logs (2).
	PriorityInfo = 2
	// PriorityWarn is the numeric priority for warn logs (3).
	PriorityWarn = 3
	// PriorityError is the numeric priority for error logs (4).
	PriorityError = 4
	// PriorityNone is used to indicate that no logging should be done.
	// Value is set to the maximum int value to ensure that it is always greater than any other priority.
	PriorityNone = math.MaxInt
)
View Source
const MessageAttributeLoggerContext = "logger:context"

Variables

This section is empty.

Functions

func AddHandlerFactory

func AddHandlerFactory(typ string, factory HandlerFactory)

AddHandlerFactory registers a new factory function for creating log handlers of a specific type. This allows for extending the logging system with custom handler implementations.

func AddHandlerIoWriterFactory

func AddHandlerIoWriterFactory(typ string, factory IoWriterWriterFactory)

AddHandlerIoWriterFactory registers a new factory function for creating the underlying writer for an "iowriter" handler. This allows for extending the "iowriter" handler with custom write destinations.

func AppendContextFields added in v0.13.0

func AppendContextFields(ctx context.Context, newFields map[string]any) context.Context

AppendContextFields appends the fields to the existing local context, creating a new context containing the merged fields.

Any existing fields with the same key as any new field provided will be overwritten.

This method breaks mutation links for the local context only. If you mutate global fields on the returned context and the original context was already mutable, it will see these changes as well. Example:

func mutateFields() {
	ctx := log.InitContext(context.Background())
	localCtx := log.AppendContextFields(ctx, map[string]any{
		"field": "value",
	})

	// mutations of local fields are only propagated to the local context
	localCtx = log.MutateContextFields(localCtx, map[string]any{
		"field": "new_value",
	})
	localFields := log.LocalOnlyContextFieldsResolver(localCtx)
	print(localFields["field"]) // "new_value"
	// the parent context wasn't changed
	localFields = log.LocalOnlyContextFieldsResolver(ctx)
	print(len(localFields)) // 0

	// mutations of global fields are still propagated to the original context
	localCtx = log.MutateGlobalContextFields(localCtx, map[string]any{
		"other_field": "other_value",
	})
	globalFields := log.GlobalContextFieldsResolver(ctx)
	print(globalFields["other_field"]) // "other_value"
}

func AppendGlobalContextFields added in v0.13.0

func AppendGlobalContextFields(ctx context.Context, newFields map[string]any) context.Context

AppendGlobalContextFields is similar to AppendContextFields, but appends to global fields instead.

func ContextFieldsResolver

func ContextFieldsResolver(ctx context.Context) map[string]any

ContextFieldsResolver extracts the local and global fields from a context and, if not present, it returns an empty map.

Global fields overwrite local fields of the same name.

func FlushFingersCrossedScope added in v0.54.4

func FlushFingersCrossedScope(ctx context.Context)

FlushFingersCrossedScope forces the flushing of all buffered logs in the current fingers-crossed scope. It is a no-op if the context does not contain a fingers-crossed scope.

func FormatterConsole

func FormatterConsole(timestamp string, level int, format string, args []any, err error, data Data) ([]byte, error)

FormatterConsole formats a log entry for console output, using colors for different parts of the log message.

func FormatterJson

func FormatterJson(timestamp string, level int, format string, args []any, err error, data Data) ([]byte, error)

FormatterJson formats a log entry as a JSON object, suitable for structured logging systems.

func FormatterSimple added in v0.36.1

func FormatterSimple(timestamp string, level int, format string, args []any, err error, data Data) ([]byte, error)

FormatterSimple formats a log entry as a simple text string without color codes.

func GetMockedStackTrace

func GetMockedStackTrace(depthSkip int) string

GetMockedStackTrace returns a fixed string "mocked trace". It is intended for use in tests where a predictable stack trace is required.

func GetStackTrace

func GetStackTrace(depthSkip int) string

GetStackTrace constructs the current stacktrace. depthSkip defines how many steps of the stacktrace should be skipped. This is useful to not clutter the stacktrace with logging function calls.

func GlobalContextFieldsResolver added in v0.13.0

func GlobalContextFieldsResolver(ctx context.Context) map[string]any

GlobalContextFieldsResolver extracts the global fields from a context and, if not present, it returns an empty map.

func InitContext added in v0.13.0

func InitContext(ctx context.Context) context.Context

InitContext returns a new context capable of carrying (mutable) local and global logger fields.

---------------------------------------------------------------------------------------------------------------------

A note about local and global context fields:

  • A local field is private to the current application. It will NOT be attached to stream.Messages or transferred in some other way to another service. Thus, it is somewhat cheaper to add local fields to a context as they will only not affect any downstream applications or increase message size.
  • A global field is the inverse of a local field. It will be forwarded with a message and thus "infect" other services. For some fields this might be desirable, for example, to record the identity of the user of an event. You should however be careful when adding many global fields as they will increase the size of any encoded message.

When logging messages, global fields overwrite local fields if they share the same name.

---------------------------------------------------------------------------------------------------------------------

A note about mutability: After using any of the methods returning a new context from this file (InitContext, AppendContextFields, MutateContextFields, AppendGlobalContextFields, MutateGlobalContextFields), the returned context will be mutable. This means that you can add context fields using MutateContextFields or MutateGlobalContextFields to the existing context (even though a new context is returned, it will be the same context if the context was already mutable). This allows for the following pattern:

func caller(ctx context.Context, logger log.Logger, input int) {
	ctx = log.InitContext(ctx)

	if result, err := callee(ctx, input); err == nil {
		logger.Info(ctx, "Computed result %d", result)
	} else {
		logger.Error(ctx, "Failed to compute result: %w", err)
	}
}

func callee(ctx context.Context, input int) (int, error) {
	_ = log.MutateContextFields(ctx, map[string]any{
		"input_value": input,
	})

	if input < 10 {
		return 0, fmt.Errorf("input must not be smaller than 10")
	}

	return input - 10, nil
}

After the callee returns, we add the (now mutated) context to the logger and will see the original input value in the logged fields even though it was for example not included in the error we got back.

func LevelName

func LevelName(level int) string

LevelName returns the string representation of a log level priority (e.g., 2 -> "info").

func LevelPriority

func LevelPriority(level string) (int, bool)

LevelPriority returns the numeric priority for a given log level name (e.g., "info" -> 2). It returns false if the level name is unknown.

func LocalOnlyContextFieldsResolver added in v0.13.0

func LocalOnlyContextFieldsResolver(ctx context.Context) map[string]any

LocalOnlyContextFieldsResolver extracts the local fields from a context and, if not present, it returns an empty map.

Warning: Besides very specific circumstances this method is most likely not what you want. Consider using GlobalContextFieldsResolver or ContextFieldsResolver instead. Outside of tests there shouldn't normally be a need to ignore any configured global fields from a context.

func MainLoggerConfigPostProcessor

func MainLoggerConfigPostProcessor(config cfg.GosoConf) (bool, error)

MainLoggerConfigPostProcessor ensures a "main" logger handler is configured. If not explicitly defined, it defaults to an "iowriter" handler.

func MutateContextFields added in v0.13.0

func MutateContextFields(ctx context.Context, newFields map[string]any) context.Context

MutateContextFields is similar to AppendContextFields, but it mutates the fields from the context if the context already contains fields which can be mutated. Otherwise, it initializes a new context able to carry fields in the future.

func MutateGlobalContextFields added in v0.13.0

func MutateGlobalContextFields(ctx context.Context, newFields map[string]any) context.Context

MutateGlobalContextFields is similar to MutateContextFields, but mutates to global fields instead.

func NewIoWriterFile

func NewIoWriterFile(path string) (io.Writer, error)

NewIoWriterFile creates a new io.Writer that appends to a file at the specified path. It opens the file with O_APPEND|O_WRONLY|O_CREATE flags and 0600 permissions.

func NewLogger

func NewLogger() *gosoLogger

NewLogger creates a new logger with a real clock and no handlers.

func NewLoggerWithInterfaces

func NewLoggerWithInterfaces(clock clock.Clock, handlers []Handler) *gosoLogger

NewLoggerWithInterfaces creates a new logger with the provided clock and handlers.

func SentryContextConfigProvider

func SentryContextConfigProvider(config ConfigProvider, handler *HandlerSentry) error

SentryContextConfigProvider attaches the entire configuration as context to Sentry events.

func SentryContextEcsMetadataProvider

func SentryContextEcsMetadataProvider(_ ConfigProvider, handler *HandlerSentry) error

SentryContextEcsMetadataProvider attaches ECS metadata (if available) as context to Sentry events.

func UnmarshalHandlerSettingsFromConfig

func UnmarshalHandlerSettingsFromConfig(config cfg.Config, name string, settings any) error

UnmarshalHandlerSettingsFromConfig extracts settings for a specific named handler from the configuration. It applies defaults where necessary, particularly for the log level.

func WithFingersCrossedScope added in v0.54.4

func WithFingersCrossedScope(ctx context.Context) context.Context

WithFingersCrossedScope creates a new context with a "fingers-crossed" logging scope. In this scope, logs are buffered and not immediately written. They are only flushed to the configured handlers if an error level log occurs within the scope (see Logger.log implementation) or if FlushFingersCrossedScope is called manually. This is useful for high-volume scenarios where detailed logs are only needed for debugging failures.

Types

type ChannelSetting added in v0.42.0

type ChannelSetting struct {
	Level string `cfg:"level"`
}

ChannelSetting configures the log level for a specific channel.

type ConfigProvider

type ConfigProvider interface {
	AllSettings() map[string]any
}

ConfigProvider defines an interface for retrieving all configuration settings as a map.

type ContextFieldsResolverFunction added in v0.13.0

type ContextFieldsResolverFunction func(ctx context.Context) map[string]any

ContextFieldsResolverFunction is a strategy for extracting logging fields from a context.Context.

type Data

type Data struct {
	Channel       string
	ContextFields map[string]any
	Fields        map[string]any
}

Data holds the structured context for a log entry, including channel, fields, and context-derived fields.

type EcsMetadata

type EcsMetadata map[string]any

EcsMetadata represents the container metadata provided by AWS ECS environment.

func ReadEcsMetadata

func ReadEcsMetadata() (EcsMetadata, error)

ReadEcsMetadata attempts to read and parse the ECS container metadata file. It waits until the metadata status is "READY" before returning the metadata. The path to the metadata file is determined by the ECS_CONTAINER_METADATA_FILE environment variable.

type Fields

type Fields map[string]any

Fields is a map of key-value pairs to add structured data to a log entry.

type Formatter

type Formatter func(timestamp string, level int, format string, args []any, err error, data Data) ([]byte, error)

Formatter is a function that formats a log entry into a byte slice. It receives metadata (timestamp, level, channel) and the log payload (message, args, error, fields).

type GosoLogger

type GosoLogger interface {
	Logger
	Option(opt ...Option) error
}

GosoLogger extends the Logger interface with the ability to apply functional options after creation.

type Handler

type Handler interface {
	ChannelLevel(name string) (level *int, err error)
	Level() int
	Log(ctx context.Context, timestamp time.Time, level int, msg string, args []any, err error, data Data) error
}

Handler defines the interface for log output destinations (e.g., console, file, Sentry). Implementations are responsible for writing the formatted log entry to the underlying resource.

func NewCliHandler

func NewCliHandler() Handler

NewCliHandler creates a handler configured for CLI output (console format, info level, stdout).

func NewHandlerIoWriter

func NewHandlerIoWriter(config cfg.Config, levelPriority int, formatter Formatter, name string, timestampFormat string, writer io.Writer) Handler

func NewHandlersFromConfig

func NewHandlersFromConfig(config cfg.Config) ([]Handler, error)

NewHandlersFromConfig creates a slice of log handlers based on the provided configuration. It parses the "log.handlers" section of the config and instantiates the corresponding handlers.

type HandlerFactory

type HandlerFactory func(config cfg.Config, name string) (Handler, error)

HandlerFactory is a function type for creating new handlers from configuration.

type HandlerIoWriterSettings

type HandlerIoWriterSettings struct {
	Level           string `cfg:"level" default:"info"`
	Formatter       string `cfg:"formatter" default:"console"`
	TimestampFormat string `cfg:"timestamp_format" default:"15:04:05.000"`
	Writer          string `cfg:"writer" default:"stdout"`
}

HandlerIoWriterSettings configures the "iowriter" handler, which writes logs to an io.Writer (e.g., stdout or file).

type HandlerSentry

type HandlerSentry struct {
	// contains filtered or unexported fields
}

HandlerSentry forwards log messages with error levels to Sentry.

func NewHandlerSentry

func NewHandlerSentry(config cfg.Config) (*HandlerSentry, error)

NewHandlerSentry creates a new Sentry handler initialized with settings from the provided configuration.

func (*HandlerSentry) ChannelLevel added in v0.46.0

func (h *HandlerSentry) ChannelLevel(string) (level *int, err error)

ChannelLevel returns nil for the Sentry handler, as it doesn't support channel-specific levels. It relies on the global level configuration.

func (*HandlerSentry) Level

func (h *HandlerSentry) Level() int

Level returns the default log level priority for the Sentry handler, which is PriorityError. This means, by default, only error logs are sent to Sentry.

func (*HandlerSentry) Log

func (h *HandlerSentry) Log(_ context.Context, _ time.Time, _ int, _ string, _ []any, err error, data Data) error

Log sends the error from the log entry to Sentry. It includes fields and context as Sentry context data.

func (*HandlerSentry) WithContext

func (h *HandlerSentry) WithContext(name string, context map[string]any)

WithContext adds contextual information to the Sentry scope for future errors.

type HandlerSettings

type HandlerSettings struct {
	Type string `cfg:"type"`
}

HandlerSettings defines the configuration for a single log handler (e.g., its type like "iowriter" or "sentry").

type IoWriterWriterFactory

type IoWriterWriterFactory func(config cfg.Config, configKey string) (io.Writer, error)

IoWriterWriterFactory is a factory function for creating the underlying io.Writer for an iowriter handler.

type Logger

type Logger interface {
	Debug(ctx context.Context, format string, args ...any)
	Info(ctx context.Context, format string, args ...any)
	Warn(ctx context.Context, format string, args ...any)
	Error(ctx context.Context, format string, args ...any)

	WithChannel(channel string) Logger
	WithFields(Fields) Logger
}

Logger is the main interface for logging. It supports standard log levels (Debug, Info, Warn, Error) and methods to create derived loggers with specific channels or fields.

func NewCliLogger

func NewCliLogger() Logger

NewCliLogger creates a logger suitable for CLI applications, writing to stdout.

func NewSamplingLogger

func NewSamplingLogger(logger Logger, interval time.Duration) Logger

type LoggerSettings

type LoggerSettings struct {
	Handlers map[string]HandlerSettings `cfg:"handlers"`
}

LoggerSettings holds the configuration for the main logger, specifically its handlers.

type MessageWithLoggingFieldsEncoder

type MessageWithLoggingFieldsEncoder struct {
	// contains filtered or unexported fields
}

MessageWithLoggingFieldsEncoder encodes context fields into message attributes during message production and decodes them back into the context during message consumption, enabling context propagation across boundaries.

func NewMessageWithLoggingFieldsEncoder

func NewMessageWithLoggingFieldsEncoder(_ cfg.Config, logger Logger) *MessageWithLoggingFieldsEncoder

NewMessageWithLoggingFieldsEncoder creates a new MessageWithLoggingFieldsEncoder. It uses a SamplingLogger to prevent flooding logs with warnings if context fields cannot be encoded.

func NewMessageWithLoggingFieldsEncoderWithInterfaces

func NewMessageWithLoggingFieldsEncoderWithInterfaces(logger Logger) *MessageWithLoggingFieldsEncoder

NewMessageWithLoggingFieldsEncoderWithInterfaces creates a new MessageWithLoggingFieldsEncoder with a specific logger.

func (MessageWithLoggingFieldsEncoder) Decode

Decode retrieves context fields from message attributes, deserializes them, and appends them to the context.

func (MessageWithLoggingFieldsEncoder) Encode

Encode extracts global context fields, serializes them to JSON, and adds them to message attributes. This allows fields to travel with the message.

type Option

type Option func(logger *gosoLogger) error

Option is a functional option pattern for configuring a GosoLogger.

func WithContextFieldsResolver

func WithContextFieldsResolver(resolvers ...ContextFieldsResolverFunction) Option

WithContextFieldsResolver adds custom context resolvers to the logger. These resolvers are used to extract fields from the context during logging.

func WithFields

func WithFields(tags map[string]any) Option

WithFields adds a default set of fields to every log entry created by this logger.

func WithHandlers

func WithHandlers(handler ...Handler) Option

WithHandlers adds additional log handlers to the logger.

func WithSamplingEnabled added in v0.54.4

func WithSamplingEnabled(enabled bool) Option

WithSamplingEnabled enables or disables log sampling for the logger.

type SamplingLogger

type SamplingLogger struct {
	Logger
	// contains filtered or unexported fields
}

SamplingLogger is a logger wrapper that rate-limits logs. Identical messages are suppressed if they occur within the configured interval.

func NewSamplingLoggerWithInterfaces

func NewSamplingLoggerWithInterfaces(logger Logger, clock clock.Clock, interval time.Duration) *SamplingLogger

NewSamplingLoggerWithInterfaces creates a new SamplingLogger with the given logger, clock, and interval.

func (*SamplingLogger) Debug

func (l *SamplingLogger) Debug(ctx context.Context, msg string, args ...any)

Debug logs a debug message if it passes sampling.

func (*SamplingLogger) Error

func (l *SamplingLogger) Error(ctx context.Context, msg string, args ...any)

Error logs an error message if it passes sampling.

func (*SamplingLogger) Info

func (l *SamplingLogger) Info(ctx context.Context, msg string, args ...any)

Info logs an info message if it passes sampling.

func (*SamplingLogger) Warn

func (l *SamplingLogger) Warn(ctx context.Context, msg string, args ...any)

Warn logs a warning message if it passes sampling.

func (*SamplingLogger) WithChannel

func (l *SamplingLogger) WithChannel(channel string) Logger

WithChannel returns a new sampling logger derived from the current one, but with a different channel.

func (*SamplingLogger) WithFields

func (l *SamplingLogger) WithFields(fields Fields) Logger

WithFields returns a new sampling logger with additional structured fields.

type SentryContextProvider

type SentryContextProvider func(config ConfigProvider, sentryHook *HandlerSentry) error

SentryContextProvider is a function type for attaching extra context (like config or ECS metadata) to the Sentry handler.

type SentryHub

type SentryHub interface {
	ConfigureScope(f func(scope *sentry.Scope))
	WithScope(f func(scope *sentry.Scope))
	CaptureException(exception error) *sentry.EventID
	Flush(timeout time.Duration) bool
}

SentryHub abstracts the Sentry SDK's Hub, allowing for testing and decoupling.

func NewSentryHub

func NewSentryHub(config cfg.Config) (SentryHub, error)

NewSentryHub creates a new SentryHub using configuration from the "app_id" settings.

func NewSentryHubWithSettings

func NewSentryHubWithSettings(settings *SentryHubSettings) (SentryHub, error)

NewSentryHubWithSettings creates a new SentryHub with the provided settings. It initializes the Sentry client and configures the scope with application tags.

type SentryHubSettings

type SentryHubSettings struct {
	Dsn         string
	Environment string
	AppFamily   string
	AppName     string
	AppGroup    string
}

SentryHubSettings configuration for establishing a connection to Sentry.

type StackTraceProvider

type StackTraceProvider func(depthSkip int) string

StackTraceProvider is a function type for generating a stack trace string, allowing for injection of mock providers in tests.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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