在Linux系统中,使用Golang进行日志轮转可以通过第三方库或者自定义实现来完成。下面是两种常见的方法:
一个流行的Golang日志库是logrus
,它支持日志轮转。你可以使用lumberjack
库来实现日志轮转功能。
logrus
和lumberjack
库:go get github.com/sirupsen/logrus
go get gopkg.in/natefinch/lumberjack.v2
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
}
这个示例中,我们创建了一个简单的日志轮转功能,每隔一段时间检查日志文件的大小,如果超过最大尺寸,则进行轮转。同时,我们还实现了删除过期日志文件的功能。
注意:这个示例仅用于演示目的,实际生产环境中可能需要更复杂的逻辑和错误处理。在生产环境中,建议使用成熟的第三方库来实现日志轮转功能。