golang中log日志如何滚动

我现在在一个web服务器启动后的init内将日志写入log文件中

file, err := os.OpenFile("/data/go/test/log/info.log."+time.Now().Format("20060102"), os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
    defer file.Close()
    if err == nil {
        log.SetFlags(log.LstdFlags | log.Lshortfile)
        log.SetPrefix("[Debug]")
        log.SetOutput(file)
    }

现在有一个问题,日志文件我想一天一个,但是这种写法go svr一旦启动起来,日志就一直往那个目录写。是不是应该启动一个goroutine,每天来重写log.setoutput?
或者有更好的办法吗?

阅读 12.7k
5 个回答

你好,这是个好问题,我之前也没仔细思考过,所以回答之前做了一番研究。下面是我的回答。

是不是应该启动一个goroutine,每天来重写log.setoutput?

我个人觉得不需要,你可以在写日志之前来判断。举个例子 lumberjack/lumberjack.go at a96e63847dc3c67d17befa69c303767e2f84e54f · natefinch/lumberjack

// Write implements io.Writer.  If a write would cause the log file to be larger
// than MaxSize, the file is closed, renamed to include a timestamp of the
// current time, and a new log file is created using the original log file name.
// If the length of the write is greater than MaxSize, an error is returned.
func (l *Logger) Write(p []byte) (n int, err error) {
    l.mu.Lock()
    defer l.mu.Unlock()

    writeLen := int64(len(p))
    if writeLen > l.max() {
        return 0, fmt.Errorf(
            "write length %d exceeds maximum file size %d", writeLen, l.max(),
        )
    }

    if l.file == nil {
        if err = l.openExistingOrNew(len(p)); err != nil {
            return 0, err
        }
    }

    if l.size+writeLen > l.max() {
        if err := l.rotate(); err != nil {
            return 0, err
        }
    }

    n, err = l.file.Write(p)
    l.size += int64(n)

    return n, err
}

这里 lumberjack 写日志之前会判断当前日志文件是否达到配置的最大值,如果是就执行一次 rotation。

或者有更好的办法吗?

你的问题抽象出来应该就是 logrotate 的问题,直接使用标准库里的 log 模块还需要自己解决很多问题,比如轮转,比如压缩和旧文件的清理等,所以可以考虑使用第三方库,或者参考他们的实现。这里的第三方库有这些:

我并没有上面看完所有的源码,所以需要你自己鉴别 :)

关键词:logrotate、log roll file、log rotation

Refs:

linux下一般使用logrotate来进行日志切割,如果不使用的话可以考虑每次进行日志写入操作时判断是否进行日志切割.

你可以自定义一个切割日志功能的 io.Writer。然后用这个实例去初始化一个 log.Logger 就可以了。

可以参考这个 https://github.com/issue9/log...

新手上路,请多包涵

需要扩展log功能直接用log4go方便

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题