操作系统: CentOS 6.9_x64

go语言版本: 1.8.3

问题描述

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

  1. /*
  2. golang log example
  3. E-Mail : Mike_Zhang@live.com
  4. */
  5. package main
  6.  
  7. import (
  8. "log"
  9. "os"
  10. )
  11.  
  12. func main() {
  13. logFile,err := os.Create("test1.log")
  14. defer logFile.Close()
  15. if err != nil {
  16. log.Fatalln("open file error!")
  17. }
  18. logger := log.New(logFile,"[Debug]",log.Ldate | log.Ltime | log.Lshortfile)
  19. logger.Println("test debug message")
  20. logger.SetPrefix("[Info]")
  21. logger.Println("test info message")
  22.  
  23. }

运行效果:

  1. [root@local t2]# go build logTest1.go
  2. [root@local t2]# ./logTest1
  3. [root@local t2]# cat test1.log
  4. [Debug]// :: logTest1.go:: test debug message
  5. [Info]// :: logTest1.go:: test info message
  6. [root@local t2]#

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

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

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

解决方案

借助带缓冲的channel来实现。

示例代码如下:

  1. /*
  2. golang log rotate example
  3. E-Mail : Mike_Zhang@live.com
  4. */
  5.  
  6. package main
  7.  
  8. import (
  9. "fmt"
  10. "log"
  11. "os"
  12. "time"
  13. )
  14.  
  15. const (
  16. BACKUP_COUNT =
  17. MAX_FILE_BYTES = *
  18. )
  19.  
  20. func doRotate(fPrefix string) {
  21. for j := BACKUP_COUNT; j >= ; j-- {
  22. curFileName := fmt.Sprintf("%s_%d.log",fPrefix,j)
  23. k := j-
  24. preFileName := fmt.Sprintf("%s_%d.log",fPrefix,k)
  25.  
  26. if k == {
  27. preFileName = fmt.Sprintf("%s.log", fPrefix)
  28. }
  29. _,err := os.Stat(curFileName)
  30. if err == nil {
  31. os.Remove(curFileName)
  32. fmt.Println("remove : ", curFileName)
  33. }
  34. _,err = os.Stat(preFileName)
  35. if err == nil {
  36. fmt.Println("rename : ", preFileName, " => ", curFileName)
  37. err = os.Rename(preFileName, curFileName)
  38. if err != nil {
  39. fmt.Println(err)
  40. }
  41. }
  42. }
  43. }
  44.  
  45. func NewLogger(fPrefix string) (*log.Logger, *os.File) {
  46. var logger *log.Logger
  47. fileName := fmt.Sprintf("%s.log", fPrefix)
  48. fmt.Println("fileName :", fileName)
  49. logFile, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, )
  50.  
  51. if err != nil {
  52. fmt.Println("open file error!")
  53. } else {
  54. logger = log.New(logFile, "[Debug]", log.Ldate|log.Ltime|log.Lshortfile)
  55. }
  56. return logger, logFile
  57. }
  58.  
  59. func logWorker(msgQueue <-chan string) {
  60. fPrefix := "msg"
  61. logger, logFile := NewLogger(fPrefix)
  62. for msg := range msgQueue {
  63. logger.Println(msg)
  64. fi, err2 := logFile.Stat()
  65. if err2 == nil {
  66. if fi.Size() > MAX_FILE_BYTES {
  67. logFile.Close()
  68. doRotate(fPrefix)
  69. logger,logFile = NewLogger(fPrefix)
  70. }
  71. }
  72. }
  73. logFile.Close()
  74. }
  75.  
  76. func main() {
  77. msgQueue := make(chan string, )
  78. go logWorker(msgQueue)
  79.  
  80. for j := ; j <= ; j++ {
  81. msgQueue <- fmt.Sprintf("msg_%d", j)
  82. time.Sleep( * time.Second)
  83. }
  84. close(msgQueue)
  85. return
  86. }

运行效果如下:

  1. [root@local t2]# ./logRotateTest1
  2. fileName : msg.log
  3. rename : msg.log => msg_1.log
  4. fileName : msg.log
  5. rename : msg_1.log => msg_2.log
  6. rename : msg.log => msg_1.log
  7. fileName : msg.log
  8. rename : msg_2.log => msg_3.log
  9. rename : msg_1.log => msg_2.log
  10. rename : msg.log => msg_1.log
  11. fileName : msg.log
  12. ^C

