101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
// Filename: internal/logging/logging.go
|
||
|
||
package logging
|
||
|
||
import (
|
||
"gemini-balancer/internal/config"
|
||
"io"
|
||
"os"
|
||
"path/filepath"
|
||
|
||
"github.com/sirupsen/logrus"
|
||
"gopkg.in/natefinch/lumberjack.v2"
|
||
)
|
||
|
||
// 包级变量,用于存储日志轮转器
|
||
var logRotator *lumberjack.Logger
|
||
|
||
// NewLogger 返回标准的 *logrus.Logger(兼容 Fx 依赖注入)
|
||
func NewLogger(cfg *config.Config) *logrus.Logger {
|
||
logger := logrus.New()
|
||
|
||
// 设置日志级别
|
||
level, err := logrus.ParseLevel(cfg.Log.Level)
|
||
if err != nil {
|
||
logger.WithField("configured_level", cfg.Log.Level).Warn("Invalid log level, defaulting to 'info'")
|
||
level = logrus.InfoLevel
|
||
}
|
||
logger.SetLevel(level)
|
||
|
||
// 设置日志格式
|
||
if cfg.Log.Format == "json" {
|
||
logger.SetFormatter(&logrus.JSONFormatter{
|
||
TimestampFormat: "2006-01-02T15:04:05.000Z07:00",
|
||
FieldMap: logrus.FieldMap{
|
||
logrus.FieldKeyTime: "timestamp",
|
||
logrus.FieldKeyLevel: "level",
|
||
logrus.FieldKeyMsg: "message",
|
||
},
|
||
})
|
||
} else {
|
||
logger.SetFormatter(&logrus.TextFormatter{
|
||
FullTimestamp: true,
|
||
TimestampFormat: "2006-01-02 15:04:05",
|
||
})
|
||
}
|
||
|
||
// 添加全局字段
|
||
hostname, _ := os.Hostname()
|
||
logger = logger.WithFields(logrus.Fields{
|
||
"service": "gemini-balancer",
|
||
"hostname": hostname,
|
||
}).Logger
|
||
|
||
// 设置日志输出
|
||
if cfg.Log.EnableFile {
|
||
if cfg.Log.FilePath == "" {
|
||
logger.Warn("Log file enabled but no path specified. Logging to console only")
|
||
logger.SetOutput(os.Stdout)
|
||
return logger
|
||
}
|
||
|
||
logDir := filepath.Dir(cfg.Log.FilePath)
|
||
if err := os.MkdirAll(logDir, 0750); err != nil {
|
||
logger.WithError(err).Warn("Failed to create log directory. Logging to console only")
|
||
logger.SetOutput(os.Stdout)
|
||
return logger
|
||
}
|
||
|
||
// 配置日志轮转(保存到包级变量)
|
||
logRotator = &lumberjack.Logger{
|
||
Filename: cfg.Log.FilePath,
|
||
MaxSize: getOrDefault(cfg.Log.MaxSize, 100),
|
||
MaxBackups: getOrDefault(cfg.Log.MaxBackups, 7),
|
||
MaxAge: getOrDefault(cfg.Log.MaxAge, 30),
|
||
Compress: cfg.Log.Compress,
|
||
}
|
||
|
||
logger.SetOutput(io.MultiWriter(os.Stdout, logRotator))
|
||
logger.WithField("log_file", cfg.Log.FilePath).Info("Logging to both console and file")
|
||
} else {
|
||
logger.SetOutput(os.Stdout)
|
||
}
|
||
|
||
logger.Info("Logger initialized successfully")
|
||
return logger
|
||
}
|
||
|
||
// Close 关闭日志轮转器(在 main.go 中调用)
|
||
func Close() {
|
||
if logRotator != nil {
|
||
logRotator.Close()
|
||
}
|
||
}
|
||
|
||
func getOrDefault(value, defaultValue int) int {
|
||
if value <= 0 {
|
||
return defaultValue
|
||
}
|
||
return value
|
||
}
|