gologger/file.go

196 lines
4.4 KiB
Go
Raw Normal View History

2023-11-28 18:29:30 +08:00
package gologger
import (
"os"
"path/filepath"
"regexp"
"strconv"
"time"
2023-11-28 18:29:30 +08:00
)
type FileAppender struct {
formatter LogFormatter
filePath string
lchan chan LogEvent
file *os.File
stopChan chan struct{}
// 新增滚动相关字段
EnableRolling bool
MaxSize int64 // 文件最大大小(字节)
MaxAge int64 // 文件最大时间(秒)
currentFileSize int64 // 当前文件大小
createdAt int64 // 文件创建时间戳
2024-09-21 14:25:45 +08:00
}
// Close implements LoggerAppender.
func (f *FileAppender) Close() {
//send stop signal
f.stopChan <- struct{}{}
2023-11-28 18:29:30 +08:00
}
func (f *FileAppender) GetName() string {
return "FileAppender:" + f.filePath
}
func (f *FileAppender) start() {
f.lchan = make(chan LogEvent, 10)
2024-09-21 14:25:45 +08:00
f.stopChan = make(chan struct{})
2023-11-28 18:29:30 +08:00
if f.file == nil || int(f.file.Fd()) == -1 {
dirName := filepath.Dir(f.filePath)
_, err := os.Stat(dirName)
if err != nil && os.IsNotExist(err) {
os.MkdirAll(dirName, 0755)
}
f.file, _ = os.OpenFile(f.filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
// 获取当前文件大小
if stat, err := f.file.Stat(); err == nil {
f.currentFileSize = stat.Size()
}
// 记录文件创建时间
f.createdAt = time.Now().Unix()
2023-11-28 18:29:30 +08:00
}
go func() {
2023-12-13 23:07:32 +08:00
defer f.file.Close()
for {
2024-09-21 14:25:45 +08:00
select {
case <-f.stopChan:
return
case logEvent := <-f.lchan:
// 检查日志滚动
if f.EnableRolling {
f.checkAndRoll(logEvent)
}
logMsg := f.formatter(logEvent)
2024-09-21 14:25:45 +08:00
f.file.WriteString(logMsg)
}
}
}()
}
// 新增日志滚动方法
func (f *FileAppender) checkAndRoll(logEvent LogEvent) {
// 按大小滚动
if f.MaxSize > 0 && f.currentFileSize >= f.MaxSize {
f.rollFile(logEvent)
return
}
// 按时间滚动
if f.MaxAge > 0 && time.Now().Unix()-f.createdAt >= f.MaxAge {
f.rollFile(logEvent)
}
}
// 日志文件滚动
func (f *FileAppender) rollFile(logEvent LogEvent) {
// 关闭当前文件
f.file.Close()
// 重命名旧文件
timestamp := time.Now().Format("20060102150405")
newPath := f.filePath + "." + timestamp
os.Rename(f.filePath, newPath)
// 创建新文件
f.file, _ = os.OpenFile(f.filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
// 重置状态
f.currentFileSize = 0
f.createdAt = time.Now().Unix()
// 重新写入当前日志
logMsg := format(logEvent)
f.file.WriteString(logMsg)
}
func (f *FileAppender) Append(logEvent LogEvent) {
2023-11-28 18:29:30 +08:00
f.lchan <- logEvent
2023-11-28 18:29:30 +08:00
}
func makeFileAppender(appenderConfig LogAppenderConfig) *LoggerAppender {
2023-11-28 18:29:30 +08:00
var logfile interface{}
var ok bool
logfile, ok = appenderConfig.Options["file"]
if !ok {
logfile = "default.log"
}
// 新增滚动配置参数
rollingEnabled := false
if enable, ok := appenderConfig.Options["enableRolling"].(bool); ok {
rollingEnabled = enable
}
maxSize := int64(0)
if size, ok := appenderConfig.Options["maxSize"].(int64); ok {
maxSize = size * 1024 * 1024 // 将兆转换为字节
} else if sizeStr, ok := appenderConfig.Options["maxSize"].(string); ok {
// 解析带单位的大小配置支持KB, MB, GB
var re = regexp.MustCompile(`(?i)^(\d+)([kmg]b)?$`)
matches := re.FindStringSubmatch(sizeStr)
if len(matches) > 0 {
num, _ := strconv.ParseInt(matches[1], 10, 64)
unit := ""
if len(matches) > 2 {
unit = matches[2]
}
switch unit {
case "KB", "kb":
maxSize = num * 1024
case "MB", "mb":
maxSize = num * 1024 * 1024
case "GB", "gb":
maxSize = num * 1024 * 1024 * 1024
default:
maxSize = num * 1024 * 1024 // 默认按MB处理
}
}
}
maxAge := int64(0)
if ageStr, ok := appenderConfig.Options["maxAge"].(string); ok {
// 解析带单位的时间配置
re := regexp.MustCompile(`^\d+[hd]?$`)
if re.MatchString(ageStr) {
// 提取数字部分和单位
numStr := ""
unit := ""
for _, c := range ageStr {
if c >= '0' && c <= '9' {
numStr += string(c)
} else {
unit = string(c)
}
}
num, _ := strconv.ParseInt(numStr, 10, 64)
switch unit {
case "h":
maxAge = num * 3600 // 小时转秒
default:
maxAge = num * 86400 // 默认按天转秒
}
}
} else if ageInt, ok := appenderConfig.Options["maxAge"].(int64); ok {
maxAge = ageInt
}
2023-11-28 18:29:30 +08:00
var ret LoggerAppender = &FileAppender{
formatter: SelectFormatter(appenderConfig.Formatter),
filePath: logfile.(string),
EnableRolling: rollingEnabled,
MaxSize: maxSize,
MaxAge: maxAge,
2023-11-28 18:29:30 +08:00
}
ret.(*FileAppender).start()
return &ret
2023-11-28 18:29:30 +08:00
}
func init() {
RegistAppender("file", makeFileAppender)
}