concord/internal/common/logging/logging.go
2025-10-24 02:26:24 +03:00

105 lines
2.2 KiB
Go

package logging
import (
"context"
"os"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
type contextKey string
const (
loggerKey contextKey = "logger"
requestIDKey contextKey = "request_id"
)
var globalLogger *zap.Logger
func Init(level, format, output string, enableFile bool, filePath string) (*zap.Logger, error) {
zapLevel := zapcore.InfoLevel
switch level {
case "debug":
zapLevel = zapcore.DebugLevel
case "info":
zapLevel = zapcore.InfoLevel
case "warn":
zapLevel = zapcore.WarnLevel
case "error":
zapLevel = zapcore.ErrorLevel
}
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.TimeKey = "timestamp"
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
var encoder zapcore.Encoder
if format == "json" {
encoder = zapcore.NewJSONEncoder(encoderConfig)
} else {
encoder = zapcore.NewConsoleEncoder(encoderConfig)
}
var cores []zapcore.Core
if output == "stdout" || output == "" {
cores = append(cores, zapcore.NewCore(
encoder,
zapcore.AddSync(os.Stdout),
zapLevel,
))
}
if enableFile && filePath != "" {
file, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return nil, err
}
cores = append(cores, zapcore.NewCore(
encoder,
zapcore.AddSync(file),
zapLevel,
))
}
core := zapcore.NewTee(cores...)
logger := zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))
globalLogger = logger
return logger, nil
}
func FromContext(ctx context.Context) *zap.Logger {
if logger, ok := ctx.Value(loggerKey).(*zap.Logger); ok {
return logger
}
if globalLogger != nil {
return globalLogger
}
return zap.NewNop()
}
func WithLogger(ctx context.Context, logger *zap.Logger) context.Context {
return context.WithValue(ctx, loggerKey, logger)
}
func WithRequestID(ctx context.Context, requestID string) context.Context {
logger := FromContext(ctx).With(zap.String("request_id", requestID))
return WithLogger(ctx, logger)
}
func GetRequestID(ctx context.Context) string {
if requestID, ok := ctx.Value(requestIDKey).(string); ok {
return requestID
}
return ""
}
func L() *zap.Logger {
if globalLogger != nil {
return globalLogger
}
return zap.NewNop()
}