fox/log/log.go

157 lines
3.7 KiB
Go
Raw Normal View History

2025-05-25 20:02:15 +08:00
package log
import (
"fmt"
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
"runtime"
"time"
)
var (
logger *zap.Logger
file *os.File
)
const (
DebugL = zapcore.DebugLevel
InfoL = zapcore.InfoLevel
WarnL = zapcore.WarnLevel
ErrorL = zapcore.ErrorLevel
)
func Open(filepath string, level zapcore.Level) {
if level < DebugL || level > ErrorL {
level = DebugL
}
// 自定义时间编码器,不显示时区
customTimeEncoder := func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006-01-02 15:04:05.000")) // 使用不含时区的格式
}
// 配置lumberjack
file := &lumberjack.Logger{
Filename: filepath, // 日志文件的位置
MaxSize: 100, // 每个日志文件保存的最大尺寸 单位MB
MaxBackups: 3, // 日志文件最多保存多少个备份
MaxAge: 28, // 文件最多保存多少天
Compress: true, // 是否压缩/归档旧文件
}
// var err error
// // 打开日志文件
// file, err = os.OpenFile(filepath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
// if err != nil {
// zap.L().Fatal("无法打开日志文件", zap.Error(err))
// }
// 设置编码器配置
encoderConfig := zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
NameKey: "logger",
CallerKey: "caller",
MessageKey: "msg",
StacktraceKey: "stacktrace",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.LowercaseLevelEncoder,
EncodeTime: customTimeEncoder,
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
}
// 创建控制台输出
consoleEncoder := zapcore.NewConsoleEncoder(encoderConfig)
consoleWriter := zapcore.AddSync(os.Stdout)
consoleCore := zapcore.NewCore(consoleEncoder, consoleWriter, zap.NewAtomicLevelAt(zap.DebugLevel))
// 创建文件输出
fileEncoder := zapcore.NewJSONEncoder(encoderConfig)
fileWriter := zapcore.AddSync(file)
fileCore := zapcore.NewCore(fileEncoder, fileWriter, zap.NewAtomicLevelAt(level))
// 将两个 Core 组合成一个 MultiWriteSyncer
core := zapcore.NewTee(consoleCore, fileCore)
// 创建logger对象
logger = zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1))
// Info = logger.Info
// Debug = logger.Debug
// Warn = logger.Warn
// Error = logger.Error
// Fatal = logger.Fatal
}
func Close() {
if logger != nil {
_ = logger.Sync()
logger = nil
}
if file != nil {
_ = file.Close()
file = nil
}
}
func StackTrace() string {
var pcs [32]uintptr
n := runtime.Callers(3, pcs[:]) // 跳过前3个栈帧即printStackTrace, caller, 和runtime.Callers本身
frames := runtime.CallersFrames(pcs[:n])
s := ""
for {
frame, more := frames.Next()
s += fmt.Sprintf("%+v\n", frame)
if !more {
break
}
}
return s
}
func InfoF(format string, args ...any) {
logger.Info(fmt.Sprintf(format, args...))
}
func Info(msg string, fields ...zap.Field) {
logger.Info(msg, fields...)
}
func Debug(msg string, fields ...zap.Field) {
logger.Debug(msg, fields...)
}
func DebugF(format string, args ...any) {
logger.Debug(fmt.Sprintf(format, args...))
}
func Warn(msg string, fields ...zap.Field) {
logger.Warn(msg, fields...)
}
func WarnF(format string, args ...any) {
logger.Info(fmt.Sprintf(format, args...))
}
func Error(msg string, fields ...zap.Field) {
logger.Error(msg, fields...)
}
func ErrorF(format string, args ...any) {
logger.Error(fmt.Sprintf(format, args...))
}
func Fatal(msg string, fields ...zap.Field) {
logger.Fatal(msg, fields...)
}
func FatalF(format string, args ...any) {
logger.Fatal(fmt.Sprintf(format, args...))
}
// 提供logger方便其它库打印正确的日志调用点
func GetLogger() *zap.Logger {
return logger
}