Linux中Golang日志轮转怎么做

在Linux系统中,使用Golang进行日志轮转可以通过第三方库或者自定义实现来完成。下面是两种常见的方法:

方法一:使用第三方库

一个流行的Golang日志库是logrus,它支持日志轮转。你可以使用lumberjack库来实现日志轮转功能。

  1. 首先,安装logruslumberjack库:
go get github.com/sirupsen/logrus
go get gopkg.in/natefinch/lumberjack.v2
  1. 在你的Golang代码中,设置logrus使用lumberjack进行日志轮转:
package main

import (
 "github.com/sirupsen/logrus"
 "gopkg.in/natefinch/lumberjack.v2"
)

func main() {
 logrus.SetFormatter(&logrus.JSONFormatter{})
 logrus.SetOutput(&lumberjack.Logger{
  Filename:   "/var/log/myapp.log",
  MaxSize:    10, // 每个日志文件的最大尺寸(单位:MB)
  MaxBackups: 3,  // 保留的最大日志文件数量
  MaxAge:     28, // 保留的最大日志文件天数
  Compress:   true, // 是否压缩旧的日志文件
 })

 logrus.Info("This is an info message")
 logrus.Warn("This is a warning message")
 logrus.Error("This is an error message")
}

方法二:自定义日志轮转

如果你不想使用第三方库,可以自己实现一个简单的日志轮转功能。以下是一个基本的示例:

package main

import (
 "fmt"
 "io/ioutil"
 "log"
 "os"
 "time"
)

const (
 logFileName = "myapp.log"
 maxFileSize = 10 * 1024 * 1024 // 10MB
 maxBackups  = 3
 maxAge      = 28
)

func main() {
 logFile, err := os.OpenFile(logFileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
 if err != nil {
  log.Fatalf("error opening log file: %v", err)
 }
 defer logFile.Close()

 logger := log.New(logFile, "", log.LstdFlags)

 for {
  // 检查文件大小
  fileInfo, err := logFile.Stat()
  if err != nil {
   log.Fatalf("error getting log file info: %v", err)
  }
  if fileInfo.Size() > maxFileSize {
   rotateLogFile()
  }

  // 写入日志
  logger.Println("This is an info message")

  // 每隔一段时间检查一次
  time.Sleep(1 * time.Minute)
 }
}

func rotateLogFile() {
 // 关闭当前日志文件
 logFile.Close()

 // 重命名日志文件
 os.Rename(logFileName, fmt.Sprintf("%s.%d", logFileName, time.Now().Unix()))

 // 创建一个新的日志文件
 logFile, err := os.OpenFile(logFileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
 if err != nil {
  log.Fatalf("error opening new log file: %v", err)
 }

 // 删除过期的日志文件
 cleanupOldLogs()
}

func cleanupOldLogs() {
 files, err := ioutil.ReadDir(".")
 if err != nil {
  log.Printf("error reading log directory: %v", err)
  return
 }

 for _, file := range files {
  if file.IsDir() {
   continue
  }

  fileName := file.Name()
  if len(fileName) < len(logFileName)+1 {
   continue
  }

  if fileName[:len(logFileName)] == logFileName && !isRecentFile(fileName) {
   os.Remove(fileName)
  }
 }
}

func isRecentFile(fileName string) bool {
 fileTime, err := time.Parse(time.RFC3339, fileName[len(logFileName):])
 if err != nil {
  log.Printf("error parsing file time: %v", err)
  return false
 }

 return time.Since(fileTime) < time class="hljs-number">24*time.Hour
}

这个示例中,我们创建了一个简单的日志轮转功能,每隔一段时间检查日志文件的大小,如果超过最大尺寸,则进行轮转。同时,我们还实现了删除过期日志文件的功能。

注意:这个示例仅用于演示目的,实际生产环境中可能需要更复杂的逻辑和错误处理。在生产环境中,建议使用成熟的第三方库来实现日志轮转功能。