diff options
Diffstat (limited to 'logging')
-rw-r--r-- | logging/logging.go | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/logging/logging.go b/logging/logging.go new file mode 100644 index 0000000..59916b4 --- /dev/null +++ b/logging/logging.go @@ -0,0 +1,95 @@ +package logging + +import ( + "context" + "sync" + + "github.com/gin-gonic/gin" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +type contextKey = string + +const loggerKey = contextKey("logger") + +var ( + defaultLogger *zap.SugaredLogger + defaultLoggerOnce sync.Once +) + +var conf = &Config{ + Encoding: "console", + Level: zapcore.InfoLevel, + Development: true, +} + +type Config struct { + Encoding string + Level zapcore.Level + Development bool +} + +// SetConfig sets given logging configs for DefaultLogger's logger. +// Must set configs before calling DefaultLogger() +func SetConfig(c *Config) { + conf = &Config{ + Encoding: c.Encoding, + Level: c.Level, + Development: c.Development, + } +} + +func SetLevel(l zapcore.Level) { + conf.Level = l +} + +// NewLogger creates a new logger with the given log level +func NewLogger(conf *Config) *zap.SugaredLogger { + ec := zap.NewProductionEncoderConfig() + ec.EncodeTime = zapcore.ISO8601TimeEncoder + cfg := zap.Config{ + Encoding: conf.Encoding, + EncoderConfig: ec, + Level: zap.NewAtomicLevelAt(conf.Level), + Development: conf.Development, + OutputPaths: []string{"stdout"}, + ErrorOutputPaths: []string{"stderr"}, + } + logger, err := cfg.Build() + if err != nil { + logger = zap.NewNop() + } + return logger.Sugar() +} + +// DefaultLogger returns the default logger for the package. +func DefaultLogger() *zap.SugaredLogger { + defaultLoggerOnce.Do(func() { + defaultLogger = NewLogger(conf) + }) + return defaultLogger +} + +// WithLogger creates a new context with the provided logger attached. +func WithLogger(ctx context.Context, logger *zap.SugaredLogger) context.Context { + if gCtx, ok := ctx.(*gin.Context); ok { + ctx = gCtx.Request.Context() + } + return context.WithValue(ctx, loggerKey, logger) +} + +// FromContext returns the logger stored in the context. If no such logger +// exists, a default logger is returned. +func FromContext(ctx context.Context) *zap.SugaredLogger { + if ctx == nil { + return DefaultLogger() + } + if gCtx, ok := ctx.(*gin.Context); ok && gCtx != nil { + ctx = gCtx.Request.Context() + } + if logger, ok := ctx.Value(loggerKey).(*zap.SugaredLogger); ok { + return logger + } + return DefaultLogger() +} |