Files
core/logger/logger.go

364 lines
8.0 KiB
Go
Raw Normal View History

2025-10-02 18:06:23 +08:00
package logger
import (
"encoding/json"
"fmt"
"io"
"log"
"os"
"path/filepath"
"strings"
"sync"
"time"
"git.apinb.com/bsm-sdk/core/conf"
"git.apinb.com/bsm-sdk/core/utils"
2025-10-04 17:42:26 +08:00
"git.apinb.com/bsm-sdk/core/vars"
2025-10-02 18:06:23 +08:00
)
// Logger 日志器结构
type Logger struct {
2025-10-04 17:42:26 +08:00
level vars.LogLevel
2025-10-02 18:06:23 +08:00
infoLogger *log.Logger
warnLogger *log.Logger
errorLogger *log.Logger
fatalLogger *log.Logger
debugLogger *log.Logger
fileWriter io.Writer
consoleWriter io.Writer
mu sync.RWMutex
name string
logDir string
currentDate string
onRemote bool
endpoint string
}
var (
globalLogger *Logger
once sync.Once
)
2025-10-16 13:29:25 +08:00
// 初始化Logger配置
func New(cfg *conf.LogConf) {
if cfg == nil {
cfg = &conf.LogConf{
Name: strings.ToLower(vars.ServiceKey),
Level: vars.LogLevel(vars.DEBUG),
Dir: "./logs/",
Endpoint: "",
Console: true,
File: true,
Remote: false,
}
}
InitLogger(cfg)
}
2025-10-02 18:06:23 +08:00
// InitLogger 初始化全局日志器
func InitLogger(cfg *conf.LogConf) error {
var err error
once.Do(func() {
globalLogger, err = NewLogger(cfg)
})
return err
}
// NewLogger 创建新的日志器
func NewLogger(cfg *conf.LogConf) (*Logger, error) {
// 确保日志目录存在
if err := os.MkdirAll(cfg.Dir, 0755); err != nil {
return nil, fmt.Errorf("创建日志目录失败: %v", err)
}
// 控制台输出
consoleWriter := os.Stdout
// 文件输出
fileWriter, err := createLogFile(cfg.Dir, cfg.Name)
if err != nil {
return nil, fmt.Errorf("创建日志文件失败: %v", err)
}
// 创建多输出写入器
multiWriter := io.MultiWriter(consoleWriter, fileWriter)
logger := &Logger{
2025-10-07 17:31:14 +08:00
level: cfg.Level,
2025-10-02 18:06:23 +08:00
fileWriter: fileWriter,
consoleWriter: consoleWriter,
logDir: cfg.Dir,
name: strings.ToLower(cfg.Name),
currentDate: time.Now().Format("2006-01-02"),
onRemote: cfg.Remote,
endpoint: cfg.Endpoint,
}
// 创建不同级别的日志器
logger.infoLogger = log.New(multiWriter, "[INFO] ", log.LstdFlags)
logger.warnLogger = log.New(multiWriter, "[WARN] ", log.LstdFlags)
logger.errorLogger = log.New(multiWriter, "[ERROR] ", log.LstdFlags)
logger.fatalLogger = log.New(multiWriter, "[FATAL] ", log.LstdFlags)
logger.debugLogger = log.New(multiWriter, "[DEBUG] ", log.LstdFlags)
return logger, nil
}
// createLogFile 创建日志文件
func createLogFile(logDir, name string) (io.Writer, error) {
filename := fmt.Sprintf("%s_%s.log", name, time.Now().Format("2006-01-02"))
filepath := filepath.Join(logDir, filename)
file, err := os.OpenFile(filepath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
return nil, err
}
return file, nil
}
// checkAndRotateLog 检查并轮转日志文件
func (l *Logger) checkAndRotateLog() error {
today := time.Now().Format("2006-01-02")
if l.currentDate != today {
l.mu.Lock()
defer l.mu.Unlock()
if l.currentDate != today {
// 关闭旧文件
if closer, ok := l.fileWriter.(io.Closer); ok {
closer.Close()
}
// 创建新文件
newFileWriter, err := createLogFile(l.logDir, l.name)
if err != nil {
return err
}
l.fileWriter = newFileWriter
l.currentDate = today
// 重新创建多输出写入器
multiWriter := io.MultiWriter(l.consoleWriter, l.fileWriter)
l.infoLogger = log.New(multiWriter, "[INFO] ", log.LstdFlags)
l.warnLogger = log.New(multiWriter, "[WARN] ", log.LstdFlags)
l.errorLogger = log.New(multiWriter, "[ERROR] ", log.LstdFlags)
l.fatalLogger = log.New(multiWriter, "[FATAL] ", log.LstdFlags)
l.debugLogger = log.New(multiWriter, "[DEBUG] ", log.LstdFlags)
}
}
return nil
}
func (l *Logger) sendToRemote(level, name, out string) {
if l.endpoint == "" {
return
}
2026-02-22 14:31:06 +08:00
data := map[string]any{
2025-10-02 18:06:23 +08:00
"level": level,
"name": name,
"out": out,
}
jsonBytes, _ := json.Marshal(data)
utils.HttpPost(l.endpoint, nil, jsonBytes)
}
2026-06-20 23:29:58 +08:00
func (l *Logger) loggerFor(level vars.LogLevel) (*log.Logger, string) {
switch level {
case vars.DEBUG:
return l.debugLogger, "DEBUG"
case vars.INFO:
return l.infoLogger, "INFO"
case vars.WARN:
return l.warnLogger, "WARN"
case vars.ERROR:
return l.errorLogger, "ERROR"
default:
return l.fatalLogger, "FATAL"
}
}
func (l *Logger) output(level vars.LogLevel, out string, fatal bool) {
if !fatal && l.level > level {
return
}
_ = l.checkAndRotateLog()
logger, levelName := l.loggerFor(level)
if fatal {
logger = l.fatalLogger
levelName = "FATAL"
}
if l.onRemote {
go l.sendToRemote(levelName, l.name, out)
}
_ = logger.Output(3, out)
if fatal {
os.Exit(1)
}
}
func (l *Logger) outputf(level vars.LogLevel, format string, v ...any) {
l.output(level, fmt.Sprintf(format, v...), false)
}
2025-10-02 18:06:23 +08:00
// Debug 输出调试信息
2026-02-22 14:31:06 +08:00
func (l *Logger) Debug(v ...any) {
2026-06-20 23:29:58 +08:00
l.output(vars.DEBUG, fmt.Sprint(v...), false)
2025-10-02 18:06:23 +08:00
}
// Debugf 格式化输出调试信息
2026-02-22 14:31:06 +08:00
func (l *Logger) Debugf(format string, v ...any) {
2026-06-20 23:29:58 +08:00
l.outputf(vars.DEBUG, format, v...)
2025-10-02 18:06:23 +08:00
}
// Info 输出信息
2026-02-22 14:31:06 +08:00
func (l *Logger) Info(v ...any) {
2026-06-20 23:29:58 +08:00
l.output(vars.INFO, fmt.Sprint(v...), false)
2025-10-02 18:06:23 +08:00
}
// Infof 格式化输出信息
2026-02-22 14:31:06 +08:00
func (l *Logger) Infof(format string, v ...any) {
2026-06-20 23:29:58 +08:00
l.outputf(vars.INFO, format, v...)
2025-10-02 18:06:23 +08:00
}
// Warn 输出警告
2026-02-22 14:31:06 +08:00
func (l *Logger) Warn(v ...any) {
2026-06-20 23:29:58 +08:00
l.output(vars.WARN, fmt.Sprint(v...), false)
2025-10-02 18:06:23 +08:00
}
// Warnf 格式化输出警告
2026-02-22 14:31:06 +08:00
func (l *Logger) Warnf(format string, v ...any) {
2026-06-20 23:29:58 +08:00
l.outputf(vars.WARN, format, v...)
2025-10-02 18:06:23 +08:00
}
// Error 输出错误
2026-02-22 14:31:06 +08:00
func (l *Logger) Error(v ...any) {
2026-06-20 23:29:58 +08:00
l.output(vars.ERROR, fmt.Sprint(v...), false)
2025-10-02 18:06:23 +08:00
}
// Errorf 格式化输出错误
2026-02-22 14:31:06 +08:00
func (l *Logger) Errorf(format string, v ...any) {
2026-06-20 23:29:58 +08:00
l.outputf(vars.ERROR, format, v...)
2025-10-02 18:06:23 +08:00
}
// Fatal 输出致命错误并退出程序
2026-02-22 14:31:06 +08:00
func (l *Logger) Fatal(v ...any) {
2026-06-20 23:29:58 +08:00
l.output(vars.ERROR, fmt.Sprint(v...), true)
2025-10-02 18:06:23 +08:00
}
// Fatalf 格式化输出致命错误并退出程序
2026-02-22 14:31:06 +08:00
func (l *Logger) Fatalf(format string, v ...any) {
2026-06-20 23:29:58 +08:00
l.output(vars.ERROR, fmt.Sprintf(format, v...), true)
2025-10-02 18:06:23 +08:00
}
// Print 输出信息兼容标准log包
2026-02-22 14:31:06 +08:00
func (l *Logger) Print(v ...any) {
2025-10-02 18:06:23 +08:00
l.Info(v...)
}
// Printf 格式化输出信息兼容标准log包
2026-02-22 14:31:06 +08:00
func (l *Logger) Printf(format string, v ...any) {
2025-10-02 18:06:23 +08:00
l.Infof(format, v...)
}
// Println 输出信息并换行兼容标准log包
2026-02-22 14:31:06 +08:00
func (l *Logger) Println(v ...any) {
2025-10-02 18:06:23 +08:00
l.Info(v...)
}
// SetLevel 设置日志级别
2025-10-04 17:42:26 +08:00
func (l *Logger) SetLevel(level vars.LogLevel) {
2025-10-02 18:06:23 +08:00
l.mu.Lock()
defer l.mu.Unlock()
l.level = level
}
// GetLevel 获取日志级别
2025-10-04 17:42:26 +08:00
func (l *Logger) GetLevel() vars.LogLevel {
2025-10-02 18:06:23 +08:00
l.mu.RLock()
defer l.mu.RUnlock()
return l.level
}
// Close 关闭日志器
func (l *Logger) Close() error {
if closer, ok := l.fileWriter.(io.Closer); ok {
return closer.Close()
}
return nil
}
// 全局日志函数兼容标准log包
2026-06-20 23:29:58 +08:00
// Global logger functions.
func withGlobalLogger(fn func(*Logger)) {
2025-10-02 18:06:23 +08:00
if globalLogger != nil {
2026-06-20 23:29:58 +08:00
fn(globalLogger)
2025-10-02 18:06:23 +08:00
}
}
2026-06-20 23:29:58 +08:00
func Debug(v ...any) {
withGlobalLogger(func(l *Logger) { l.Debug(v...) })
}
2026-02-22 14:31:06 +08:00
func Debugf(format string, v ...any) {
2026-06-20 23:29:58 +08:00
withGlobalLogger(func(l *Logger) { l.Debugf(format, v...) })
2025-10-02 18:06:23 +08:00
}
2026-02-22 14:31:06 +08:00
func Info(v ...any) {
2026-06-20 23:29:58 +08:00
withGlobalLogger(func(l *Logger) { l.Info(v...) })
2025-10-02 18:06:23 +08:00
}
2026-02-22 14:31:06 +08:00
func Infof(format string, v ...any) {
2026-06-20 23:29:58 +08:00
withGlobalLogger(func(l *Logger) { l.Infof(format, v...) })
2025-10-02 18:06:23 +08:00
}
2026-02-22 14:31:06 +08:00
func Warn(v ...any) {
2026-06-20 23:29:58 +08:00
withGlobalLogger(func(l *Logger) { l.Warn(v...) })
2025-10-02 18:06:23 +08:00
}
2026-02-22 14:31:06 +08:00
func Warnf(format string, v ...any) {
2026-06-20 23:29:58 +08:00
withGlobalLogger(func(l *Logger) { l.Warnf(format, v...) })
2025-10-02 18:06:23 +08:00
}
2026-02-22 14:31:06 +08:00
func Error(v ...any) {
2026-06-20 23:29:58 +08:00
withGlobalLogger(func(l *Logger) { l.Error(v...) })
2025-10-02 18:06:23 +08:00
}
2026-02-22 14:31:06 +08:00
func Errorf(format string, v ...any) {
2026-06-20 23:29:58 +08:00
withGlobalLogger(func(l *Logger) { l.Errorf(format, v...) })
2025-10-02 18:06:23 +08:00
}
2026-02-22 14:31:06 +08:00
func Fatal(v ...any) {
2026-06-20 23:29:58 +08:00
withGlobalLogger(func(l *Logger) { l.Fatal(v...) })
2025-10-02 18:06:23 +08:00
}
2026-02-22 14:31:06 +08:00
func Fatalf(format string, v ...any) {
2026-06-20 23:29:58 +08:00
withGlobalLogger(func(l *Logger) { l.Fatalf(format, v...) })
2025-10-02 18:06:23 +08:00
}
2026-02-22 14:31:06 +08:00
func Print(v ...any) {
2026-06-20 23:29:58 +08:00
withGlobalLogger(func(l *Logger) { l.Print(v...) })
2025-10-02 18:06:23 +08:00
}
2026-02-22 14:31:06 +08:00
func Printf(format string, v ...any) {
2026-06-20 23:29:58 +08:00
withGlobalLogger(func(l *Logger) { l.Printf(format, v...) })
2025-10-02 18:06:23 +08:00
}
2026-02-22 14:31:06 +08:00
func Println(v ...any) {
2026-06-20 23:29:58 +08:00
withGlobalLogger(func(l *Logger) { l.Println(v...) })
2025-10-02 18:06:23 +08:00
}
// GetLogger 获取全局日志器实例
func GetLogger() *Logger {
return globalLogger
}