189 lines
4.7 KiB
Go
189 lines
4.7 KiB
Go
package logger
|
|
|
|
import (
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
)
|
|
|
|
var (
|
|
Log *zap.Logger
|
|
Sugar *zap.SugaredLogger
|
|
)
|
|
|
|
// Config holds logger configuration
|
|
type Config struct {
|
|
Level string `mapstructure:"level"`
|
|
Encoding string `mapstructure:"encoding"`
|
|
OutputPath string `mapstructure:"output_path"`
|
|
}
|
|
|
|
// Init initializes the global logger
|
|
func Init(cfg *Config) error {
|
|
level := zapcore.InfoLevel
|
|
if cfg != nil && cfg.Level != "" {
|
|
if err := level.UnmarshalText([]byte(cfg.Level)); err != nil {
|
|
return err
|
|
}
|
|
// Debug output to verify level parsing
|
|
println("DEBUG: Parsed level:", level.String())
|
|
}
|
|
|
|
encoding := "json"
|
|
if cfg != nil && cfg.Encoding != "" {
|
|
encoding = cfg.Encoding
|
|
}
|
|
|
|
outputPath := "stdout"
|
|
if cfg != nil && cfg.OutputPath != "" {
|
|
outputPath = cfg.OutputPath
|
|
}
|
|
|
|
atomicLevel := zap.NewAtomicLevelAt(level)
|
|
println("DEBUG: Created AtomicLevel:", atomicLevel.String())
|
|
|
|
zapConfig := zap.Config{
|
|
Level: atomicLevel,
|
|
Development: true, // Changed to true to test if this affects debug logging
|
|
DisableCaller: false,
|
|
DisableStacktrace: false,
|
|
Sampling: nil,
|
|
Encoding: encoding,
|
|
EncoderConfig: zapcore.EncoderConfig{
|
|
MessageKey: "message",
|
|
LevelKey: "level",
|
|
TimeKey: "time",
|
|
NameKey: "logger",
|
|
CallerKey: "caller",
|
|
FunctionKey: zapcore.OmitKey,
|
|
StacktraceKey: "stacktrace",
|
|
LineEnding: zapcore.DefaultLineEnding,
|
|
EncodeLevel: zapcore.LowercaseLevelEncoder,
|
|
EncodeTime: zapcore.ISO8601TimeEncoder,
|
|
EncodeDuration: zapcore.SecondsDurationEncoder,
|
|
EncodeCaller: zapcore.ShortCallerEncoder,
|
|
},
|
|
OutputPaths: []string{outputPath},
|
|
ErrorOutputPaths: []string{"stderr"},
|
|
}
|
|
|
|
var err error
|
|
Log, err = zapConfig.Build()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
println("DEBUG: After Build, AtomicLevel:", atomicLevel.String())
|
|
println("DEBUG: After Build, Log.Level():", Log.Level().String())
|
|
|
|
// TEST: Try to log a debug message immediately after Build()
|
|
Log.Debug("INTERNAL TEST: Debug log immediately after Build()")
|
|
Log.Info("INTERNAL TEST: Info log immediately after Build()")
|
|
|
|
Sugar = Log.Sugar()
|
|
|
|
// Replace global zap logger to ensure our config takes effect
|
|
zap.ReplaceGlobals(Log)
|
|
|
|
// Debug output to verify logger initialization
|
|
println("DEBUG: Logger initialized with level:", Log.Level().String())
|
|
|
|
return nil
|
|
}
|
|
|
|
// InitDevelopment initializes logger for development environment
|
|
func InitDevelopment() error {
|
|
var err error
|
|
Log, err = zap.NewDevelopment()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
Sugar = Log.Sugar()
|
|
return nil
|
|
}
|
|
|
|
// InitProduction initializes logger for production environment
|
|
func InitProduction() error {
|
|
var err error
|
|
Log, err = zap.NewProduction()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
Sugar = Log.Sugar()
|
|
return nil
|
|
}
|
|
|
|
// Sync flushes any buffered log entries
|
|
func Sync() error {
|
|
if Log != nil {
|
|
return Log.Sync()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// WithFields creates a new logger with additional fields
|
|
func WithFields(fields ...zap.Field) *zap.Logger {
|
|
return Log.With(fields...)
|
|
}
|
|
|
|
// Debug logs a debug message
|
|
func Debug(msg string, fields ...zap.Field) {
|
|
Log.Debug(msg, fields...)
|
|
}
|
|
|
|
// Info logs an info message
|
|
func Info(msg string, fields ...zap.Field) {
|
|
Log.Info(msg, fields...)
|
|
}
|
|
|
|
// Warn logs a warning message
|
|
func Warn(msg string, fields ...zap.Field) {
|
|
Log.Warn(msg, fields...)
|
|
}
|
|
|
|
// Error logs an error message
|
|
func Error(msg string, fields ...zap.Field) {
|
|
Log.Error(msg, fields...)
|
|
}
|
|
|
|
// Fatal logs a fatal message and exits
|
|
func Fatal(msg string, fields ...zap.Field) {
|
|
Log.Fatal(msg, fields...)
|
|
}
|
|
|
|
// Panic logs a panic message and panics
|
|
func Panic(msg string, fields ...zap.Field) {
|
|
Log.Panic(msg, fields...)
|
|
}
|
|
|
|
// Field creates a zap field
|
|
func Field(key string, value interface{}) zap.Field {
|
|
return zap.Any(key, value)
|
|
}
|
|
|
|
// String creates a string field
|
|
func String(key, value string) zap.Field {
|
|
return zap.String(key, value)
|
|
}
|
|
|
|
// Int creates an int field
|
|
func Int(key string, value int) zap.Field {
|
|
return zap.Int(key, value)
|
|
}
|
|
|
|
// Err creates an error field
|
|
func Err(err error) zap.Field {
|
|
return zap.Error(err)
|
|
}
|
|
|
|
// Removed init() function to prevent it from overriding logger config.
|
|
// The logger will be initialized when Init() is explicitly called with config.
|
|
// func init() {
|
|
// // Initialize with development logger by default
|
|
// // This will be overridden when Init() is called with proper config
|
|
// if os.Getenv("ENV") == "production" {
|
|
// _ = InitProduction()
|
|
// } else {
|
|
// _ = InitDevelopment()
|
|
// }
|
|
// }
|