fox/log/log.go
2025-05-30 22:13:19 +08:00

157 lines
3.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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, // FullCallerEncoder,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
}