logger

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jun 30, 2026 License: MIT Imports: 10 Imported by: 0

README

logger

A minimal, dependency-injection-friendly logging interface for Go libraries. It is silent by default and lets the consuming application plug in its own logging backend.

Install

go get github.com/0verkilll/logger

Sponsor

If this project is useful to you, please consider supporting its development:

Sponsor @0verkilll on GitHub

License

MIT

Documentation

Overview

Package logger provides a minimal, SOLID-compliant logging interface.

This package allows library authors to offer optional logging capabilities without forcing consumers to use a specific logging implementation. By default, all logs are silently discarded using NopLogger.

Usage:

// Set a custom logger
logger.SetLogger(myLogger)

// Use package-level functions
logger.Info("message", "key", "value")

// Or get the logger instance
log := logger.GetLogger()
log.WithFields("request_id", "abc123").Info("request received")

Package logger defines the core Logger and LeveledLogger interfaces.

Index

Constants

View Source
const (
	// LocaleEnUS is the English (United States) locale, used as the default.
	LocaleEnUS = "en-US"

	// LocaleEsES is the Spanish (Spain) locale.
	LocaleEsES = "es-ES"

	// LocaleFrFR is the French (France) locale.
	LocaleFrFR = "fr-FR"
)

Supported locale constants.

Variables

View Source
var (
	// ErrInvalidLevel is returned when parsing an unrecognized level string.
	ErrInvalidLevel = errors.New("logger: invalid log level")
)
View Source
var I18n = i18n.NewPackageTranslatorWithFS("logger", localeFS, "locales",
	i18n.WithDefaults(defaults),
)

I18n is the package-level translator for the logger package. It uses the shared i18n package's PackageTranslator pattern with namespace "logger". Without a translator configured, it returns English defaults from the defaults map above.

Functions

func Debug

func Debug(msg string, args ...any)

Debug logs a debug-level message using the global logger.

func DetectLocale

func DetectLocale() string

DetectLocale automatically detects the system locale from environment variables. It checks LC_ALL, LC_MESSAGES, and LANG in order, returning "en-US" as the default.

func Error

func Error(msg string, args ...any)

Error logs an error-level message using the global logger.

func Fatal

func Fatal(msg string, args ...any)

Fatal logs a fatal-level message using the global logger.

func GetSupportedLocales

func GetSupportedLocales() []string

GetSupportedLocales returns a sorted list of all supported locale codes. This includes all locales that have translation files embedded in the package.

Currently supported locales: en-US, es-ES, fr-FR

Additional locale files can be contributed to support more languages. See the locales/ directory for the translation file format.

Escape analysis: the []string slice and its append results escape to heap because they are returned to the caller. This is inherent to functions that build and return slices.

func Info

func Info(msg string, args ...any)

Info logs an info-level message using the global logger.

func ResetUnpairedWithFieldsCount

func ResetUnpairedWithFieldsCount()

ResetUnpairedWithFieldsCount resets the unpaired-WithFields counter to zero and re-arms the one-time warning. Intended for tests.

func SetLogger

func SetLogger(log Logger)

SetLogger sets the global logger. Pass nil to reset to the default NopLogger. This function is safe for concurrent use.

Escape analysis: the log parameter escapes to heap because it is stored in the package-level globalLogger interface variable. This is inherent to the global-logger pattern and cannot be avoided without removing the feature.

func SetTranslator

func SetTranslator(translator TranslatorProvider)

SetTranslator sets the global translator for the logger package. Pass nil to disable translations and use English defaults. This function is safe for concurrent use.

Escape analysis: the translator parameter escapes because it is stored in the I18n PackageTranslator. Inherent to setting a global translator.

func UnpairedWithFieldsCount

func UnpairedWithFieldsCount() uint64

UnpairedWithFieldsCount returns the total number of times the package-level WithFields helper has been invoked with an odd number of arguments (a trailing unpaired key). The value is cumulative for the lifetime of the process and is safe to read concurrently.

func Warn

func Warn(msg string, args ...any)

Warn logs a warn-level message using the global logger.

Types

type GenderCategory

type GenderCategory = i18n.GenderCategory

GenderCategory is a grammatical gender for message selection, aliased from the i18n package.

