linux

Linux中Golang日志轮转怎么做

小樊
37
2025-05-10 15:51:06
栏目: 编程语言

在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.Duration(maxAge)*24*time.Hour
}

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

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

0
看了该问题的人还看了