golang glog maxsize

glog源码中有这个定义:

// MaxSize is the maximum size of a log file in bytes.
var MaxSize uint64 = 1024 * 1024 * 1800

如果我没有老眼昏花看不清楚的话,这个值是1.8GB。
也就是说,golang glog最大单个日志文件的大小为1.8GB。
写个程序来测试:

[www@dev-hdp007 glogtest]$ cat test.go 
package main

import (
    "flag"
    "github.com/golang/glog"
)

func main() {

    flag.Parse()

    for {
        glog.Info("just a test, how big will glog file grow")
    }
}

build之后,运行:

./glogtest -log_dir=.

过一段时间观测到如下结果:

[www@dev-hdp007 glogtest]$ du -hs *
2.2M    glogtest
1.8G    glogtest.dev-hdp007.www.log.INFO.20170817-145957.22644
320M    glogtest.dev-hdp007.www.log.INFO.20170817-150110.22644
0       glogtest.INFO
4.0K    test.go

可见,当glog文件增长到1.8G之后,确实自动分割出新的文件来了。

那么如何修改单个文件大小呢?
很简单:

func init() {
    glog.MaxSize = 1024 * 1024 // 1MB
}

再次测试结果:

[www@dev-hdp007 glogtest]$ du -hs *
2.2M    glogtest
1.0M    glogtest.dev-hdp007.www.log.INFO.20170817-150538.27894
1.0M    glogtest.dev-hdp007.www.log.INFO.20170817-150539.27894
1.0M    glogtest.dev-hdp007.www.log.INFO.20170817-150540.27894
1.0M    glogtest.dev-hdp007.www.log.INFO.20170817-150541.27894
1.0M    glogtest.dev-hdp007.www.log.INFO.20170817-150542.27894
1.0M    glogtest.dev-hdp007.www.log.INFO.20170817-150543.27894
516K    glogtest.dev-hdp007.www.log.INFO.20170817-150544.27894
0       glogtest.INFO
4.0K    test.go

单个文件大小确实如我们预期。

本着“求根问底”的求是精神,我们还得问一句,这是如何实现的呢?于是寻根溯源,找到glog的源码中:

// syncBuffer joins a bufio.Writer to its underlying file, providing access to the
// file's Sync method and providing a wrapper for the Write method that provides log
// file rotation. There are conflicting methods, so the file cannot be embedded.
// l.mu is held for all its methods.
type syncBuffer struct {
    logger *loggingT
    *bufio.Writer
    file   *os.File
    sev    severity
    nbytes uint64 // The number of bytes written to this file
}

func (sb *syncBuffer) Sync() error {
    return sb.file.Sync()
}

func (sb *syncBuffer) Write(p []byte) (n int, err error) {
    if sb.nbytes+uint64(len(p)) >= MaxSize { // 判断是否超出MaxSize
        if err := sb.rotateFile(time.Now()); err != nil {
            sb.logger.exit(err)
        }
    }
    n, err = sb.Writer.Write(p)
    sb.nbytes += uint64(n)
    if err != nil {
        sb.logger.exit(err)
    }
    return
}

在写入缓冲的时候,如果发现大小已经超过MaxSize,就rotateFile(写入缓冲,关闭旧的文件句柄,并新建文件,句柄关联到sb.Writer)。

这下就明白了glog的单个log文件大小控制的原理了,以后如果需要自己定制log处理库的话,也可以参考这种rotate方式。

你可能感兴趣的:(go)