const (
	// Masculine represents the masculine grammatical gender.
	Masculine GenderCategory = "masculine"

	// Feminine represents the feminine grammatical gender.
	Feminine GenderCategory = "feminine"

	// Neuter represents the neuter grammatical gender.
	Neuter GenderCategory = "neuter"

	// GenderOther represents a grammatical gender that does not fit other categories.
	GenderOther GenderCategory = "other"
)

Gender category constants matching the i18n package.

type Level

type Level int

Level represents the severity of a log message. Levels are ordered from least to most severe: Debug < Info < Warn < Error < Fatal.

const (
	// LevelDebug is for detailed debugging information.
	LevelDebug Level = iota

	// LevelInfo is for general informational messages.
	LevelInfo

	// LevelWarn is for warning messages that indicate potential issues.
	LevelWarn

	// LevelError is for error messages that indicate failures.
	LevelError

	// LevelFatal is for fatal errors that require immediate termination.
	LevelFatal
)

Log levels ordered by severity. The numeric values are stable and can be used for serialization.

func ParseLevel

func ParseLevel(s string) (Level, error)

ParseLevel parses a level string and returns the corresponding Level. It accepts case-insensitive level names: "debug", "info", "warn", "error", "fatal". Returns ErrInvalidLevel if the string doesn't match any known level.

Example:

level, err := logger.ParseLevel("info")
if err != nil {
    // handle error
}

func (Level) String

func (l Level) String() string

String returns the string representation of the log level.

type LeveledLogger

type LeveledLogger interface {
	// Debug logs a debug-level message with optional format arguments.
	// Debug messages are for detailed debugging information.
	Debug(msg string, args ...any)

	// Info logs an info-level message with optional format arguments.
	// Info messages are for general informational messages.
	Info(msg string, args ...any)

	// Warn logs a warn-level message with optional format arguments.
	// Warn messages indicate potential issues that should be investigated.
	Warn(msg string, args ...any)

	// Error logs an error-level message with optional format arguments.
	// Error messages indicate failures that need attention.
	Error(msg string, args ...any)

	// Fatal logs a fatal-level message with optional format arguments.
	// Fatal messages indicate critical errors. Implementations may choose
	// to terminate the program after logging a fatal message.
	Fatal(msg string, args ...any)
}

LeveledLogger defines minimal leveled logging without fields or context. Use this interface when you only need basic logging capabilities. This follows the Interface Segregation Principle by providing a smaller interface for simpler use cases.

type Logger

type Logger interface {
	// LeveledLogger provides the core logging methods.
	LeveledLogger

	// WithFields returns a new Logger with additional structured fields.
	// Fields are provided as key-value pairs: ("user_id", 123, "action", "login").
	// Implementations should merge fields from parent loggers.
	WithFields(fields ...any) Logger

	// WithContext returns a new Logger with the given context.
	// Implementations can extract values from context such as trace IDs,
	// correlation IDs, or request-scoped values.
	WithContext(ctx context.Context) Logger

	// WithLevel returns a new Logger that only logs at or above the given level.
	// Messages below this level should be silently discarded.
	WithLevel(level Level) Logger

	// Enabled returns true if logging at the given level would produce output.
	// Use this to avoid expensive computation for disabled log levels:
	//
	//	if log.Enabled(LevelDebug) {
	//	    log.Debug("expensive: %v", computeExpensiveValue())
	//	}
	Enabled(level Level) bool
}

Logger defines the core logging interface. Implementations must be safe for concurrent use.

The interface follows SOLID principles:

  • Single Responsibility: focused on logging operations
  • Open/Closed: extensible through implementation
  • Liskov Substitution: any implementation is substitutable
  • Interface Segregation: LeveledLogger provides minimal subset
  • Dependency Inversion: depend on this abstraction, not concrete loggers

func GetLogger

func GetLogger() Logger

GetLogger returns the global logger. If no logger has been set, returns NopLogger. This function is safe for concurrent use.

func Log

func Log() Logger

Log returns the global logger. This is a convenience alias for GetLogger().

func WithContext

func WithContext(ctx context.Context) Logger

WithContext returns a new Logger with the given context using the global logger.

Escape analysis: the ctx parameter escapes because it is forwarded to the Logger interface method. Inherent to interface dispatch.

func WithField

func WithField(key string, value any) Logger

WithField returns a new Logger with a single structured field attached to the global logger. It is a typed, always-paired convenience over WithFields that eliminates the risk of providing an odd number of arguments.

