golang之log rotate详解

 更新时间:2017年06月14日 08:00:10   投稿:jingxian  
下面小编就为大家带来一篇golang之log rotate详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

操作系统: 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详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Go语言中GORM存取数组/自定义类型数据

    Go语言中GORM存取数组/自定义类型数据

    在使用gorm时往往默认的数据类型不满足我们的要求,需要使用一些自定义数据类型作为字段类型,下面这篇文章主要给大家介绍了关于Go语言中GORM存取数组/自定义类型数据的相关资料,需要的朋友可以参考下
    2023-01-01
  • 使用Golang Validator包实现数据验证详解

    使用Golang Validator包实现数据验证详解

    在开发过程中,数据验证是一个非常重要的环节,而golang中的Validator包是一个非常常用和强大的数据验证工具,提供了简单易用的API和丰富的验证规则,下面我们就来看看Validator包的具体使用吧
    2023-12-12
  • 简单了解Go语言中函数作为值以及函数闭包的使用

    简单了解Go语言中函数作为值以及函数闭包的使用

    这篇文章主要介绍了简单了解Go语言中函数作为值以及函数闭包的使用,是golang入门学习中的基础知识,需要的朋友可以参考下
    2015-10-10
  • Go语言利用aicli实现轻松调用DeepSeek和ChatGPT

    Go语言利用aicli实现轻松调用DeepSeek和ChatGPT

    这篇文章主要为大家介绍了一款用Go语言编写的AI助手客户端库——aicli,该库不仅支持ChatGPT,还集成了DeepSeek,感兴趣的小伙伴可以了解一下
    2025-03-03
  • GoLang函数与面向接口编程全面分析讲解

    GoLang函数与面向接口编程全面分析讲解

    这篇文章主要介绍了GoLang函数与面向接口编程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-01-01
  • golang time包的用法详解

    golang time包的用法详解

    这篇文章主要介绍了golang time包的用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Go Singleflight导致死锁问题解决分析

    Go Singleflight导致死锁问题解决分析

    这篇文章主要为大家介绍了Go Singleflight导致死锁问题解决分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 详解Go语言运用广度优先搜索走迷宫

    详解Go语言运用广度优先搜索走迷宫

    广度优先搜索是从图中的某一顶点出发,遍历每一个顶点时,依次遍历其所有的邻接点,再从这些邻接点出发,依次访问它们的邻接点,直到图中所有被访问过的顶点的邻接点都被访问到。然后查看图中是否存在尚未被访问的顶点,若有,则以该顶点为起始点,重复上述遍历的过程
    2021-06-06
  • 理解Golang中的数组(array)、切片(slice)和map

    理解Golang中的数组(array)、切片(slice)和map

    这篇文章主要介绍了理解Golang中的数组(array)、切片(slice)和map,本文先是给出代码,然后一一分解,并给出一张内图加深理解,需要的朋友可以参考下
    2014-10-10
  • 详解Go语言中空结构体的惯用法

    详解Go语言中空结构体的惯用法

    空结构体在 Go 编程中有着广泛的应用,本文将详细探讨空结构体的几种典型用法,并解释为何它们在特定场景下非常有用,希望对大家有所帮助
    2024-11-11

最新评论