Best way to roll log file in GO

huangapple go评论65阅读模式
英文:

Best way to roll log file in GO

问题

有没有使用Go语言在生产环境中遇到滚动日志文件问题的人?

有没有办法安全地滚动日志文件?

有没有可以实现这个功能的框架?

谢谢。

英文:

Is anyone who is using go language in production faced problem with rolling of log files?

Is there any possibility to roll log file thread safely?

Are there any frameworks that make this?

Thank you.

答案1

得分: 7

我已经在https://github.com/natefinch/lumberjack上取得了很好的成功,它是一个轻量级的库,依赖于Go语言的标准和内存高效的"log"包。

非常简单易用,只需添加一行代码进行设置,然后像正常使用log一样即可:

log.SetOutput(&lumberjack.Logger{
    Filename:   "/var/log/myapp/foo.log",
    MaxSize:    500, // 兆字节
    MaxBackups: 3,
    MaxAge:     28, // 天数
})
英文:

i've had good success with https://github.com/natefinch/lumberjack it's lightweight and piggy backs on golang's standard and memory efficient "log" pkg.

very simple to use, just add one line of code to set it up, and use log as normal:

log.SetOutput(&lumberjack.Logger{
    Filename:   "/var/log/myapp/foo.log",
    MaxSize:    500, // megabytes
    MaxBackups: 3,
    MaxAge:     28, //days
})

答案2

得分: 5

我倾向于采用12因素的日志记录方法,将日志记录到标准错误输出,并让其他组件来处理日志轮转。

然后,你可以让系统自动为你进行日志轮转,具体可以参考这里

英文:

I tend to take the 12 Factor approach of logging to std error and letting something else deal with the rotation.

Then, you have the system rotate the logs for you, as is mentioned here

答案3

得分: 2

我通常不直接使用日志文件。要么你写入网络日志记录器,比如scribe或kafka等;要么更好的是,你写入stdout/stderr,然后由服务运行程序处理写入日志文件、转发到网络日志记录器或轮转文件。

英文:

What I usually do is not use log files directly. Either you write to a network logger, like scribe or kafka, etc; Or preferably, you write to stdout/stderr, and have the service runner deal with writing to logfiles, forwarding to a network logger, or rotating the files.

答案4

得分: 2

这是一个内部解决方案。你可以考虑使用一个单独的goroutine负责日志记录和日志轮转,使用一个通道接收来自其他goroutine的日志。当需要进行轮转时,该goroutine将进行日志轮转,同时其他goroutine传入的日志将被排队在通道中。完成日志轮转后,它将从通道中出队并继续记录日志。

代码示例:

type Log struct {
    log string
    // 其他你可能需要的信息
}

// 这将是你的goroutine
func Logging(LogChannel chan Log) {
    // 假设logger创建/打开一个文件并准备好写入
    logger := New(logger)

    for {
        // 收集日志。也会阻塞,直到通道上有可用的日志
        log := <-LogChannel

        if timeToRotate() {
            RotateLogFile(logger)
        }

        // 写入日志
        logger.Log(log)
    }
}

编辑:之前的代码在检查日志文件是否轮转后才进行阻塞调用。更好的做法是将其放在timeToRotate函数调用之前,以防止在日志文件轮转后仍然写入日志。

英文:

Here's an internal solution. You can consider having a single goroutine responsible for logging and log rotation with a channel where it receives logs from other goroutines. Whenever it is time to rotate, the goroutine will rotate the log, while the incoming logs from other goroutines are enqueued on the channel. After log rotation is completed, it will then dequeue whatever is on the channel and continue logging.

Something along the lines of:

type Log struct {

	log string
	// other info you might want
}

// This will be your goroutine
func Logging(LogChannel chan Log) {
  
	// assume logger creates/opens a file and prepares it for writing  
	logger := New(logger) 

	for {

	    // collect a log. Will also block until a log is available on the channel
	    log &lt;- LogChannel

		if timeToRotate() {
 
			RotateLogFile(logger)
 
		}

		// write log 
		logger.Log(log)
	}
}

EDIT: The previous code had the blocking call after checking if the log file rotated. It is better to put it before the timeToRotate function call to prevent the possibility of writing the log after the log file has rotated

huangapple
  • 本文由 发表于 2016年3月22日 02:37:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/36139061.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定