Documentation
¶
Overview ¶
Package log provides a minimal, backend-agnostic logging interface for the go-wind framework.
The package intentionally defines only an interface contract and a global registry — it ships no concrete logging backend. This keeps the framework core free of any logging dependency; projects adapt their own backend (the stdlib *slog.Logger, zap, zerolog, kratos log, …) with a few lines of glue code. A zero-cost [nopLogger] is included as the silent default so that importing the package has no side effects; concrete adapters (slog adapter, LevelFilter, MultiLogger) live in go-wind-plugins.
The Logger interface ¶
Logger is deliberately small — 4 log methods (Logger.Debug, Logger.Info, Logger.Warn, Logger.Error) plus Logger.Enabled and Logger.With — so adapting any backend is trivial:
type zapAdapter struct{ l *zap.Logger }
func (z zapAdapter) Info(ctx context.Context, msg string, args ...any) { … }
// … implement Debug/Warn/Error/Enabled/With likewise
The first argument is always a context.Context so backends that support it can extract trace ids or request-scoped attributes. Callers with no context at hand may pass nil.
Injecting a backend ¶
Use SetLogger to install the package-level logger used by the framework, and GetLogger to read it. Both are safe to call concurrently with log calls. Pass nil to SetLogger to revert to the silent nopLogger:
windlog.SetLogger(myZapAdapter{})
defer windlog.SetLogger(nil)
Submodules obtain the shared logger via GetLogger without taking a direct dependency on any logging framework.
Global helper functions ¶
For convenience, the package also provides global helper functions (Debug, Info, Warn, Error, Enabled, With) that forward to the current package-level logger:
log.Info(ctx, "server started", "addr", addr)
if log.Enabled(log.LevelDebug) {
log.Debug(ctx, "detail", expensiveState())
}
Guarding expensive arguments ¶
Logger.Enabled lets callers avoid constructing expensive log arguments when the level would be discarded:
if logger.Enabled(log.LevelDebug) {
logger.Debug(ctx, "detail", computeExpensiveData())
}
Level enumerates the standard severities (LevelDebug … LevelError) and is the argument type for Logger.Enabled.
Attaching context to a logger ¶
Logger.With returns a new Logger with key-value pairs permanently attached, typically used to tag a module or request:
moduleLogger := logger.With("module", "registry")
moduleLogger.Info(ctx, "started")
Index ¶
- func Debug(ctx context.Context, msg string, args ...any)
- func Enabled(level Level) bool
- func Error(ctx context.Context, msg string, args ...any)
- func Info(ctx context.Context, msg string, args ...any)
- func SetLogger(l Logger)
- func Warn(ctx context.Context, msg string, args ...any)
- type Level
- type Logger
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Enabled ¶ added in v0.0.2
Enabled reports whether the global logger emits records at the given level.
func SetLogger ¶
func SetLogger(l Logger)
SetLogger sets the package-level Logger used by the framework. Pass nil to revert to the silent nopLogger.
SetLogger is safe to call concurrently with log calls; callers that want to mutate the logger without races should hold their own coordination.
Example ¶
ExampleSetLogger demonstrates setting the package-level global logger. After this call, all code using log.GetLogger will receive the new logger. Pass nil to revert to the silent nopLogger.
package main
import (
"context"
"github.com/tx7do/go-wind/log"
)
func main() {
// Use a custom Logger implementation or one from go-wind-plugins.
// Here we demonstrate the global logger lifecycle.
log.SetLogger(nil) // revert to nopLogger
defer log.SetLogger(nil)
logger := log.GetLogger()
logger.Info(context.Background(), "hello from global logger")
}
Output:
Types ¶
type Level ¶
type Level int
Level represents a log severity level. Higher values are more severe. It is used as an argument to Logger.Enabled to check whether a given level would be emitted by the underlying backend.
Standard log levels ordered from least to most severe.
type Logger ¶
type Logger interface {
// Debug logs a message at DEBUG level with optional structured key/value
// pairs passed as args (alternating keys and values).
Debug(ctx context.Context, msg string, args ...any)
// Info logs a message at INFO level.
Info(ctx context.Context, msg string, args ...any)
// Warn logs a message at WARN level.
Warn(ctx context.Context, msg string, args ...any)
// Error logs a message at ERROR level.
Error(ctx context.Context, msg string, args ...any)
// Enabled reports whether the logger emits records at the given [Level].
// Expensive argument construction can be guarded by this check:
//
// if logger.Enabled(log.LevelDebug) {
// logger.Debug(ctx, "detail", computeExpensiveData())
// }
Enabled(level Level) bool
// With returns a new Logger instance with the given key-value pairs
// attached. This is typically used to distinguish modules, e.g.,
// logger.With("module", "registry").
With(args ...any) Logger
}
Logger is the minimal logging interface used throughout the framework. See the package documentation (doc.go) for how to adapt a backend and inject it.
Example ¶
ExampleLogger demonstrates the Logger interface contract. Callers implement this interface to bridge their own logging backend.
package main
import (
"context"
"fmt"
"github.com/tx7do/go-wind/log"
)
func main() {
// A minimal custom logger implementation:
var l log.Logger = myLogger{}
// All methods take context as the first argument for trace propagation.
l.Debug(context.Background(), "debug message", "key", "value")
l.Info(context.Background(), "info message")
l.Warn(context.Background(), "warn message")
l.Error(context.Background(), "error message")
// Enabled lets callers guard expensive argument construction.
if l.Enabled(log.LevelDebug) {
l.Debug(context.Background(), "expensive", computeData())
}
// With returns a new logger with attached key-value pairs.
child := l.With("module", "example")
child.Info(context.Background(), "child logger")
}
func computeData() any { return nil }
// myLogger is a minimal Logger implementation for demonstration purposes.
type myLogger struct{}
func (myLogger) Debug(context.Context, string, ...any) { fmt.Println("DEBUG") }
func (myLogger) Info(context.Context, string, ...any) { fmt.Println("INFO") }
func (myLogger) Warn(context.Context, string, ...any) { fmt.Println("WARN") }
func (myLogger) Error(context.Context, string, ...any) { fmt.Println("ERROR") }
func (myLogger) Enabled(log.Level) bool { return true }
func (l myLogger) With(args ...any) log.Logger { return l }
Output: DEBUG INFO WARN ERROR DEBUG INFO