140 lines
2.9 KiB
Go
140 lines
2.9 KiB
Go
package logger
|
||
|
||
import (
|
||
"log"
|
||
"os"
|
||
"path/filepath"
|
||
"sync"
|
||
"time"
|
||
)
|
||
|
||
// Logger 全局日志实例
|
||
var Logger *log.Logger
|
||
var logFile *os.File
|
||
var logFileName string
|
||
var mu sync.Mutex
|
||
|
||
// InitLogger 初始化日志,创建 /data/logs 目录并按天命名文件
|
||
func InitLogger() error {
|
||
mu.Lock()
|
||
defer mu.Unlock()
|
||
|
||
// 创建 /data/logs 目录
|
||
logDir := "/data/logs"
|
||
if err := os.MkdirAll(logDir, 0755); err != nil {
|
||
return err
|
||
}
|
||
|
||
// 按天生成日志文件名:20260102.log
|
||
logFileName = filepath.Join(logDir, time.Now().Format("20060102")+".log")
|
||
file, err := os.OpenFile(logFileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
logFile = file
|
||
Logger = log.New(file, "", log.LstdFlags)
|
||
|
||
// 启动日志文件切换和清理的goroutine
|
||
go startLogMaintenance()
|
||
|
||
return nil
|
||
}
|
||
|
||
// startLogMaintenance 启动日志维护(文件切换和清理)
|
||
func startLogMaintenance() {
|
||
// 每天凌晨检查是否需要切换日志文件
|
||
ticker := time.NewTicker(1 * time.Hour) // 每小时检查一次
|
||
defer ticker.Stop()
|
||
|
||
for range ticker.C {
|
||
checkLogFileSwitch()
|
||
|
||
// 每天凌晨2点执行日志清理
|
||
if time.Now().Hour() == 2 {
|
||
CleanupOldLogs()
|
||
}
|
||
}
|
||
}
|
||
|
||
// checkLogFileSwitch 检查并切换日志文件
|
||
func checkLogFileSwitch() {
|
||
mu.Lock()
|
||
defer mu.Unlock()
|
||
|
||
if logFile == nil {
|
||
return
|
||
}
|
||
|
||
newFileName := filepath.Join("/data/logs", time.Now().Format("20060102")+".log")
|
||
if newFileName != logFileName {
|
||
newFile, err := os.OpenFile(newFileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||
if err != nil {
|
||
log.Printf("切换日志文件失败: %v", err)
|
||
return
|
||
}
|
||
|
||
logFile.Close()
|
||
logFile = newFile
|
||
logFileName = newFileName
|
||
Logger = log.New(newFile, "", log.LstdFlags)
|
||
Logger.Printf("日志文件已切换到: %s", newFileName)
|
||
}
|
||
}
|
||
|
||
// CloseLogger 关闭日志文件
|
||
func CloseLogger() {
|
||
mu.Lock()
|
||
defer mu.Unlock()
|
||
if logFile != nil {
|
||
logFile.Close()
|
||
logFile = nil
|
||
}
|
||
}
|
||
|
||
// Close 是 CloseLogger 的别名,提供兼容性
|
||
func Close() {
|
||
CloseLogger()
|
||
}
|
||
|
||
// CleanupOldLogs 删除超过30天的日志文件
|
||
func CleanupOldLogs() {
|
||
logDir := "/data/logs"
|
||
files, err := os.ReadDir(logDir)
|
||
if err != nil {
|
||
if Logger != nil {
|
||
Logger.Printf("读取日志目录 %s 错误: %v", logDir, err)
|
||
}
|
||
return
|
||
}
|
||
|
||
const maxAge = 30 * 24 * time.Hour // 30天
|
||
cutoffTime := time.Now().Add(-maxAge)
|
||
|
||
for _, file := range files {
|
||
if file.IsDir() {
|
||
continue
|
||
}
|
||
|
||
info, err := file.Info()
|
||
if err != nil {
|
||
if Logger != nil {
|
||
Logger.Printf("获取文件信息 %s 错误: %v", file.Name(), err)
|
||
}
|
||
continue
|
||
}
|
||
|
||
if info.ModTime().Before(cutoffTime) {
|
||
filePath := filepath.Join(logDir, file.Name())
|
||
if err := os.Remove(filePath); err != nil {
|
||
if Logger != nil {
|
||
Logger.Printf("删除旧日志文件 %s 错误: %v", filePath, err)
|
||
}
|
||
} else {
|
||
if Logger != nil {
|
||
Logger.Printf("删除旧日志文件 %s 成功", filePath)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|