diff --git a/log/.golangci.yaml b/log/.golangci.yaml new file mode 100644 index 0000000..d884b2f --- /dev/null +++ b/log/.golangci.yaml @@ -0,0 +1,141 @@ +## 基于 golangci-lint@v1.52.2 +run: + timeout: 1m + build-tags: [ ] + skip-dirs: [ ] + skip-files: [ ] +linters: + disable-all: true + enable: + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - typecheck + - unused + - asasalint + - asciicheck + - bidichk + - bodyclose + - containedctx + - cyclop + - dupl + - durationcheck + - errname + - errorlint + - exhaustive + - exportloopref + - funlen + - gocheckcompilerdirectives + - gochecknoinits + - goconst + - gocritic + - gocyclo + - goimports + - gomnd + - goprintffuncname + - gosec + - lll + - loggercheck + - makezero + - nakedret + - nestif + - nilnil + - noctx + - nolintlint + - prealloc + - predeclared + - promlinter + - reassign + - revive + - rowserrcheck + - stylecheck + - tenv + - testableexamples + - testpackage + - tparallel + - unconvert + - unparam + - usestdlibvars + - wastedassign + - whitespace +linters-settings: + errcheck: + check-type-assertions: true + exclude-functions: [ ] + govet: + enable-all: true + disable: [ ] + cyclop: + max-complexity: 10 + package-average: 0.0 + dupl: + threshold: 150 + exhaustive: + check: + - switch + - map + funlen: + lines: 100 + statements: 60 + gocritic: + disabled-checks: + - commentFormatting + settings: + captLocal: + paramsOnly: false + underef: + skipRecvDeref: false + gocyclo: + min-complexity: 20 + gomnd: + ignored-functions: + - os.Chmod + - os.Mkdir + - os.MkdirAll + - os.OpenFile + - os.WriteFile + - prometheus.ExponentialBuckets + - prometheus.ExponentialBucketsRange + - prometheus.LinearBuckets + lll: + line-length: 240 + nakedret: + max-func-lines: 10 + nestif: + min-complexity: 5 + predeclared: + ignore: "" + q: false + reassign: + patterns: + - ".*" + rowserrcheck: + packages: + - github.com/jmoiron/sqlx + tenv: + all: true + usestdlibvars: + time-month: true + time-layout: true + crypto-hash: true + default-rpc-path: true + os-dev-null: true + sql-isolation-level: true + tls-signature-scheme: true + constant-kind: true + syslog-priority: true +issues: + max-same-issues: 10 + exclude-rules: + - source: "//noinspection" + linters: [ gocritic ] + - path: "_test\\.go" + linters: + - bodyclose + - dupl + - funlen + - goconst + - gosec + - noctx diff --git a/log/logsdk/entry.go b/log/logsdk/entry.go index 11e72bc..29a280e 100644 --- a/log/logsdk/entry.go +++ b/log/logsdk/entry.go @@ -37,7 +37,7 @@ func (entry Entry) AddCallerSkip(n int) Entry { // WithField 增加1组键值对 func (entry Entry) WithField(key string, value any) Entry { - return entry.WithFields(KV{Key: key, Value: value}) + return entry.WithFields(Field(key, value)) } // WithFields 增加键值对 @@ -198,7 +198,7 @@ func (entry Entry) log(ctx context.Context, level Level, message string) { readonlyEntry.Caller = getCaller(newEntry.callerSkip) } if newEntry.GetReportStack() || level <= newEntry.logger.GetReportStackLevel() { - readonlyEntry.Stack = getStack(newEntry.callerSkip, 32) + readonlyEntry.Stack = getStack(newEntry.callerSkip, maximumFrames) } for _, processor := range newEntry.logger.getLevelProcessors(level) { processor.Process(ctx, readonlyEntry) diff --git a/log/logsdk/field.go b/log/logsdk/field.go index 6aba454..91c3ce3 100644 --- a/log/logsdk/field.go +++ b/log/logsdk/field.go @@ -3,13 +3,15 @@ package logsdk // Field 返回键值对 func Field(key string, value any) KV { return KV{ - Value: value, Key: key, + Value: value, } } // KV 是日志记录中的键值对 +// +//nolint:govet type KV struct { - Value any `json:"v"` Key string `json:"k"` + Value any `json:"v"` } diff --git a/log/logsdk/level.go b/log/logsdk/level.go index 514fb67..774948b 100644 --- a/log/logsdk/level.go +++ b/log/logsdk/level.go @@ -28,6 +28,8 @@ func (level Level) MarshalText() ([]byte, error) { return []byte(LevelDebugValue), nil case LevelTrace: return []byte(LevelTraceValue), nil + case LevelDisabled: + return []byte(levelDisabledValue), nil } return nil, fmt.Errorf("not a valid log level %d", level) } @@ -61,6 +63,8 @@ const ( LevelInfoValue = "info" LevelDebugValue = "debug" LevelTraceValue = "trace" + + levelDisabledValue = "disabled" ) var AllLevels = []Level{ diff --git a/log/logsdk/logger.go b/log/logsdk/logger.go index 5889efb..ab612bb 100644 --- a/log/logsdk/logger.go +++ b/log/logsdk/logger.go @@ -111,11 +111,12 @@ func (logger *Logger) Reset() { // Exit 退出程序, 执行的具体过程可以通过 SetExit 指定 func (logger *Logger) Exit(code int) { logger.lock.RLock() - defer logger.lock.RUnlock() - if logger.exit == nil { + exit := logger.exit + logger.lock.RUnlock() + if exit == nil { os.Exit(code) } - logger.exit(code) + exit(code) } // SetExit 指定退出程序时执行的函数 @@ -134,7 +135,7 @@ func (logger *Logger) getLevelProcessors(level Level) []EntryProcessor { func (logger *Logger) newEntry() Entry { return Entry{ logger: logger, - callerSkip: logger.GetCallerSkip() + 2, + callerSkip: logger.GetCallerSkip() + entrySkipOffset, reportCaller: logger.GetReportCaller(), reportStack: logger.GetReportStack(), initialized: true, diff --git a/log/logsdk/logjson/option.go b/log/logsdk/logjson/option.go index 2929c8d..7869ac8 100644 --- a/log/logsdk/logjson/option.go +++ b/log/logsdk/logjson/option.go @@ -60,7 +60,7 @@ func newConfig(opts ...Option) *config { opt.apply(cfg) } if !cfg.hasPool { - cfg.bytesBufferPool = NewBytesBufferPool(512, 4096) + cfg.bytesBufferPool = NewBytesBufferPool(bytesBufferInitialSize, bytesBufferMaximumSize) } if cfg.output == nil { cfg.output = NewSyncWriter(os.Stderr) diff --git a/log/logsdk/logjson/pool.go b/log/logsdk/logjson/pool.go index 7b3bc5b..cd8ba3f 100644 --- a/log/logsdk/logjson/pool.go +++ b/log/logsdk/logjson/pool.go @@ -5,6 +5,11 @@ import ( "sync" ) +const ( + bytesBufferInitialSize = 512 + bytesBufferMaximumSize = 4096 +) + type BytesBufferPool interface { Get() *bytes.Buffer Put(buffer *bytes.Buffer) diff --git a/log/logsdk/logjson/writer.go b/log/logsdk/logjson/writer.go index bda4a62..d5bed83 100644 --- a/log/logsdk/logjson/writer.go +++ b/log/logsdk/logjson/writer.go @@ -18,7 +18,7 @@ type syncWriter struct { lock sync.Mutex } -func (w *syncWriter) Write(p []byte) (n int, err error) { +func (w *syncWriter) Write(p []byte) (int, error) { w.lock.Lock() defer w.lock.Unlock() return w.writer.Write(p) diff --git a/log/logsdk/runtime.go b/log/logsdk/runtime.go index b7f537e..ab92a1c 100644 --- a/log/logsdk/runtime.go +++ b/log/logsdk/runtime.go @@ -4,6 +4,12 @@ import ( "runtime" ) +const ( + maximumFrames = 32 + getCallerSkipOffset = 2 + entrySkipOffset = 2 +) + // Frame 调用相关信息 type Frame struct { Function string `json:"func"` @@ -18,7 +24,7 @@ func (frame Frame) IsValid() bool { func getCaller(skip int) Frame { pc := make([]uintptr, 1) - n := runtime.Callers(skip+2, pc) + n := runtime.Callers(skip+getCallerSkipOffset, pc) frame, _ := runtime.CallersFrames(pc[:n]).Next() if frame.PC == 0 { return Frame{} @@ -32,7 +38,7 @@ func getCaller(skip int) Frame { func getStack(skip, maximumFrames int) []Frame { pc := make([]uintptr, maximumFrames) - n := runtime.Callers(skip+2, pc) + n := runtime.Callers(skip+getCallerSkipOffset, pc) stack := make([]Frame, 0, n) frames := runtime.CallersFrames(pc[:n]) for {