当前位置: 移动技术网 > IT编程>脚本编程>Go语言 > golang之log rotate详解

golang之log rotate详解

2017年12月08日  | 移动技术网IT编程  | 我要评论

操作系统: centos 6.9_x64

go语言版本: 1.8.3

问题描述

golang的log模块提供的有写日志功能,示例代码如下:

/*
golang log example

*/
package main

import (
  "log"
  "os"
)

func main() {
  logfile,err := os.create("test1.log")
  defer logfile.close()
  if err != nil {
    log.fatalln("open file error!")
  }
  logger := log.new(logfile,"[debug]",log.ldate | log.ltime | log.lshortfile)
  logger.println("test debug message")
  logger.setprefix("[info]")
  logger.println("test info message")

}

运行效果:

[root@local t2]# go build logtest1.go
[root@local t2]# ./logtest1
[root@local t2]# cat test1.log
[debug]2017/06/13 23:18:36 logtest1.go:19: test debug message
[info]2017/06/13 23:18:36 logtest1.go:21: test info message
[root@local t2]#

go语言的log模块没有提供log rotate接口,但实际开发中我们需要该功能:

我们不希望单个日志过大,否则文本编辑器无法打开,查看比较困难;

更不希望占用太大的存储空间,可以指定最多存多少个日志文件。

解决方案

借助带缓冲的channel来实现。

示例代码如下:

/*
  golang log rotate example

*/

package main

import (
  "fmt"
  "log"
  "os"
  "time"
)

const (
  backup_count = 5
  max_file_bytes = 2 * 1024
)

func dorotate(fprefix string) {
  for j := backup_count; j >= 1; j-- {
    curfilename := fmt.sprintf("%s_%d.log",fprefix,j)
    k := j-1
    prefilename := fmt.sprintf("%s_%d.log",fprefix,k)

    if k == 0 {
      prefilename = fmt.sprintf("%s.log", fprefix)
    }
    _,err := os.stat(curfilename)
    if err == nil {
      os.remove(curfilename)
      fmt.println("remove : ", curfilename)
    }
    _,err = os.stat(prefilename)
    if err == nil {
      fmt.println("rename : ", prefilename, " => ", curfilename)
      err = os.rename(prefilename, curfilename)
      if err != nil {
        fmt.println(err)
      }
    }
  }
}

func newlogger(fprefix string) (*log.logger, *os.file) {
  var logger *log.logger
  filename := fmt.sprintf("%s.log", fprefix)
  fmt.println("filename :", filename)
  logfile, err := os.openfile(filename, os.o_rdwr|os.o_create|os.o_append, 0666)

  if err != nil {
    fmt.println("open file error!")
  } else {
    logger = log.new(logfile, "[debug]", log.ldate|log.ltime|log.lshortfile)
  }
  return logger, logfile
}

func logworker(msgqueue <-chan string) {
  fprefix := "msg"
  logger, logfile := newlogger(fprefix)
  for msg := range msgqueue {
    logger.println(msg)
    fi, err2 := logfile.stat()
    if err2 == nil {
      if fi.size() > max_file_bytes {
        logfile.close()
        dorotate(fprefix)
        logger,logfile = newlogger(fprefix)
      }
    }
  }
  logfile.close()
}

func main() {
  msgqueue := make(chan string, 1000)
  go logworker(msgqueue)

  for j := 1; j <= 1000; j++ {
    msgqueue <- fmt.sprintf("msg_%d", j)
    time.sleep(1 * time.second)
  }
  close(msgqueue)
  return
}

运行效果如下:

[root@local t2]# ./logrotatetest1
filename : msg.log
rename : msg.log => msg_1.log
filename : msg.log
rename : msg_1.log => msg_2.log
rename : msg.log => msg_1.log
filename : msg.log
rename : msg_2.log => msg_3.log
rename : msg_1.log => msg_2.log
rename : msg.log => msg_1.log
filename : msg.log
^c

讨论

这里只是个简单的示例代码,实现了log rotate,更多功能需自行开发。

好,就这些了,希望对你有帮助。

以上这篇golang之log rotate详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网