Go语言实现按小时自动切割日志文件的组件

“最近在用Go语言开发一个日志系统,需要实现按小时自动切割日志文件的功能。想请教大家有没有现成的轮子推荐?或者有没有比较好的实现思路?目前主要考虑如何高效地检测时间变化并触发文件切割,同时保证日志写入不丢失。希望有经验的朋友能分享一下解决方案,谢谢!”

2 回复

推荐使用lumberjack库,配合log包实现。示例:

import "gopkg.in/natefinch/lumberjack.v2"

log.SetOutput(&lumberjack.Logger{
    Filename:   "app.log",
    MaxSize:    1, // MB
    MaxAge:     1, // 天
    MaxBackups: 3,
    LocalTime:  true,
})

支持按大小、时间自动切割和清理。


可以使用Go标准库log和第三方包lumberjack实现按小时切割日志。以下是完整实现:

package main

import (
    "log"
    "net/http"
    
    "gopkg.in/natefinch/lumberjack.v2"
)

func main() {
    // 配置日志切割
    logger := &lumberjack.Logger{
        Filename:   "/var/log/myapp/app.log", // 日志文件路径
        MaxSize:    100,  // 单个文件最大100MB
        MaxBackups: 30,   // 保留30个备份
        MaxAge:     28,   // 保留28天
        Compress:   true, // 启用压缩
    }
    
    // 设置按小时切割(需要自定义时间格式)
    log.SetFlags(log.LstdFlags | log.Lmicroseconds | log.Lshortfile)
    log.SetOutput(logger)
    
    // 示例:模拟日志输出
    go func() {
        for {
            log.Println("这是一条测试日志")
            time.Sleep(10 * time.Second)
        }
    }()
    
    http.ListenAndServe(":8080", nil)
}

关键配置说明:

  1. 按小时切割:lumberjack默认按文件大小切割,要实现按小时切割需要结合日志时间戳
  2. 自定义时间格式:可在日志内容中加入精确时间戳
  3. 文件命名:可通过在Filename中加入时间变量实现按小时分割

增强版(支持按小时分割文件名):

func getHourlyLogFileName() string {
    return fmt.Sprintf("/var/log/myapp/app-%s.log", 
        time.Now().Format("2006-01-02-15"))
}

// 每小时更新日志文件
go func() {
    for {
        logger.Filename = getHourlyLogFileName()
        time.Sleep(time.Hour)
    }
}()

安装依赖:

go get gopkg.in/natefinch/lumberjack.v2

这个方案提供了自动压缩、备份管理和文件滚动功能,适合生产环境使用。

回到顶部