golang glog maxsize

6959 ワード

glogソースにはこの定義があります.
// MaxSize is the maximum size of a log file in bytes.
var MaxSize uint64 = 1024 * 1024 * 1800

もし私が老眼でぼんやりしていなければ、この値は1.8 GBです.すなわち、golang glogの最大単一ログファイルのサイズは1.8 GBである.テストのためにプログラムを書きます.
[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")
    }
}

ビルド後、実行:
./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.8 Gに増加すると,確かに新しいファイルが自動的に分割されることがわかる.
では、単一のファイルサイズをどのように変更しますか?簡単:
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方式を参考にすることもできます.