Files
MyClub/pkg/logger/logger.go
T
Tomas Dvorak 30d70a6aeb update
2026-03-13 14:34:19 +01:00

142 lines
3.4 KiB
Go

package logger
import (
"os"
"strings"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
// Log levels
const (
LevelDebug = "DEBUG"
LevelInfo = "INFO"
LevelWarn = "WARN"
LevelError = "ERROR"
)
// Logger represents a leveled zap-backed logger while preserving the package API.
type Logger struct {
level zap.AtomicLevel
sugar *zap.SugaredLogger
}
var (
// DefaultLogger is the default logger instance.
DefaultLogger = NewLogger(LevelInfo)
)
func parseLevel(level string) zapcore.Level {
switch strings.ToUpper(strings.TrimSpace(level)) {
case LevelDebug:
return zap.DebugLevel
case LevelWarn:
return zap.WarnLevel
case LevelError:
return zap.ErrorLevel
default:
return zap.InfoLevel
}
}
func newZapLogger(level zap.AtomicLevel) *zap.SugaredLogger {
cfg := zap.NewProductionConfig()
cfg.Encoding = "console"
cfg.Level = level
cfg.OutputPaths = []string{"stderr"}
cfg.ErrorOutputPaths = []string{"stderr"}
cfg.DisableStacktrace = true
cfg.EncoderConfig.TimeKey = "ts"
cfg.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
cfg.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
cfg.EncoderConfig.EncodeDuration = zapcore.StringDurationEncoder
cfg.EncoderConfig.CallerKey = ""
logger, err := cfg.Build()
if err != nil {
fallback := zap.New(
zapcore.NewCore(
zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig()),
zapcore.Lock(os.Stderr),
level,
),
)
return fallback.Sugar()
}
return logger.Sugar()
}
// NewLogger creates a new logger instance with the specified log level.
func NewLogger(level string) *Logger {
atomicLevel := zap.NewAtomicLevelAt(parseLevel(level))
return &Logger{
level: atomicLevel,
sugar: newZapLogger(atomicLevel),
}
}
// SetLevel changes the logger level at runtime.
func (l *Logger) SetLevel(level string) {
if l == nil {
return
}
l.level.SetLevel(parseLevel(level))
}
func (l *Logger) logWithFormat(logFn func(string, ...interface{}), plainFn func(...interface{}), message string, args ...interface{}) {
if len(args) == 0 {
plainFn(message)
return
}
logFn(message, args...)
}
// Debug logs a debug message.
func (l *Logger) Debug(message string, args ...interface{}) {
l.logWithFormat(l.sugar.Debugf, l.sugar.Debug, message, args...)
}
// Info logs an info message.
func (l *Logger) Info(message string, args ...interface{}) {
l.logWithFormat(l.sugar.Infof, l.sugar.Info, message, args...)
}
// Warn logs a warning message.
func (l *Logger) Warn(message string, args ...interface{}) {
l.logWithFormat(l.sugar.Warnf, l.sugar.Warn, message, args...)
}
// Error logs an error message.
func (l *Logger) Error(message string, args ...interface{}) {
l.logWithFormat(l.sugar.Errorf, l.sugar.Error, message, args...)
}
// SetLevel changes the default logger level at runtime.
func SetLevel(level string) {
if DefaultLogger != nil {
DefaultLogger.SetLevel(level)
}
}
// Debug logs a debug message using the default logger.
func Debug(message string, args ...interface{}) {
DefaultLogger.Debug(message, args...)
}
// Info logs an info message using the default logger.
func Info(message string, args ...interface{}) {
DefaultLogger.Info(message, args...)
}
// Warn logs a warning message using the default logger.
func Warn(message string, args ...interface{}) {
DefaultLogger.Warn(message, args...)
}
// Error logs an error message using the default logger.
func Error(message string, args ...interface{}) {
DefaultLogger.Error(message, args...)
}