You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
278 lines
7.7 KiB
278 lines
7.7 KiB
package log
|
|
|
|
import (
|
|
"OpenIM/pkg/common/config"
|
|
"OpenIM/pkg/common/constant"
|
|
"OpenIM/pkg/common/tracelog"
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/go-logr/logr"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
)
|
|
|
|
var (
|
|
discardLogger = logr.Discard()
|
|
defaultLogger Logger = LogRLogger(discardLogger)
|
|
pkgLogger Logger = LogRLogger(discardLogger)
|
|
)
|
|
|
|
// InitFromConfig initializes a Zap-based logger
|
|
func InitFromConfig(name string) {
|
|
//var c zap.Config
|
|
//file, _ := os.Create(config.Config.Log.StorageLocation)
|
|
//writeSyncer := zapcore.AddSync(file)
|
|
|
|
l, err := NewZapLogger()
|
|
if err == nil {
|
|
setLogger(l, name)
|
|
}
|
|
}
|
|
|
|
// GetLogger returns the logger that was set with SetLogger with an extra depth of 1
|
|
func GetLogger() Logger {
|
|
return defaultLogger
|
|
}
|
|
|
|
// SetLogger lets you use a custom logger. Pass in a logr.Logger with default depth
|
|
func setLogger(l Logger, name string) {
|
|
defaultLogger = l.WithCallDepth(1).WithName(name)
|
|
// pkg wrapper needs to drop two levels of depth
|
|
pkgLogger = l.WithCallDepth(2).WithName(name)
|
|
}
|
|
|
|
func Debug(ctx context.Context, msg string, keysAndValues ...interface{}) {
|
|
pkgLogger.Debug(ctx, msg, keysAndValues...)
|
|
}
|
|
|
|
func Info(ctx context.Context, msg string, keysAndValues ...interface{}) {
|
|
pkgLogger.Info(ctx, msg, keysAndValues...)
|
|
}
|
|
|
|
func Warn(ctx context.Context, msg string, err error, keysAndValues ...interface{}) {
|
|
pkgLogger.Warn(ctx, msg, err, keysAndValues...)
|
|
}
|
|
|
|
func Error(ctx context.Context, msg string, err error, keysAndValues ...interface{}) {
|
|
pkgLogger.Error(ctx, msg, err, keysAndValues...)
|
|
}
|
|
|
|
func ParseZapLevel(level string) zapcore.Level {
|
|
lvl := zapcore.InfoLevel
|
|
if level != "" {
|
|
_ = lvl.UnmarshalText([]byte(level))
|
|
}
|
|
return lvl
|
|
}
|
|
|
|
type Logger interface {
|
|
Debug(ctx context.Context, msg string, keysAndValues ...interface{})
|
|
Info(ctx context.Context, msg string, keysAndValues ...interface{})
|
|
Warn(ctx context.Context, msg string, err error, keysAndValues ...interface{})
|
|
Error(ctx context.Context, msg string, err error, keysAndValues ...interface{})
|
|
WithValues(keysAndValues ...interface{}) Logger
|
|
WithName(name string) Logger
|
|
WithCallDepth(depth int) Logger
|
|
WithItemSampler() Logger
|
|
// WithoutSampler returns the original logger without sampling
|
|
WithoutSampler() Logger
|
|
}
|
|
|
|
type ZapLogger struct {
|
|
zap *zap.SugaredLogger
|
|
// store original logger without sampling to avoid multiple samplers
|
|
unsampled *zap.SugaredLogger
|
|
SampleDuration time.Duration
|
|
SampleInitial int
|
|
SampleInterval int
|
|
}
|
|
|
|
func NewZapLogger() (*ZapLogger, error) {
|
|
zapConfig := zap.Config{
|
|
Level: zap.NewAtomicLevelAt(zapcore.DebugLevel),
|
|
Development: true,
|
|
Encoding: "json",
|
|
EncoderConfig: zap.NewProductionEncoderConfig(),
|
|
OutputPaths: []string{config.Config.Log.StorageLocation},
|
|
ErrorOutputPaths: []string{"stderr"},
|
|
}
|
|
l, err := zapConfig.Build()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
zl := &ZapLogger{
|
|
unsampled: l.Sugar(),
|
|
//SampleDuration: time.Duration(conf.ItemSampleSeconds) * time.Second,
|
|
//SampleInitial: conf.ItemSampleInitial,
|
|
//SampleInterval: conf.ItemSampleInterval,
|
|
}
|
|
|
|
//if conf.Sample {
|
|
// // use a sampling logger for the main logger
|
|
// samplingConf := &zap.SamplingConfig{
|
|
// Initial: conf.SampleInitial,
|
|
// Thereafter: conf.SampleInterval,
|
|
// }
|
|
// // sane defaults
|
|
// if samplingConf.Initial == 0 {
|
|
// samplingConf.Initial = 20
|
|
// }
|
|
// if samplingConf.Thereafter == 0 {
|
|
// samplingConf.Thereafter = 100
|
|
// }
|
|
// zl.zap = l.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
|
|
// return zapcore.NewSamplerWithOptions(
|
|
// core,
|
|
// time.Second,
|
|
// samplingConf.Initial,
|
|
// samplingConf.Thereafter,
|
|
// )
|
|
// })).Sugar()
|
|
//} else {
|
|
// zl.zap = zl.unsampled
|
|
//}
|
|
return zl, nil
|
|
}
|
|
|
|
func (l *ZapLogger) ToZap() *zap.SugaredLogger {
|
|
return l.zap
|
|
}
|
|
|
|
func (l *ZapLogger) Debug(ctx context.Context, msg string, keysAndValues ...interface{}) {
|
|
keysAndValues = append([]interface{}{constant.OperationID, tracelog.GetOperationID(ctx)}, keysAndValues...)
|
|
l.zap.Debugw(msg, keysAndValues...)
|
|
}
|
|
|
|
func (l *ZapLogger) Info(ctx context.Context, msg string, keysAndValues ...interface{}) {
|
|
keysAndValues = append([]interface{}{constant.OperationID, tracelog.GetOperationID(ctx)}, keysAndValues...)
|
|
l.zap.Infow(msg, keysAndValues...)
|
|
}
|
|
|
|
func (l *ZapLogger) Warn(ctx context.Context, msg string, err error, keysAndValues ...interface{}) {
|
|
if err != nil {
|
|
keysAndValues = append(keysAndValues, "error", err)
|
|
}
|
|
keysAndValues = append([]interface{}{constant.OperationID, tracelog.GetOperationID(ctx)}, keysAndValues...)
|
|
l.zap.Warnw(msg, keysAndValues...)
|
|
}
|
|
|
|
func (l *ZapLogger) Error(ctx context.Context, msg string, err error, keysAndValues ...interface{}) {
|
|
if err != nil {
|
|
keysAndValues = append(keysAndValues, "error", err)
|
|
}
|
|
keysAndValues = append([]interface{}{constant.OperationID, tracelog.GetOperationID(ctx)}, keysAndValues...)
|
|
l.zap.Errorw(msg, keysAndValues...)
|
|
}
|
|
|
|
func (l *ZapLogger) WithValues(keysAndValues ...interface{}) Logger {
|
|
dup := *l
|
|
dup.zap = l.zap.With(keysAndValues...)
|
|
// mirror unsampled logger too
|
|
if l.unsampled == l.zap {
|
|
dup.unsampled = dup.zap
|
|
} else {
|
|
dup.unsampled = l.unsampled.With(keysAndValues...)
|
|
}
|
|
return &dup
|
|
}
|
|
|
|
func (l *ZapLogger) WithName(name string) Logger {
|
|
dup := *l
|
|
dup.zap = l.zap.Named(name)
|
|
if l.unsampled == l.zap {
|
|
dup.unsampled = dup.zap
|
|
} else {
|
|
dup.unsampled = l.unsampled.Named(name)
|
|
}
|
|
return &dup
|
|
}
|
|
|
|
func (l *ZapLogger) WithCallDepth(depth int) Logger {
|
|
dup := *l
|
|
dup.zap = l.zap.WithOptions(zap.AddCallerSkip(depth))
|
|
if l.unsampled == l.zap {
|
|
dup.unsampled = dup.zap
|
|
} else {
|
|
dup.unsampled = l.unsampled.WithOptions(zap.AddCallerSkip(depth))
|
|
}
|
|
return &dup
|
|
}
|
|
|
|
func (l *ZapLogger) WithItemSampler() Logger {
|
|
if l.SampleDuration == 0 {
|
|
return l
|
|
}
|
|
dup := *l
|
|
dup.zap = l.unsampled.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
|
|
return zapcore.NewSamplerWithOptions(
|
|
core,
|
|
l.SampleDuration,
|
|
l.SampleInitial,
|
|
l.SampleInterval,
|
|
)
|
|
}))
|
|
return &dup
|
|
}
|
|
|
|
func (l *ZapLogger) WithoutSampler() Logger {
|
|
if l.SampleDuration == 0 {
|
|
return l
|
|
}
|
|
dup := *l
|
|
dup.zap = l.unsampled
|
|
return &dup
|
|
}
|
|
|
|
type LogRLogger logr.Logger
|
|
|
|
func (l LogRLogger) toLogr() logr.Logger {
|
|
if logr.Logger(l).GetSink() == nil {
|
|
return discardLogger
|
|
}
|
|
return logr.Logger(l)
|
|
}
|
|
|
|
func (l LogRLogger) Debug(ctx context.Context, msg string, keysAndValues ...interface{}) {
|
|
keysAndValues = append([]interface{}{constant.OperationID, tracelog.GetOperationID(ctx)}, keysAndValues...)
|
|
l.toLogr().V(1).Info(msg, keysAndValues...)
|
|
}
|
|
|
|
func (l LogRLogger) Info(ctx context.Context, msg string, keysAndValues ...interface{}) {
|
|
keysAndValues = append([]interface{}{constant.OperationID, tracelog.GetOperationID(ctx)}, keysAndValues...)
|
|
l.toLogr().Info(msg, keysAndValues...)
|
|
}
|
|
|
|
func (l LogRLogger) Warn(ctx context.Context, msg string, err error, keysAndValues ...interface{}) {
|
|
if err != nil {
|
|
keysAndValues = append(keysAndValues, "error", err)
|
|
}
|
|
keysAndValues = append([]interface{}{constant.OperationID, tracelog.GetOperationID(ctx)}, keysAndValues...)
|
|
l.toLogr().Info(msg, keysAndValues...)
|
|
}
|
|
|
|
func (l LogRLogger) Error(ctx context.Context, msg string, err error, keysAndValues ...interface{}) {
|
|
keysAndValues = append([]interface{}{constant.OperationID, tracelog.GetOperationID(ctx)}, keysAndValues...)
|
|
l.toLogr().Error(err, msg, keysAndValues...)
|
|
}
|
|
|
|
func (l LogRLogger) WithValues(keysAndValues ...interface{}) Logger {
|
|
return LogRLogger(l.toLogr().WithValues(keysAndValues...))
|
|
}
|
|
|
|
func (l LogRLogger) WithName(name string) Logger {
|
|
return LogRLogger(l.toLogr().WithName(name))
|
|
}
|
|
|
|
func (l LogRLogger) WithCallDepth(depth int) Logger {
|
|
return LogRLogger(l.toLogr().WithCallDepth(depth))
|
|
}
|
|
|
|
func (l LogRLogger) WithItemSampler() Logger {
|
|
return l
|
|
}
|
|
|
|
func (l LogRLogger) WithoutSampler() Logger {
|
|
return l
|
|
}
|