Files
2026-08-23 00:48:10 +08:00

143 lines
3.3 KiB
Go

package utils
import (
"fmt"
"os"
"path/filepath"
"time"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gorm.io/gorm"
"filestoragesystem/internal/model"
)
var logger *zap.Logger
// Logger 获取全局日志对象
func Logger() *zap.Logger {
if logger == nil {
logger, _ = zap.NewProduction()
}
return logger
}
// InitLogger 初始化zap日志(控制台 + 可选文件)
func InitLogger(level, dir string) (*zap.Logger, error) {
lvl := zapcore.InfoLevel
_ = lvl.UnmarshalText([]byte(level))
encoderCfg := zap.NewProductionEncoderConfig()
encoderCfg.EncodeTime = zapcore.ISO8601TimeEncoder
encoderCfg.EncodeLevel = zapcore.CapitalLevelEncoder
cores := make([]zapcore.Core, 0, 3)
// 控制台
consoleSyncer := zapcore.AddSync(os.Stdout)
consoleEncoder := zapcore.NewConsoleEncoder(encoderCfg)
cores = append(cores, zapcore.NewCore(consoleEncoder, consoleSyncer, lvl))
// 文件
if dir != "" {
if err := os.MkdirAll(dir, 0o755); err == nil {
fileSyncer := zapcore.AddSync(&dateRollFile{dir: dir})
fileEncoder := zapcore.NewJSONEncoder(encoderCfg)
cores = append(cores, zapcore.NewCore(fileEncoder, fileSyncer, lvl))
}
}
logger = zap.New(zapcore.NewTee(cores...), zap.AddCaller(), zap.AddCallerSkip(1))
return logger, nil
}
// dateRollFile 按天滚动的日志文件
type dateRollFile struct {
dir string
f *os.File
day string
}
func (d *dateRollFile) Write(p []byte) (int, error) {
today := time.Now().Format("2006-01-02")
if d.f == nil || d.day != today {
if d.f != nil {
_ = d.f.Close()
}
path := filepath.Join(d.dir, "app-"+today+".log")
f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644)
if err != nil {
return 0, err
}
d.f, d.day = f, today
}
return d.f.Write(p)
}
func (d *dateRollFile) Sync() error {
if d.f != nil {
return d.f.Sync()
}
return nil
}
// ---- 系统日志异步落库 ----
var sysLogDB *gorm.DB
var sysLogCh chan model.SystemLog
// InitSystemLog 初始化系统日志异步写入器
func InitSystemLog(db *gorm.DB) {
sysLogDB = db
sysLogCh = make(chan model.SystemLog, 256)
go func() {
for entry := range sysLogCh {
if err := sysLogDB.Create(&entry).Error; err != nil {
Logger().Error("写入系统日志失败", zap.Error(err))
}
}
}()
}
// SystemLog 异步记录一条系统日志
func SystemLog(level, module, message string) {
if sysLogCh == nil {
return
}
select {
case sysLogCh <- model.SystemLog{Level: level, Module: module, Message: message, CreatedAt: time.Now()}:
default:
// 队列满则丢弃,避免阻塞业务
}
}
// SystemLogDetail 异步记录带详情的系统日志
func SystemLogDetail(level, module, message, requestID, ip, extra string) {
if sysLogCh == nil {
return
}
select {
case sysLogCh <- model.SystemLog{
Level: level, Module: module, Message: message,
RequestID: requestID, IP: ip, ExtraData: extra, CreatedAt: time.Now(),
}:
default:
}
}
// Info 记录info级别系统日志
func Info(module, format string, args ...interface{}) {
SystemLog("info", module, fmt.Sprintf(format, args...))
}
// Warn 记录warn级别系统日志
func Warn(module, format string, args ...interface{}) {
SystemLog("warn", module, fmt.Sprintf(format, args...))
}
// Error 记录error级别系统日志
func Error(module, format string, args ...interface{}) {
SystemLog("error", module, fmt.Sprintf(format, args...))
}