Escape analysis: key and value escape because they are forwarded to the Logger interface method. Inherent to variadic ...any and interface dispatch.

func WithFields

func WithFields(fields ...any) Logger

WithFields returns a new Logger with the given fields using the global logger.

The fields parameter is expected to be an even-length sequence of key/value pairs: ("user_id", 123, "action", "login"). If an odd number of arguments is supplied the trailing unpaired argument is dropped, an internal counter is incremented (observable via UnpairedWithFieldsCount), and a one-time warning is emitted through the global logger. This keeps the historical "silently ignore trailing arg" behavior but surfaces the mistake so it can be fixed.

Escape analysis: the fields parameter escapes because it is forwarded to the Logger interface method. Inherent to variadic ...any and interface dispatch.

type NopLogger

type NopLogger struct{}

NopLogger is a silent logger that discards all messages. This is the default logger when no logger is configured. NopLogger is stateless and safe for concurrent use.

Coverage: the Debug, Info, Warn, Error, and Fatal methods have empty bodies (zero executable statements). Go's coverage tool reports 0% for these methods because there are no statements to instrument. Tests in nop_test.go call each method with various inputs and verify no panics occur. The 0% is a coverage tool limitation, not a testing gap.

func (NopLogger) Debug

func (NopLogger) Debug(string, ...any)

Debug discards the message.

func (NopLogger) Enabled

func (NopLogger) Enabled(Level) bool

Enabled always returns false since NopLogger never logs.

func (NopLogger) Error

func (NopLogger) Error(string, ...any)

Error discards the message.

func (NopLogger) Fatal

func (NopLogger) Fatal(string, ...any)

Fatal discards the message.

func (NopLogger) Info

func (NopLogger) Info(string, ...any)

Info discards the message.

func (NopLogger) Warn

func (NopLogger) Warn(string, ...any)

Warn discards the message.

func (NopLogger) WithContext

func (n NopLogger) WithContext(context.Context) Logger

WithContext returns the same NopLogger since context is not used.

Escape analysis: same as WithFields -- value receiver boxed into Logger interface.

func (NopLogger) WithFields

func (n NopLogger) WithFields(...any) Logger

WithFields returns the same NopLogger since fields are not used.

Escape analysis: the receiver n escapes to heap because the return type is the Logger interface; boxing a value type into an interface requires a heap allocation. This is inherent to interface-based returns and cannot be avoided without changing the Logger API contract.

func (NopLogger) WithLevel

func (n NopLogger) WithLevel(Level) Logger

WithLevel returns the same NopLogger since level filtering is not used.

Escape analysis: same as WithFields -- value receiver boxed into Logger interface.

type TranslatorProvider

type TranslatorProvider interface {
	// Translate returns the translated string for the given key.
	Translate(key string) string

	// TranslateWithArgs returns translated string with format arguments.
	TranslateWithArgs(key string, args ...interface{}) string

	// TranslatePlural returns count-dependent translation for the given key.
	TranslatePlural(key string, count interface{}) string

	// TranslateGender returns gender-aware translation for the given key.
	TranslateGender(key string, gender GenderCategory) string

	// HasKey returns true if the translation key exists.
	HasKey(key string) bool

	// SetLocale changes the current locale.
	SetLocale(locale string)

	// GetLocale returns the current locale.
	GetLocale() string
}

TranslatorProvider defines the interface for translation providers. This interface matches the i18n package's TranslatorProvider so that translators created by either package can be used interchangeably.

func GetTranslator

func GetTranslator() TranslatorProvider

GetTranslator returns the current global translator. Returns nil if no translator has been set. This function is safe for concurrent use.

func NewTranslator

func NewTranslator(locale string) (TranslatorProvider, error)

NewTranslator creates a new translator for the specified locale. Pass an empty string to auto-detect the locale from system environment variables. Returns an error if the translator cannot be initialized.

Escape analysis: the locale parameter escapes because it is passed to translator.SetLocale which stores it. Inherent to locale configuration.

Directories

Path Synopsis
internal
testutil
Package testutil provides test utilities for packages that use the logger package.
Package testutil provides test utilities for packages that use the logger package.
Package testing provides a mock Logger and assertion helpers for use in tests.
Package testing provides a mock Logger and assertion helpers for use in tests.

Jump to

Keyboard shortcuts

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