From 0a7e165794b2d07bec9589f6f053f44e432e5f56 Mon Sep 17 00:00:00 2001 From: thinkgos Date: Wed, 8 May 2024 14:22:06 +0800 Subject: [PATCH] fix: fix --- caller.go | 141 +++++++++++++++++++++++++++++++++++++++++++++++ logger.go | 8 +-- pool.go | 51 ++++++++++------- valuer_preset.go | 48 +--------------- wrapper.go | 24 ++++---- zap.go | 24 ++++++++ 6 files changed, 215 insertions(+), 81 deletions(-) create mode 100644 caller.go diff --git a/caller.go b/caller.go new file mode 100644 index 0000000..9c7ee04 --- /dev/null +++ b/caller.go @@ -0,0 +1,141 @@ +package log + +import ( + "context" + "runtime" + "strconv" + "strings" + + "go.uber.org/zap" +) + +const loggerPackage = "mod.miligc.com/edge-common/logger" + +type CallerCore struct { + level AtomicLevel + Skip int + SkipPackages []string + Caller func(depth int, skipPackages ...string) Field +} + +func NewCallerCore() *CallerCore { + return &CallerCore{ + level: NewAtomicLevelAt(ErrorLevel), + Skip: 0, + SkipPackages: nil, + Caller: DefaultCallerFile, + } +} + +// AddSkip add the number of callers skipped by caller annotation. +func (c *CallerCore) AddSkip(callerSkip int) *CallerCore { + c.Skip += callerSkip + return c +} + +// AddSkipPackage add the caller skip package. +func (c *CallerCore) AddSkipPackage(vs ...string) *CallerCore { + c.SkipPackages = append(c.SkipPackages, vs...) + return c +} + +// SetSkip set the number of callers skipped by caller annotation. +// +// Deprecated: Use AddSkip instead. +func (c *CallerCore) SetSkip(callerSkip int) *CallerCore { + return c.AddSkip(callerSkip) +} + +// SetSkipPackage set the caller skip package. +// +// Deprecated: Use AddSkipPackage instead. +func (c *CallerCore) SetSkipPackage(vs ...string) *CallerCore { + return c.AddSkipPackage(vs...) +} + +// SetLevel set the caller level. +func (c *CallerCore) SetLevel(lv Level) *CallerCore { + c.level.SetLevel(lv) + return c +} + +// Level returns the minimum enabled log level. +func (c *CallerCore) Level() Level { + return c.level.Level() +} + +// Enabled returns true if the given level is at or above this level. +func (c *CallerCore) Enabled(lvl Level) bool { + return c.level.Enabled(lvl) +} + +// UseExternalLevel use external level, which controller by user. +func (c *CallerCore) UseExternalLevel(l AtomicLevel) *CallerCore { + c.level = l + return c +} + +// UnderlyingLevel get underlying level. +func (c *CallerCore) UnderlyingLevel() AtomicLevel { + return c.level +} + +// DefaultCallerFile caller file. +func DefaultCallerFile(depth int, skipPackages ...string) Field { + var file string + var line int + var ok bool + + for i := depth; i < depth+10; i++ { + _, file, line, ok = runtime.Caller(i) + if ok && !skipPackage(file, skipPackages...) { + break + } + } + return zap.String("file", file+":"+strconv.Itoa(line)) +} + +// DefaultCaller caller. +func DefaultCaller(depth int, skipPackages ...string) Field { + var file string + var line int + var ok bool + + for i := depth; i < depth+10; i++ { + _, file, line, ok = runtime.Caller(i) + if ok && !skipPackage(file, skipPackages...) { + break + } + } + idx := strings.LastIndexByte(file, '/') + return zap.String("caller", file[idx+1:]+":"+strconv.Itoa(line)) +} + +// File returns a Valuer that returns a pkg/file:line description of the caller. +func File(depth int, skipPackages ...string) Valuer { + return func(context.Context) Field { + return DefaultCallerFile(depth, skipPackages...) + } +} + +// Caller returns a Valuer that returns a pkg/file:line description of the caller. +func Caller(depth int, skipPackages ...string) Valuer { + return func(context.Context) Field { + return DefaultCaller(depth, skipPackages...) + } +} + +func skipPackage(file string, skipPackages ...string) bool { + if strings.HasSuffix(file, "_test.go") { + return false + } + if strings.Contains(file, loggerPackage) { + return true + } + for _, p := range skipPackages { + if strings.Contains(file, p) { + return true + } + } + return false +} diff --git a/logger.go b/logger.go index 96470a6..4cff2cf 100644 --- a/logger.go +++ b/logger.go @@ -156,8 +156,8 @@ func (l *Log) Logw(ctx context.Context, level Level, msg string, keysAndValues . if !l.level.Enabled(level) { return } - fc := defaultFieldPool.Get() - defer defaultFieldPool.Put(fc) + fc := poolGet() + defer poolPut(fc) for _, f := range l.fn { fc.Fields = append(fc.Fields, f(ctx)) } @@ -172,8 +172,8 @@ func (l *Log) Logx(ctx context.Context, level Level, msg string, fields ...Field if len(l.fn) == 0 { l.log.Log(level, msg, fields...) } else { - fc := defaultFieldPool.Get() - defer defaultFieldPool.Put(fc) + fc := poolGet() + defer poolPut(fc) for _, f := range l.fn { fc.Fields = append(fc.Fields, f(ctx)) } diff --git a/pool.go b/pool.go index 025c56a..47d2d6c 100644 --- a/pool.go +++ b/pool.go @@ -6,7 +6,13 @@ import ( "go.uber.org/zap" ) -var defaultFieldPool = newFieldPool() +var fieldPool = &sync.Pool{ + New: func() any { + return &fieldContainer{ + make([]zap.Field, 0, 32), + } + }, +} type fieldContainer struct { Fields []Field @@ -17,25 +23,32 @@ func (c *fieldContainer) reset() *fieldContainer { return c } -type fieldPool struct { - pool sync.Pool -} - -func newFieldPool() *fieldPool { - return &fieldPool{ - pool: sync.Pool{ - New: func() any { - return &fieldContainer{make([]zap.Field, 0, 32)} - }, - }, - } -} - -func (p *fieldPool) Get() *fieldContainer { - c := p.pool.Get().(*fieldContainer) +// poolGet selects an arbitrary item from the field Pool, removes it from the +// field Pool, and returns it to the caller. +// poolGet may choose to ignore the field pool and treat it as empty. +// Callers should not assume any relation between values passed to PoolPut and +// the values returned by poolGet. +// +// NOTE: This function should be call PoolPut to give back. +// NOTE: You should know `sync.Pool` work principle +// ```go +// +// fc := logger.poolGet() +// defer logger.PoolPut(fc) +// fc.Fields = append(fc.Fields, logger.String("k1", "v1")) +// ... use fc.Fields +// +// ``` +func poolGet() *fieldContainer { + c := fieldPool.Get().(*fieldContainer) return c.reset() } -func (p *fieldPool) Put(c *fieldContainer) { - p.pool.Put(c.reset()) +// poolPut adds x to the pool. +// NOTE: See PoolGet. +func poolPut(c *fieldContainer) { + if c == nil { + return + } + fieldPool.Put(c.reset()) } diff --git a/valuer_preset.go b/valuer_preset.go index e5e5574..48710f3 100644 --- a/valuer_preset.go +++ b/valuer_preset.go @@ -2,53 +2,8 @@ package log import ( "context" - "runtime" - "strconv" - "strings" - - "go.uber.org/zap" ) -func caller(depth int) (file string, line int) { - ok := false - for i := depth; i < depth+10; i++ { - _, file, line, ok = runtime.Caller(i) - if ok && !skipPackage(file, "github.com/things-go/log") { - return file, line - } - } - return file, line -} - -func skipPackage(file string, skipPackages ...string) bool { - if strings.HasSuffix(file, "_test.go") { - return false - } - for _, p := range skipPackages { - if strings.Contains(file, p) { - return true - } - } - return false -} - -// Caller returns a Valuer that returns a pkg/file:line description of the caller. -func Caller(depth int) Valuer { - return func(context.Context) Field { - file, line := caller(depth) - idx := strings.LastIndexByte(file, '/') - return zap.String("caller", file[idx+1:]+":"+strconv.Itoa(line)) - } -} - -// File returns a Valuer that returns a pkg/file:line description of the caller. -func File(depth int) Valuer { - return func(context.Context) Field { - file, line := caller(depth) - return zap.String("file", file+":"+strconv.Itoa(line)) - } -} - // Package returns a Valuer that returns an immutable Valuer which key is pkg func Package(v string) Valuer { return ImmutString("pkg", v) @@ -78,3 +33,6 @@ func TraceId(f func(c context.Context) string) Valuer { func RequestId(f func(c context.Context) string) Valuer { return FromString("requestId", f) } +func Source(f func(c context.Context) string) Valuer { + return FromString("source", f) +} diff --git a/wrapper.go b/wrapper.go index 24f735c..a5813e0 100644 --- a/wrapper.go +++ b/wrapper.go @@ -5,22 +5,20 @@ import ( "time" "go.uber.org/zap" - "go.uber.org/zap/zapcore" ) -type Field = zap.Field -type Level = zapcore.Level -type ObjectMarshaler = zapcore.ObjectMarshaler +// NewAtomicLevel creates an AtomicLevel with InfoLevel and above logging +// enabled. +func NewAtomicLevel() AtomicLevel { return zap.NewAtomicLevel() } -const ( - DebugLevel = zap.DebugLevel - InfoLevel = zap.InfoLevel - WarnLevel = zap.WarnLevel - ErrorLevel = zap.ErrorLevel - DPanicLevel = zap.DPanicLevel - PanicLevel = zap.PanicLevel - FatalLevel = zap.FatalLevel -) +// NewAtomicLevelAt is a convenience function that creates an AtomicLevel +// and then calls SetLevel with the given level. +func NewAtomicLevelAt(l Level) AtomicLevel { return zap.NewAtomicLevelAt(l) } + +// ParseAtomicLevel parses an AtomicLevel based on a lowercase or all-caps ASCII +// representation of the log level. If the provided ASCII representation is +// invalid an error is returned. +func ParseAtomicLevel(text string) (AtomicLevel, error) { return zap.ParseAtomicLevel(text) } func Err(val error) Field { return zap.Error(val) } func Errors(key string, val []error) Field { return zap.Errors(key, val) } diff --git a/zap.go b/zap.go index 33018ff..1916803 100644 --- a/zap.go +++ b/zap.go @@ -10,6 +10,22 @@ import ( "go.uber.org/zap/zapcore" ) +type AtomicLevel = zap.AtomicLevel +type Field = zap.Field +type Level = zapcore.Level +type ObjectMarshaler = zapcore.ObjectMarshaler + +// log level defined +const ( + DebugLevel = zap.DebugLevel + InfoLevel = zap.InfoLevel + WarnLevel = zap.WarnLevel + ErrorLevel = zap.ErrorLevel + DPanicLevel = zap.DPanicLevel + PanicLevel = zap.PanicLevel + FatalLevel = zap.FatalLevel +) + // adapter defined const ( AdapterConsole = "console" // console @@ -27,6 +43,14 @@ const ( FormatConsole = "console" ) +// encode level defined +const ( + EncodeLevelLowercase = "LowercaseLevelEncoder" // 小写编码器 + EncodeLevelLowercaseColor = "LowercaseColorLevelEncoder" // 小写编码器带颜色 + EncodeLevelCapital = "CapitalLevelEncoder" // 大写编码器 + EncodeLevelCapitalColor = "CapitalColorLevelEncoder" // 大写编码器带颜色 +) + // New constructs a new Log func New(opts ...Option) (*zap.Logger, zap.AtomicLevel) { c := &Config{}