讨论

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

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

本文github地址:

https://github.com/mike-zhang/mikeBlogEssays/blob/master/2017/20170614_golang之logRotate.rst

欢迎补充

golang之log rotate的更多相关文章

  1. Golang官方log包详解

    Golang官方log包详解 以下全是代码, 详解在注释中, 请从头到尾看 // Copyright 2009 The Go Authors. All rights reserved. // Use ...

  2. linux log rotate

    今天老大提醒我产线kafka自身的log文件积累了好几个月了,我才发现原来kafka的log4j并删除old log. 第一反应是采用linux自带的logrotate功能,在/etc/logrota ...

  3. golang package log

    package main import ( "log" "os" ) var logger *log.Logger func main() { file, er ...

  4. Golang中log与fmt区别

    关于使用log与使用fmt的区别 最初的就是直接打印出来,之后一点点升级,比如加上输出的时间,加上goroutine之间的并发操作(打印信息并不能一定按照你规定好的顺序输出来 每次输出的顺序可能会不同 ...

  5. Golang Learn Log #0

    Print/Printf 区别 Print: 可以打印出字符串, 和变量 fmt.Println(var) //right fmt.Println("string") //righ ...

  6. golang基础学习---log

    package main import ( "log" ) func init() { log.SetPrefix("TRACE: ") log.SetFlag ...

  7. Golang 标准库log的实现

      原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://gotaly.blog.51cto.com/8861157/1406905 前 ...

  8. Golang 标准库提供的Log(一)

      原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://gotaly.blog.51cto.com/8861157/1405754 G ...

  9. 关于Relay Log无法自己主动删除的问题(Neither --relay-log nor --relay-log-index were used)

    今天查看mysql err日志.发现mysql重新启动时总会有例如以下日志出现: [Warning] Neither --relay-log nor --relay-log-index were us ...

随机推荐

  1. windows快速删除大量文件

    del /f/s/q dirname> nulrmdir /s/q dirname

  2. js混淆加密,通过混淆Js代码让别人(很难)无法还原

    js混淆加密,通过混淆Js代码让别人(很难)无法还原   使用js的混淆加密,其目的是为了保护我们的前端代码逻辑,对应一些搞技术吃饭的公司来说,为了防止被竞争对手抓取或使用自己的代码,就会考虑如何加密 ...

  3. HTML5实现简单圆周运动示例

    一.使用JS实现圆周运动 根据指定圆心.半径,在定时器中移动固定的弧度,重绘圆圈的位置 源代码: <!DOCTYPE html> <html lang="en"& ...

  4. 02 如何创建线程 线程并发与synchornized

    所有程序运行结果 请自行得出 创建线程方式一:继承Thread类 步骤: 1,定义一个类继承Thread类. 2,覆盖Thread类中的run方法. 3,直接创建Thread的子类对象创建线程. 4, ...

  5. whl文件(python)安装方法

    https://blog.csdn.net/fhl812432059/article/details/51745226 windows7 python2.7 1.用管理员方式打开cmd 2.首先通过p ...

  6. sys.stdout.flush()以及subprocess的用处

    sys.stdout.flush()立即把stdout缓存内容输出. subprocess与shell进行交互,执行shell命令等. 执行shell命令集合: subprocess.check_ou ...

  7. java实时监听日志写入kafka(转)

    原文链接:http://www.sjsjw.com/kf_cloud/article/020376ABA013802.asp 目的 实时监听某目录下的日志文件,如有新文件切换到新文件,并同步写入kaf ...

  8. String、StringBuffer与StringBuilder之间区别(转)

    原文链接:String.StringBuffer与StringBuilder之间区别 最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,Stri ...

  9. IDEA远程debug的使用

    1.打开配置页面 2.添加远程调试配置 3.进行参数配置 不同的jdk版本,配置的参数是不一样的! 其中Host为远程服务器的地址,Port为远程debug的端口,注意要与前面设置的address保持 ...

  10. QT入门系列(3):控制台输出QString

    方式一:使用qDebug()输出 QString str("liyifeng");qDebug() << str;12输出结果:"liyifeng" ...