Documentation
¶
Overview ¶
Package slogs provides a lightweight, zero-external-dependency unified logging solution built on Go's standard log/slog package (Go 1.21+).
Features ¶
- Dual-target output: console (stdout) and file (JSON), dispatched via a built-in fan-out multiHandler.
- File rotation: built-in Rotator (adapted from lumberjack, MIT License) supports size-based rolling, backup retention, age-based cleanup, and gzip compression.
- Structured attributes: Logger.With attaches key-value context that propagates to all output targets.
- Named loggers: package-level CreateLogger/GetLogger manage multiple isolated logger instances via a singleton Manager.
- Global default: lazy-initialized default logger with package-level convenience functions (Info, Debug, Error, etc.).
Quick Start ¶
Zero-configuration usage with the global default logger:
slogs.Info("server started", "port", 8080)
slogs.Errorf("connection failed: %v", err)
Explicit initialization with file output:
cfg := slogs.NewConfig("debug", "logs/app.log", "json")
if err := slogs.Init(cfg); err != nil {
log.Fatal(err)
}
Standalone logger instance:
logger, err := slogs.NewLogger(slogs.LogConfig{
ConsoleLevel: "info",
LogFilePath: "logs/audit.log",
MaxSize: 50,
})
if err != nil {
log.Fatal(err)
}
defer logger.Close()
logger.Info("audit event", "user", "admin")
Named loggers for multi-module isolation:
scanLog, _ := slogs.CreateLogger("scan", slogs.NewConfig("info", "logs/scan.log", "json"))
auditLog, _ := slogs.CreateLogger("audit", slogs.NewConfig("debug", "logs/audit.log", "json"))
defer slogs.CloseAll()
Configuration ¶
The LogConfig struct controls logging behavior:
- ConsoleLevel: minimum log level for console output ("debug", "info", "warn", "error"; empty defaults to "info").
- FileLevel: minimum log level for file output ("debug", "info", "warn", "error"; empty defaults to "debug").
- ConsoleFormat: console output format: "text" or "json"; empty = mask "LCM"; a mask string (e.g. "TLCM") enables mask format; "off" disables console.
- LogFileFormat: file output format (same options; empty = json).
- LogFilePath: log file path; empty disables file output.
- MaxSize: max megabytes per file before rotation (default 100).
- MaxBackups: max old files to retain (default 3).
- MaxAge: max days to retain old files (default 30).
- Compress: gzip-compress rotated files (default true).
Console and file levels are independent: set ConsoleLevel to "info" for a quiet console while FileLevel defaults to "debug" so files capture debug logs.
Thread Safety ¶
All exported types and functions are safe for concurrent use. The Manager uses a read-write mutex; Logger and Rotator use internal synchronization.
Index ¶
- func CloseAll() error
- func Debug(msg string, args ...any)
- func DebugContext(ctx context.Context, msg string, args ...any)
- func Debugf(template string, args ...any)
- func Error(msg string, args ...any)
- func ErrorContext(ctx context.Context, msg string, args ...any)
- func Errorf(template string, args ...any)
- func Info(msg string, args ...any)
- func InfoContext(ctx context.Context, msg string, args ...any)
- func Infof(template string, args ...any)
- func Init(config LogConfig) error
- func LogAttrs(ctx context.Context, level slog.Level, msg string, attrs ...slog.Attr)
- func LogContext(ctx context.Context, level slog.Level, msg string, args ...any)
- func RemoveLogger(name string) error
- func SetDefault(logger *Logger)
- func Warn(msg string, args ...any)
- func WarnContext(ctx context.Context, msg string, args ...any)
- func Warnf(template string, args ...any)
- type LogConfig
- type Logger
- func (l *Logger) Close() error
- func (l *Logger) Debug(msg string, args ...any)
- func (l *Logger) DebugContext(ctx context.Context, msg string, args ...any)
- func (l *Logger) Debugf(template string, args ...any)
- func (l *Logger) Enabled(ctx context.Context, level slog.Level) bool
- func (l *Logger) Error(msg string, args ...any)
- func (l *Logger) ErrorContext(ctx context.Context, msg string, args ...any)
- func (l *Logger) Errorf(template string, args ...any)
- func (l *Logger) Info(msg string, args ...any)
- func (l *Logger) InfoContext(ctx context.Context, msg string, args ...any)
- func (l *Logger) Infof(template string, args ...any)
- func (l *Logger) Log(ctx context.Context, level slog.Level, msg string, args ...any)
- func (l *Logger) LogAttrs(ctx context.Context, level slog.Level, msg string, attrs ...slog.Attr)
- func (l *Logger) Slog() *slog.Logger
- func (l *Logger) Warn(msg string, args ...any)
- func (l *Logger) WarnContext(ctx context.Context, msg string, args ...any)
- func (l *Logger) Warnf(template string, args ...any)
- func (l *Logger) With(args ...any) *Logger
- type Manager
- type Rotator
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CloseAll ¶
func CloseAll() error
CloseAll closes all managed loggers, closes the default logger, and resets the registry.
func DebugContext ¶ added in v0.1.1
DebugContext logs at debug level using the default logger and context.
func ErrorContext ¶ added in v0.1.1
ErrorContext logs at error level using the default logger and context.
func InfoContext ¶ added in v0.1.1
InfoContext logs at info level using the default logger and context.
func Init ¶
Init initializes the global default logger with the given configuration. Once the default logger has been initialized (either via Init or lazy init), subsequent calls are no-ops and return nil.
Example ¶
ExampleInit demonstrates initializing the global default logger with file output.
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/winezer0/slogs"
)
func main() {
dir, _ := os.MkdirTemp("", "slogs-example")
defer os.RemoveAll(dir)
cfg := slogs.NewConfig("debug", filepath.Join(dir, "app.log"), "json")
if err := slogs.Init(cfg); err != nil {
fmt.Println("init error:", err)
return
}
slogs.Debug("initialized with file output")
// Output is written to stdout and the log file.
}
Output:
func LogAttrs ¶ added in v0.1.1
LogAttrs logs pre-built attributes at the supplied level using the default logger.
func LogContext ¶ added in v0.1.1
LogContext logs at the supplied level using the default logger and context.
func RemoveLogger ¶ added in v0.0.3
RemoveLogger removes and closes a named logger from the registry.
func SetDefault ¶
func SetDefault(logger *Logger)
SetDefault replaces the global default logger (useful for testing or late configuration). The previous default logger is closed to prevent resource leaks.
Example ¶
ExampleSetDefault demonstrates replacing the global default logger.
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/winezer0/slogs"
)
func main() {
dir, _ := os.MkdirTemp("", "slogs-example")
defer os.RemoveAll(dir)
cfg := slogs.NewConfig("warn", filepath.Join(dir, "warn.log"), "json")
logger, err := slogs.NewLogger(cfg)
if err != nil {
fmt.Println("error:", err)
return
}
defer logger.Close()
slogs.SetDefault(logger)
// Now package-level functions use the new logger.
slogs.Warn("disk usage high", "percent", 92)
}
Output:
func WarnContext ¶ added in v0.1.1
WarnContext logs at warn level using the default logger and context.
Types ¶
type LogConfig ¶ added in v0.1.0
type LogConfig struct {
// ConsoleLevel is the minimum log level for console output: debug, info, warn, error.
ConsoleLevel string `yaml:"console_level"`
// FileLevel is the minimum log level for file output: debug, info, warn, error.
// Empty string defaults to "debug".
FileLevel string `yaml:"file_level"`
// ConsoleFormat is the console (stdout) output format:
// "" - default mask "LCM"
// "text" - slog text (key=value)
// "json" - slog json
// "off" - disable console output
// otherwise - mask format (T=time, L=level, C=caller, M=message), e.g. "TLCM", "CM"
ConsoleFormat string `yaml:"console_format"`
// LogFileFormat is the file output format (same options as ConsoleFormat;
// empty defaults to "json").
LogFileFormat string `yaml:"log_file_format"`
// LogFilePath is the log file path; empty means no file output.
LogFilePath string `yaml:"log_file_path"`
// MaxSize is the maximum size in megabytes of a single log file before rotation.
MaxSize int `yaml:"max_size"`
// MaxBackups is the maximum number of old log files to retain.
MaxBackups int `yaml:"max_backups"`
// MaxAge is the maximum number of days to retain old log files.
MaxAge int `yaml:"max_age"`
// Compress determines whether rotated files are compressed.
Compress bool `yaml:"compress"`
}
LogConfig holds logging configuration.
func DefaultConfig ¶
func DefaultConfig() LogConfig
DefaultConfig 创建日志配置实例,提供全部默认值
Example ¶
ExampleDefaultConfig demonstrates obtaining the default configuration.
package main
import (
"fmt"
"github.com/winezer0/slogs"
)
func main() {
cfg := slogs.DefaultConfig()
fmt.Println(cfg.ConsoleLevel)
fmt.Println(cfg.FileLevel)
fmt.Println(cfg.MaxSize)
}
Output: info debug 100
func NewConfig ¶
NewConfig creates a LogConfig with the given console level, file path, and console format, applying defaults for rotation parameters. FileLevel is left empty (defaults to "debug" at runtime).
The format argument is stored verbatim in ConsoleFormat:
- "text", "json", "off" → console text / json / disabled
- a mask string (e.g. "TLCM", "CM") → console mask format
- empty → console defaults to mask "LCM"
Example ¶
ExampleNewConfig demonstrates creating a configuration with custom parameters.
package main
import (
"fmt"
"github.com/winezer0/slogs"
)
func main() {
cfg := slogs.NewConfig("error", "/var/log/myapp.log", "json")
fmt.Println(cfg.ConsoleLevel)
fmt.Println(cfg.FileLevel)
fmt.Println(cfg.LogFilePath)
fmt.Println(cfg.Compress)
}
Output: error debug /var/log/myapp.log true
type Logger ¶
type Logger struct {
// contains filtered or unexported fields
}
Logger wraps slog.Logger with configuration and lifecycle management.
func CreateLogger ¶
CreateLogger creates and registers a named logger.
Example ¶
ExampleCreateLogger demonstrates creating and retrieving named loggers.
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/winezer0/slogs"
)
func main() {
dir, _ := os.MkdirTemp("", "slogs-example")
defer os.RemoveAll(dir)
defer slogs.CloseAll()
_, err := slogs.CreateLogger("scan", slogs.NewConfig("info", filepath.Join(dir, "scan.log"), "off"))
if err != nil {
fmt.Println("error:", err)
return
}
logger, ok := slogs.GetLogger("scan")
fmt.Println("retrieved:", ok)
logger.Info("scan completed", "targets", 42)
}
Output: retrieved: true
func Default ¶
func Default() *Logger
Default returns the global default logger, initializing it if necessary.
Example ¶
ExampleDefault demonstrates using the global default logger with zero configuration.
package main
import (
"github.com/winezer0/slogs"
)
func main() {
logger := slogs.Default()
logger.Info("using default logger", "version", "1.0.0")
}
Output:
func NewLogger ¶
NewLogger creates a Logger from the given configuration. Console output goes to stdout; file output (if configured) uses rotation. A format value of "off" disables the corresponding target. If every target is disabled, the logger silently discards all records.
Console level comes from ConsoleLevel (empty defaults to "info"); file level comes from FileLevel (empty defaults to "debug").
Example ¶
ExampleNewLogger demonstrates creating a standalone logger instance.
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/winezer0/slogs"
)
func main() {
dir, _ := os.MkdirTemp("", "slogs-example")
defer os.RemoveAll(dir)
cfg := slogs.LogConfig{
ConsoleLevel: "info",
LogFilePath: filepath.Join(dir, "audit.log"),
MaxSize: 50,
MaxBackups: 5,
MaxAge: 14,
Compress: true,
}
logger, err := slogs.NewLogger(cfg)
if err != nil {
fmt.Println("error:", err)
return
}
defer logger.Close()
logger.Info("audit event", "user", "admin", "action", "login")
}
Output:
func (*Logger) DebugContext ¶ added in v0.1.1
DebugContext logs at debug level with the supplied context.
func (*Logger) Enabled ¶ added in v0.1.1
Enabled reports whether any configured output accepts the level.
func (*Logger) ErrorContext ¶ added in v0.1.1
ErrorContext logs at error level with the supplied context.
func (*Logger) InfoContext ¶ added in v0.1.1
InfoContext logs at info level with the supplied context.
func (*Logger) LogAttrs ¶ added in v0.1.1
LogAttrs records a message with pre-built attributes at the supplied level.
func (*Logger) WarnContext ¶ added in v0.1.1
WarnContext logs at warn level with the supplied context.
func (*Logger) With ¶
With returns a Logger with the given attributes attached.
Example ¶
ExampleLogger_With demonstrates attaching structured attributes to a logger.
package main
import (
"github.com/winezer0/slogs"
)
func main() {
logger := slogs.Default()
reqLogger := logger.With("request_id", "abc-123", "service", "gateway")
reqLogger.Info("processing request", "method", "GET", "path", "/api/users")
}
Output:
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager manages named logger instances.
func (*Manager) CloseAll ¶
CloseAll closes all managed loggers, closes the default logger, and clears the registry.
type Rotator ¶
type Rotator struct {
// Filename is the file to write logs to. Backup log files will be retained
// in the same directory.
Filename string
// MaxSize is the maximum size in megabytes of the log file before rotation.
// Defaults to 100 megabytes.
MaxSize int
// MaxAge is the maximum number of days to retain old log files.
MaxAge int
// MaxBackups is the maximum number of old log files to retain.
MaxBackups int
// LocalTime determines if the time used for formatting the timestamps in
// backup files is the computer's local time. Default is UTC.
LocalTime bool
// Compress determines if rotated log files should be compressed using gzip.
Compress bool
// contains filtered or unexported fields
}
Rotator is an io.WriteCloser that writes to a rotating log file.
Rotator opens or creates the logfile on first Write. If the file exists and is less than MaxSize megabytes, it will open and append to that file. If the file exists and its size is >= MaxSize megabytes, the file is renamed by putting the current time in a timestamp in the name immediately before the file's extension. A new log file is then created using original filename.
Backups use the form `name-timestamp.ext` where timestamp is formatted with `2006-01-02T15-04-05.000`.