mirror of
https://github.com/duanhf2012/origin.git
synced 2026-04-10 01:37:29 +08:00
替换slog日志为zap
This commit is contained in:
@@ -1,93 +0,0 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const _size = 9216
|
||||
|
||||
type Buffer struct {
|
||||
bs []byte
|
||||
//mu sync.Mutex // ensures atomic writes; protects the following fields
|
||||
}
|
||||
|
||||
func (buff *Buffer) Init() {
|
||||
buff.bs = make([]byte, _size)
|
||||
}
|
||||
|
||||
// AppendByte writes a single byte to the Buffer.
|
||||
func (buff *Buffer) AppendByte(v byte) {
|
||||
buff.bs = append(buff.bs, v)
|
||||
}
|
||||
|
||||
func (buff *Buffer) AppendBytes(v []byte) {
|
||||
buff.bs = append(buff.bs, v...)
|
||||
}
|
||||
|
||||
// AppendString writes a string to the Buffer.
|
||||
func (buff *Buffer) AppendString(s string) {
|
||||
buff.bs = append(buff.bs, s...)
|
||||
}
|
||||
|
||||
// AppendInt appends an integer to the underlying buffer (assuming base 10).
|
||||
func (buff *Buffer) AppendInt(i int64) {
|
||||
buff.bs = strconv.AppendInt(buff.bs, i, 10)
|
||||
}
|
||||
|
||||
// AppendUint appends an unsigned integer to the underlying buffer (assuming
|
||||
// base 10).
|
||||
func (buff *Buffer) AppendUint(i uint64) {
|
||||
buff.bs = strconv.AppendUint(buff.bs, i, 10)
|
||||
}
|
||||
|
||||
// AppendBool appends a bool to the underlying buffer.
|
||||
func (buff *Buffer) AppendBool(v bool) {
|
||||
buff.bs = strconv.AppendBool(buff.bs, v)
|
||||
}
|
||||
|
||||
// AppendFloat appends a float to the underlying buffer. It doesn't quote NaN
|
||||
// or +/- Inf.
|
||||
func (buff *Buffer) AppendFloat(f float64, bitSize int) {
|
||||
buff.bs = strconv.AppendFloat(buff.bs, f, 'f', -1, bitSize)
|
||||
}
|
||||
|
||||
// Len returns the length of the underlying byte slice.
|
||||
func (buff *Buffer) Len() int {
|
||||
return len(buff.bs)
|
||||
}
|
||||
|
||||
// Cap returns the capacity of the underlying byte slice.
|
||||
func (buff *Buffer) Cap() int {
|
||||
return cap(buff.bs)
|
||||
}
|
||||
|
||||
// Bytes returns a mutable reference to the underlying byte slice.
|
||||
func (buff *Buffer) Bytes() []byte {
|
||||
return buff.bs
|
||||
}
|
||||
|
||||
// String returns a string copy of the underlying byte slice.
|
||||
func (buff *Buffer) String() string {
|
||||
return string(buff.bs)
|
||||
}
|
||||
|
||||
// Reset resets the underlying byte slice. Subsequent writes re-use the slice's
|
||||
// backing array.
|
||||
func (buff *Buffer) Reset() {
|
||||
buff.bs = buff.bs[:0]
|
||||
}
|
||||
|
||||
// Write implements io.Writer.
|
||||
func (buff *Buffer) Write(bs []byte) (int, error) {
|
||||
buff.bs = append(buff.bs, bs...)
|
||||
return len(bs), nil
|
||||
}
|
||||
|
||||
// TrimNewline trims any final "\n" byte from the end of the buffer.
|
||||
func (buff *Buffer) TrimNewline() {
|
||||
if i := len(buff.bs) - 1; i >= 0 {
|
||||
if buff.bs[i] == '\n' {
|
||||
buff.bs = buff.bs[:i]
|
||||
}
|
||||
}
|
||||
}
|
||||
161
log/handler.go
161
log/handler.go
@@ -1,161 +0,0 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"log/slog"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const defaultSkip = 7
|
||||
|
||||
type IOriginHandler interface {
|
||||
slog.Handler
|
||||
Lock()
|
||||
UnLock()
|
||||
SetSkip(skip int)
|
||||
GetSkip() int
|
||||
}
|
||||
|
||||
type BaseHandler struct {
|
||||
addSource bool
|
||||
w io.Writer
|
||||
locker sync.Mutex
|
||||
skip int
|
||||
}
|
||||
|
||||
type OriginTextHandler struct {
|
||||
BaseHandler
|
||||
*slog.TextHandler
|
||||
}
|
||||
|
||||
type OriginJsonHandler struct {
|
||||
BaseHandler
|
||||
*slog.JSONHandler
|
||||
}
|
||||
|
||||
func (bh *BaseHandler) SetSkip(skip int) {
|
||||
bh.skip = skip
|
||||
}
|
||||
|
||||
func (bh *BaseHandler) GetSkip() int {
|
||||
return bh.skip
|
||||
}
|
||||
|
||||
func getStrLevel(level slog.Level) string {
|
||||
switch level {
|
||||
case LevelTrace:
|
||||
return "Trace"
|
||||
case LevelDebug:
|
||||
return "Debug"
|
||||
case LevelInfo:
|
||||
return "Info"
|
||||
case LevelWarning:
|
||||
return "Warning"
|
||||
case LevelError:
|
||||
return "Error"
|
||||
case LevelStack:
|
||||
return "Stack"
|
||||
case LevelDump:
|
||||
return "Dump"
|
||||
case LevelFatal:
|
||||
return "Fatal"
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func defaultReplaceAttr(groups []string, a slog.Attr) slog.Attr {
|
||||
if a.Key == slog.LevelKey {
|
||||
level := a.Value.Any().(slog.Level)
|
||||
a.Value = slog.StringValue(getStrLevel(level))
|
||||
} else if a.Key == slog.TimeKey && len(groups) == 0 {
|
||||
a.Value = slog.StringValue(a.Value.Time().Format("2006/01/02 15:04:05"))
|
||||
} else if a.Key == slog.SourceKey {
|
||||
source := a.Value.Any().(*slog.Source)
|
||||
source.File = filepath.Base(source.File)
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func NewOriginTextHandler(level slog.Level, w io.Writer, addSource bool, replaceAttr func([]string, slog.Attr) slog.Attr) slog.Handler {
|
||||
var textHandler OriginTextHandler
|
||||
textHandler.addSource = addSource
|
||||
textHandler.w = w
|
||||
textHandler.TextHandler = slog.NewTextHandler(w, &slog.HandlerOptions{
|
||||
AddSource: addSource,
|
||||
Level: level,
|
||||
ReplaceAttr: replaceAttr,
|
||||
})
|
||||
|
||||
textHandler.skip = defaultSkip
|
||||
return &textHandler
|
||||
}
|
||||
|
||||
func (oh *OriginTextHandler) Handle(context context.Context, record slog.Record) error {
|
||||
oh.Fill(context, &record)
|
||||
oh.locker.Lock()
|
||||
defer oh.locker.Unlock()
|
||||
|
||||
if record.Level == LevelStack || record.Level == LevelFatal {
|
||||
err := oh.TextHandler.Handle(context, record)
|
||||
oh.logStack(&record)
|
||||
return err
|
||||
} else if record.Level == LevelDump {
|
||||
strDump := record.Message
|
||||
record.Message = "dump info"
|
||||
err := oh.TextHandler.Handle(context, record)
|
||||
oh.w.Write([]byte(strDump))
|
||||
return err
|
||||
}
|
||||
|
||||
return oh.TextHandler.Handle(context, record)
|
||||
}
|
||||
|
||||
func (bh *BaseHandler) logStack(record *slog.Record) {
|
||||
bh.w.Write(debug.Stack())
|
||||
}
|
||||
|
||||
func (bh *BaseHandler) Lock() {
|
||||
bh.locker.Lock()
|
||||
}
|
||||
|
||||
func (bh *BaseHandler) UnLock() {
|
||||
bh.locker.Unlock()
|
||||
}
|
||||
|
||||
func NewOriginJsonHandler(level slog.Level, w io.Writer, addSource bool, replaceAttr func([]string, slog.Attr) slog.Attr) slog.Handler {
|
||||
var jsonHandler OriginJsonHandler
|
||||
jsonHandler.addSource = addSource
|
||||
jsonHandler.w = w
|
||||
jsonHandler.JSONHandler = slog.NewJSONHandler(w, &slog.HandlerOptions{
|
||||
AddSource: addSource,
|
||||
Level: level,
|
||||
ReplaceAttr: replaceAttr,
|
||||
})
|
||||
|
||||
jsonHandler.skip = defaultSkip
|
||||
return &jsonHandler
|
||||
}
|
||||
|
||||
func (oh *OriginJsonHandler) Handle(context context.Context, record slog.Record) error {
|
||||
oh.Fill(context, &record)
|
||||
if record.Level == LevelStack || record.Level == LevelFatal || record.Level == LevelDump {
|
||||
record.Add("stack", debug.Stack())
|
||||
}
|
||||
|
||||
oh.locker.Lock()
|
||||
defer oh.locker.Unlock()
|
||||
return oh.JSONHandler.Handle(context, record)
|
||||
}
|
||||
|
||||
func (bh *BaseHandler) Fill(_ context.Context, record *slog.Record) {
|
||||
if bh.addSource {
|
||||
var pcs [1]uintptr
|
||||
runtime.Callers(bh.skip, pcs[:])
|
||||
record.PC = pcs[0]
|
||||
}
|
||||
}
|
||||
688
log/log.go
688
log/log.go
@@ -1,520 +1,326 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/duanhf2012/origin/v2/util/bytespool"
|
||||
"io"
|
||||
"log/slog"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
var OpenConsole bool
|
||||
var LogSize int64
|
||||
var LogChannelCap int
|
||||
var LogPath string
|
||||
var LogLevel = LevelTrace
|
||||
|
||||
var gLogger, _ = NewTextLogger(LevelDebug, "", "", true, LogChannelCap)
|
||||
var isSetLogger bool
|
||||
var memPool = bytespool.NewMemAreaPool()
|
||||
|
||||
// levels
|
||||
const (
|
||||
LevelTrace = slog.Level(-8)
|
||||
LevelDebug = slog.LevelDebug
|
||||
LevelInfo = slog.LevelInfo
|
||||
LevelWarning = slog.LevelWarn
|
||||
LevelError = slog.LevelError
|
||||
LevelStack = slog.Level(12)
|
||||
LevelDump = slog.Level(16)
|
||||
LevelFatal = slog.Level(20)
|
||||
)
|
||||
|
||||
type ILogger interface {
|
||||
Trace(msg string, args ...any)
|
||||
Debug(msg string, args ...any)
|
||||
Info(msg string, args ...any)
|
||||
Warning(msg string, args ...any)
|
||||
Error(msg string, args ...any)
|
||||
Stack(msg string, args ...any)
|
||||
Dump(msg string, args ...any)
|
||||
Fatal(msg string, args ...any)
|
||||
|
||||
DoSPrintf(level slog.Level, a []interface{})
|
||||
FormatHeader(buf *Buffer, level slog.Level, callDepth int)
|
||||
Close()
|
||||
}
|
||||
var gLogger = NewDefaultLogger()
|
||||
|
||||
type Logger struct {
|
||||
SLogger *slog.Logger
|
||||
*zap.Logger
|
||||
stack bool
|
||||
|
||||
ioWriter IoWriter
|
||||
|
||||
sBuff Buffer
|
||||
OpenConsole *bool
|
||||
LogPath string
|
||||
FileName string
|
||||
LogLevel zapcore.Level
|
||||
Encoder zapcore.Encoder
|
||||
LogConfig *lumberjack.Logger
|
||||
sugaredLogger *zap.SugaredLogger
|
||||
}
|
||||
|
||||
type IoWriter struct {
|
||||
outFile io.Writer // destination for output
|
||||
writeBytes int64
|
||||
logChannel chan []byte
|
||||
wg sync.WaitGroup
|
||||
closeSig chan struct{}
|
||||
|
||||
lockWrite sync.Mutex
|
||||
|
||||
filePath string
|
||||
filePrefix string
|
||||
fileDay int
|
||||
fileCreateTime int64 //second
|
||||
}
|
||||
|
||||
func (iw *IoWriter) Close() error {
|
||||
iw.lockWrite.Lock()
|
||||
defer iw.lockWrite.Unlock()
|
||||
|
||||
iw.close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iw *IoWriter) close() error {
|
||||
if iw.closeSig != nil {
|
||||
close(iw.closeSig)
|
||||
iw.closeSig = nil
|
||||
}
|
||||
iw.wg.Wait()
|
||||
|
||||
if iw.outFile != nil {
|
||||
err := iw.outFile.(io.Closer).Close()
|
||||
iw.outFile = nil
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iw *IoWriter) writeFile(p []byte) (n int, err error) {
|
||||
//switch log file
|
||||
iw.switchFile()
|
||||
|
||||
if iw.outFile != nil {
|
||||
n, err = iw.outFile.Write(p)
|
||||
if n > 0 {
|
||||
atomic.AddInt64(&iw.writeBytes, int64(n))
|
||||
}
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (iw *IoWriter) Write(p []byte) (n int, err error) {
|
||||
iw.lockWrite.Lock()
|
||||
defer iw.lockWrite.Unlock()
|
||||
|
||||
if iw.logChannel == nil {
|
||||
return iw.writeIo(p)
|
||||
}
|
||||
|
||||
copyBuff := memPool.MakeBytes(len(p))
|
||||
if copyBuff == nil {
|
||||
return 0, fmt.Errorf("MakeByteSlice failed")
|
||||
}
|
||||
copy(copyBuff, p)
|
||||
|
||||
iw.logChannel <- copyBuff
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (iw *IoWriter) writeIo(p []byte) (n int, err error) {
|
||||
n, err = iw.writeFile(p)
|
||||
|
||||
if OpenConsole {
|
||||
n, err = os.Stdout.Write(p)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (iw *IoWriter) setLogChannel(logChannelNum int) (err error) {
|
||||
iw.lockWrite.Lock()
|
||||
defer iw.lockWrite.Unlock()
|
||||
iw.close()
|
||||
|
||||
if logChannelNum == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
//copy iw.logChannel
|
||||
var logInfo []byte
|
||||
logChannel := make(chan []byte, logChannelNum)
|
||||
for i := 0; i < logChannelNum && i < len(iw.logChannel); i++ {
|
||||
logInfo = <-iw.logChannel
|
||||
logChannel <- logInfo
|
||||
}
|
||||
iw.logChannel = logChannel
|
||||
|
||||
iw.closeSig = make(chan struct{})
|
||||
iw.wg.Add(1)
|
||||
go iw.run()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iw *IoWriter) run() {
|
||||
defer iw.wg.Done()
|
||||
|
||||
Loop:
|
||||
for {
|
||||
select {
|
||||
case <-iw.closeSig:
|
||||
break Loop
|
||||
case logs := <-iw.logChannel:
|
||||
iw.writeIo(logs)
|
||||
memPool.ReleaseBytes(logs)
|
||||
}
|
||||
}
|
||||
|
||||
for len(iw.logChannel) > 0 {
|
||||
logs := <-iw.logChannel
|
||||
iw.writeIo(logs)
|
||||
memPool.ReleaseBytes(logs)
|
||||
}
|
||||
}
|
||||
|
||||
func (iw *IoWriter) isFull() bool {
|
||||
if LogSize == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return atomic.LoadInt64(&iw.writeBytes) >= LogSize
|
||||
}
|
||||
|
||||
func (logger *Logger) setLogChannel(logChannel int) (err error) {
|
||||
return logger.ioWriter.setLogChannel(logChannel)
|
||||
}
|
||||
|
||||
func (iw *IoWriter) switchFile() error {
|
||||
now := time.Now()
|
||||
if iw.fileCreateTime == now.Unix() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if iw.fileDay == now.Day() && iw.isFull() == false {
|
||||
return nil
|
||||
}
|
||||
|
||||
if iw.filePath != "" {
|
||||
var err error
|
||||
fileName := fmt.Sprintf("%s%d%02d%02d_%02d_%02d_%02d.log",
|
||||
iw.filePrefix,
|
||||
now.Year(),
|
||||
now.Month(),
|
||||
now.Day(),
|
||||
now.Hour(),
|
||||
now.Minute(),
|
||||
now.Second())
|
||||
|
||||
filePath := path.Join(iw.filePath, fileName)
|
||||
|
||||
iw.outFile, err = os.Create(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iw.fileDay = now.Day()
|
||||
iw.fileCreateTime = now.Unix()
|
||||
atomic.StoreInt64(&iw.writeBytes, 0)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetDefaultHandler() IOriginHandler {
|
||||
return gLogger.(*Logger).SLogger.Handler().(IOriginHandler)
|
||||
}
|
||||
|
||||
func NewTextLogger(level slog.Level, pathName string, filePrefix string, addSource bool, logChannelCap int) (ILogger, error) {
|
||||
var logger Logger
|
||||
logger.ioWriter.filePath = pathName
|
||||
logger.ioWriter.filePrefix = filePrefix
|
||||
|
||||
logger.SLogger = slog.New(NewOriginTextHandler(level, &logger.ioWriter, addSource, defaultReplaceAttr))
|
||||
logger.setLogChannel(logChannelCap)
|
||||
err := logger.ioWriter.switchFile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &logger, nil
|
||||
}
|
||||
|
||||
func NewJsonLogger(level slog.Level, pathName string, filePrefix string, addSource bool, logChannelCap int) (ILogger, error) {
|
||||
var logger Logger
|
||||
logger.ioWriter.filePath = pathName
|
||||
logger.ioWriter.filePrefix = filePrefix
|
||||
|
||||
logger.SLogger = slog.New(NewOriginJsonHandler(level, &logger.ioWriter, true, defaultReplaceAttr))
|
||||
logger.setLogChannel(logChannelCap)
|
||||
err := logger.ioWriter.switchFile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &logger, nil
|
||||
}
|
||||
|
||||
// Close It's dangerous to call the method on logging
|
||||
func (logger *Logger) Close() {
|
||||
logger.ioWriter.Close()
|
||||
}
|
||||
|
||||
func (logger *Logger) Trace(msg string, args ...any) {
|
||||
logger.SLogger.Log(context.Background(), LevelTrace, msg, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debug(msg string, args ...any) {
|
||||
|
||||
logger.SLogger.Log(context.Background(), LevelDebug, msg, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Info(msg string, args ...any) {
|
||||
logger.SLogger.Log(context.Background(), LevelInfo, msg, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warning(msg string, args ...any) {
|
||||
logger.SLogger.Log(context.Background(), LevelWarning, msg, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Error(msg string, args ...any) {
|
||||
logger.SLogger.Log(context.Background(), LevelError, msg, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Stack(msg string, args ...any) {
|
||||
logger.SLogger.Log(context.Background(), LevelStack, msg, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Dump(msg string, args ...any) {
|
||||
logger.SLogger.Log(context.Background(), LevelDump, msg, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatal(msg string, args ...any) {
|
||||
logger.SLogger.Log(context.Background(), LevelFatal, msg, args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// SetLogger It's non-thread-safe
|
||||
func SetLogger(logger ILogger) {
|
||||
func SetLogger(logger *Logger) {
|
||||
if logger != nil && isSetLogger == false {
|
||||
gLogger = logger
|
||||
isSetLogger = true
|
||||
}
|
||||
}
|
||||
|
||||
func GetLogger() ILogger {
|
||||
func GetLogger() *Logger {
|
||||
return gLogger
|
||||
}
|
||||
|
||||
func Trace(msg string, args ...any) {
|
||||
gLogger.Trace(msg, args...)
|
||||
func (logger *Logger) SetEncoder(encoder zapcore.Encoder) {
|
||||
logger.Encoder = encoder
|
||||
}
|
||||
|
||||
func Debug(msg string, args ...any) {
|
||||
gLogger.Debug(msg, args...)
|
||||
func GetJsonEncoder() zapcore.Encoder {
|
||||
encoderConfig := zap.NewProductionEncoderConfig()
|
||||
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
|
||||
encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder
|
||||
encoderConfig.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
|
||||
enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
|
||||
}
|
||||
|
||||
return zapcore.NewJSONEncoder(encoderConfig)
|
||||
}
|
||||
|
||||
func Info(msg string, args ...any) {
|
||||
gLogger.Info(msg, args...)
|
||||
func GetTxtEncoder() zapcore.Encoder {
|
||||
encoderConfig := zap.NewProductionEncoderConfig()
|
||||
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
|
||||
encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder
|
||||
encoderConfig.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
|
||||
enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
|
||||
}
|
||||
|
||||
return zapcore.NewConsoleEncoder(encoderConfig)
|
||||
}
|
||||
|
||||
func Warning(msg string, args ...any) {
|
||||
gLogger.Warning(msg, args...)
|
||||
func getLogConfig() *lumberjack.Logger {
|
||||
return &lumberjack.Logger{
|
||||
Filename: "",
|
||||
MaxSize: 2048,
|
||||
MaxBackups: 0,
|
||||
MaxAge: 0,
|
||||
Compress: false,
|
||||
}
|
||||
}
|
||||
|
||||
func Error(msg string, args ...any) {
|
||||
gLogger.Error(msg, args...)
|
||||
func NewDefaultLogger() *Logger {
|
||||
logger := Logger{}
|
||||
logger.Encoder = GetJsonEncoder()
|
||||
logger.LogConfig = getLogConfig()
|
||||
logger.LogConfig.LocalTime = true
|
||||
|
||||
logger.Init()
|
||||
return &logger
|
||||
}
|
||||
|
||||
func Stack(msg string, args ...any) {
|
||||
gLogger.Stack(msg, args...)
|
||||
func (logger *Logger) SetLogLevel(level zapcore.Level) {
|
||||
logger.LogLevel = level
|
||||
}
|
||||
|
||||
func Dump(dump string, args ...any) {
|
||||
gLogger.Dump(dump, args...)
|
||||
func (logger *Logger) Enabled(zapcore.Level) bool {
|
||||
return logger.stack
|
||||
}
|
||||
|
||||
func Fatal(msg string, args ...any) {
|
||||
gLogger.Fatal(msg, args...)
|
||||
func (logger *Logger) Init() {
|
||||
var coreList []zapcore.Core
|
||||
|
||||
if logger.OpenConsole == nil || *logger.OpenConsole {
|
||||
core := zapcore.NewCore(logger.Encoder, zapcore.AddSync(os.Stdout), logger.LogLevel)
|
||||
coreList = append(coreList, core)
|
||||
}
|
||||
|
||||
if logger.LogPath != "" {
|
||||
writeSyncer := zapcore.AddSync(logger.LogConfig)
|
||||
core := zapcore.NewCore(logger.Encoder, writeSyncer, logger.LogLevel)
|
||||
coreList = append(coreList, core)
|
||||
}
|
||||
|
||||
core := zapcore.NewTee(coreList...)
|
||||
logger.Logger = zap.New(core, zap.AddCaller(), zap.AddStacktrace(logger), zap.AddCallerSkip(1))
|
||||
logger.sugaredLogger = logger.Logger.Sugar()
|
||||
}
|
||||
|
||||
func Close() {
|
||||
gLogger.Close()
|
||||
func (logger *Logger) Debug(msg string, fields ...zap.Field) {
|
||||
logger.Logger.Debug(msg, fields...)
|
||||
}
|
||||
|
||||
func ErrorAttr(key string, value error) slog.Attr {
|
||||
func (logger *Logger) Info(msg string, fields ...zap.Field) {
|
||||
logger.Logger.Info(msg, fields...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warn(msg string, fields ...zap.Field) {
|
||||
logger.Logger.Warn(msg, fields...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Error(msg string, fields ...zap.Field) {
|
||||
logger.Logger.Error(msg, fields...)
|
||||
}
|
||||
|
||||
func (logger *Logger) StackError(msg string, args ...zap.Field) {
|
||||
logger.stack = true
|
||||
logger.Logger.Log(zapcore.ErrorLevel, msg, args...)
|
||||
logger.stack = false
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatal(msg string, fields ...zap.Field) {
|
||||
gLogger.stack = true
|
||||
logger.Logger.Fatal(msg, fields...)
|
||||
gLogger.stack = false
|
||||
}
|
||||
|
||||
func Debug(msg string, fields ...zap.Field) {
|
||||
gLogger.Logger.Debug(msg, fields...)
|
||||
}
|
||||
|
||||
func Info(msg string, fields ...zap.Field) {
|
||||
gLogger.Logger.Info(msg, fields...)
|
||||
}
|
||||
|
||||
func Warn(msg string, fields ...zap.Field) {
|
||||
gLogger.Logger.Warn(msg, fields...)
|
||||
}
|
||||
|
||||
func Error(msg string, fields ...zap.Field) {
|
||||
gLogger.Logger.Error(msg, fields...)
|
||||
}
|
||||
|
||||
func StackError(msg string, fields ...zap.Field) {
|
||||
gLogger.stack = true
|
||||
gLogger.Logger.Error(msg, fields...)
|
||||
gLogger.stack = false
|
||||
}
|
||||
|
||||
func Fatal(msg string, fields ...zap.Field) {
|
||||
gLogger.stack = true
|
||||
gLogger.Logger.Fatal(msg, fields...)
|
||||
gLogger.stack = false
|
||||
}
|
||||
|
||||
func Debugf(msg string, args ...any) {
|
||||
gLogger.sugaredLogger.Debugf(msg, args...)
|
||||
}
|
||||
|
||||
func Infof(msg string, args ...any) {
|
||||
gLogger.sugaredLogger.Infof(msg, args...)
|
||||
}
|
||||
|
||||
func Warnf(msg string, args ...any) {
|
||||
gLogger.sugaredLogger.Warnf(msg, args...)
|
||||
}
|
||||
|
||||
func Errorf(msg string, args ...any) {
|
||||
gLogger.sugaredLogger.Errorf(msg, args...)
|
||||
}
|
||||
|
||||
func StackErrorf(msg string, args ...any) {
|
||||
gLogger.stack = true
|
||||
gLogger.sugaredLogger.Errorf(msg, args...)
|
||||
gLogger.stack = false
|
||||
}
|
||||
|
||||
func Fatalf(msg string, args ...any) {
|
||||
gLogger.sugaredLogger.Fatalf(msg, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) SDebug(args ...interface{}) {
|
||||
logger.sugaredLogger.Debugln(args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) SInfo(args ...interface{}) {
|
||||
logger.sugaredLogger.Infoln(args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) SWarn(args ...interface{}) {
|
||||
logger.sugaredLogger.Warnln(args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) SError(args ...interface{}) {
|
||||
logger.sugaredLogger.Errorln(args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) SStackError(args ...interface{}) {
|
||||
gLogger.stack = true
|
||||
logger.sugaredLogger.Errorln(args...)
|
||||
gLogger.stack = false
|
||||
}
|
||||
|
||||
func (logger *Logger) SFatal(args ...interface{}) {
|
||||
gLogger.stack = true
|
||||
logger.sugaredLogger.Fatalln(args...)
|
||||
gLogger.stack = false
|
||||
}
|
||||
|
||||
func SDebug(args ...interface{}) {
|
||||
gLogger.sugaredLogger.Debugln(args...)
|
||||
}
|
||||
|
||||
func SInfo(args ...interface{}) {
|
||||
gLogger.sugaredLogger.Infoln(args...)
|
||||
}
|
||||
|
||||
func SWarn(args ...interface{}) {
|
||||
gLogger.sugaredLogger.Warnln(args...)
|
||||
}
|
||||
|
||||
func SError(args ...interface{}) {
|
||||
gLogger.sugaredLogger.Errorln(args...)
|
||||
}
|
||||
|
||||
func SStackError(args ...interface{}) {
|
||||
gLogger.stack = true
|
||||
gLogger.sugaredLogger.Errorln(args...)
|
||||
gLogger.stack = false
|
||||
}
|
||||
|
||||
func SFatal(args ...interface{}) {
|
||||
gLogger.stack = true
|
||||
gLogger.sugaredLogger.Fatalln(args...)
|
||||
gLogger.stack = false
|
||||
}
|
||||
|
||||
func ErrorField(key string, value error) zap.Field {
|
||||
if value == nil {
|
||||
return slog.Attr{Key: key, Value: slog.StringValue("nil")}
|
||||
return zap.String(key, "nil")
|
||||
}
|
||||
|
||||
return slog.Attr{Key: key, Value: slog.StringValue(value.Error())}
|
||||
return zap.String(key, value.Error())
|
||||
}
|
||||
|
||||
func String(key, value string) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.StringValue(value)}
|
||||
func String(key, value string) zap.Field {
|
||||
return zap.String(key, value)
|
||||
}
|
||||
|
||||
func Int(key string, value int) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.Int64Value(int64(value))}
|
||||
func Int(key string, value int) zap.Field {
|
||||
return zap.Int(key, value)
|
||||
}
|
||||
|
||||
func Int64(key string, value int64) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.Int64Value(value)}
|
||||
func Int64(key string, value int64) zap.Field {
|
||||
return zap.Int64(key, value)
|
||||
}
|
||||
|
||||
func Int32(key string, value int32) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.Int64Value(int64(value))}
|
||||
func Int32(key string, value int32) zap.Field {
|
||||
return zap.Int32(key, value)
|
||||
}
|
||||
|
||||
func Int16(key string, value int16) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.Int64Value(int64(value))}
|
||||
func Int16(key string, value int16) zap.Field {
|
||||
return zap.Int16(key, value)
|
||||
}
|
||||
|
||||
func Int8(key string, value int8) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.Int64Value(int64(value))}
|
||||
func Int8(key string, value int8) zap.Field {
|
||||
return zap.Int8(key, value)
|
||||
}
|
||||
|
||||
func Uint(key string, value uint) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.Uint64Value(uint64(value))}
|
||||
func Uint(key string, value uint) zap.Field {
|
||||
return zap.Uint(key, value)
|
||||
}
|
||||
|
||||
func Uint64(key string, v uint64) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.Uint64Value(v)}
|
||||
func Uint64(key string, v uint64) zap.Field {
|
||||
return zap.Uint64(key, v)
|
||||
}
|
||||
|
||||
func Uint32(key string, value uint32) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.Uint64Value(uint64(value))}
|
||||
func Uint32(key string, value uint32) zap.Field {
|
||||
return zap.Uint32(key, value)
|
||||
}
|
||||
|
||||
func Uint16(key string, value uint16) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.Uint64Value(uint64(value))}
|
||||
func Uint16(key string, value uint16) zap.Field {
|
||||
return zap.Uint16(key, value)
|
||||
}
|
||||
|
||||
func Uint8(key string, value uint8) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.Uint64Value(uint64(value))}
|
||||
func Uint8(key string, value uint8) zap.Field {
|
||||
return zap.Uint8(key, value)
|
||||
}
|
||||
|
||||
func Float64(key string, v float64) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.Float64Value(v)}
|
||||
func Float64(key string, v float64) zap.Field {
|
||||
return zap.Float64(key, v)
|
||||
}
|
||||
|
||||
func Bool(key string, v bool) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.BoolValue(v)}
|
||||
func Bool(key string, v bool) zap.Field {
|
||||
return zap.Bool(key, v)
|
||||
}
|
||||
|
||||
func Time(key string, v time.Time) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.TimeValue(v)}
|
||||
func Bools(key string, v []bool) zap.Field {
|
||||
return zap.Bools(key, v)
|
||||
}
|
||||
|
||||
func Duration(key string, v time.Duration) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.DurationValue(v)}
|
||||
func Time(key string, v time.Time) zap.Field {
|
||||
return zap.Time(key, v)
|
||||
}
|
||||
|
||||
func Any(key string, value any) slog.Attr {
|
||||
return slog.Attr{Key: key, Value: slog.AnyValue(value)}
|
||||
func Duration(key string, v time.Duration) zap.Field {
|
||||
return zap.Duration(key, v)
|
||||
}
|
||||
|
||||
func Group(key string, args ...any) slog.Attr {
|
||||
return slog.Group(key, args...)
|
||||
func Durations(key string, v []time.Duration) zap.Field {
|
||||
return zap.Durations(key, v)
|
||||
}
|
||||
|
||||
func (logger *Logger) DoSPrintf(level slog.Level, a []interface{}) {
|
||||
if logger.SLogger.Enabled(context.Background(), level) == false {
|
||||
return
|
||||
}
|
||||
|
||||
logger.SLogger.Handler().(IOriginHandler).Lock()
|
||||
defer logger.SLogger.Handler().(IOriginHandler).UnLock()
|
||||
|
||||
logger.sBuff.Reset()
|
||||
|
||||
logger.FormatHeader(&logger.sBuff, level, 3)
|
||||
|
||||
for _, s := range a {
|
||||
logger.sBuff.AppendString(slog.AnyValue(s).String())
|
||||
}
|
||||
logger.sBuff.AppendString("\"\n")
|
||||
logger.ioWriter.Write(logger.sBuff.Bytes())
|
||||
}
|
||||
|
||||
func (logger *Logger) STrace(a ...interface{}) {
|
||||
logger.DoSPrintf(LevelTrace, a)
|
||||
}
|
||||
|
||||
func (logger *Logger) SDebug(a ...interface{}) {
|
||||
logger.DoSPrintf(LevelDebug, a)
|
||||
}
|
||||
|
||||
func (logger *Logger) SInfo(a ...interface{}) {
|
||||
logger.DoSPrintf(LevelInfo, a)
|
||||
}
|
||||
|
||||
func (logger *Logger) SWarning(a ...interface{}) {
|
||||
logger.DoSPrintf(LevelWarning, a)
|
||||
}
|
||||
|
||||
func (logger *Logger) SError(a ...interface{}) {
|
||||
logger.DoSPrintf(LevelError, a)
|
||||
}
|
||||
|
||||
func STrace(a ...interface{}) {
|
||||
gLogger.DoSPrintf(LevelTrace, a)
|
||||
}
|
||||
|
||||
func SDebug(a ...interface{}) {
|
||||
gLogger.DoSPrintf(LevelDebug, a)
|
||||
}
|
||||
|
||||
func SInfo(a ...interface{}) {
|
||||
gLogger.DoSPrintf(LevelInfo, a)
|
||||
}
|
||||
|
||||
func SWarning(a ...interface{}) {
|
||||
gLogger.DoSPrintf(LevelWarning, a)
|
||||
}
|
||||
|
||||
func SError(a ...interface{}) {
|
||||
gLogger.DoSPrintf(LevelError, a)
|
||||
}
|
||||
|
||||
func (logger *Logger) FormatHeader(buf *Buffer, level slog.Level, callDepth int) {
|
||||
t := time.Now()
|
||||
var file string
|
||||
var line int
|
||||
|
||||
// Release lock while getting caller info - it's expensive.
|
||||
var ok bool
|
||||
_, file, line, ok = runtime.Caller(callDepth)
|
||||
if !ok {
|
||||
file = "???"
|
||||
line = 0
|
||||
}
|
||||
file = filepath.Base(file)
|
||||
|
||||
buf.AppendString("time=\"")
|
||||
buf.AppendString(t.Format("2006/01/02 15:04:05"))
|
||||
buf.AppendString("\"")
|
||||
logger.sBuff.AppendString(" level=")
|
||||
logger.sBuff.AppendString(getStrLevel(level))
|
||||
logger.sBuff.AppendString(" source=")
|
||||
|
||||
buf.AppendString(file)
|
||||
buf.AppendByte(':')
|
||||
buf.AppendInt(int64(line))
|
||||
buf.AppendString(" msg=\"")
|
||||
func Any(key string, value any) zap.Field {
|
||||
return zap.Any(key, value)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user