143 lines
3.3 KiB
Go
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...))
|
|
}
|