centos

CentOS环境下Golang日志如何分割

小樊
41
2025-08-02 15:10:41
栏目: 编程语言

在CentOS环境下,使用Golang进行日志分割可以通过以下几种方法实现:

方法一:使用第三方库

  1. 安装第三方日志库: 你可以使用logruszap等第三方日志库,它们提供了日志分割的功能。

    go get github.com/sirupsen/logrus
    
  2. 配置日志分割: 使用logrus时,可以通过设置logrus.SetReportCaller(true)来记录调用者信息,并通过自定义io.Writer来实现日志分割。

    package main
    
    import (
        "os"
        "time"
        "github.com/sirupsen/logrus"
        "gopkg.in/natefinch/lumberjack.v2"
    )
    
    func main() {
        log := logrus.New()
        log.SetReportCaller(true)
        log.SetFormatter(&logrus.JSONFormatter{})
    
        // 设置日志分割
        log.SetOutput(&lumberjack.Logger{
            Filename:   "/var/log/myapp.log",
            MaxSize:    10, // 每个日志文件最大10MB
            MaxBackups: 3,  // 最多保留3个备份
            MaxAge:     28, // 最多保留28天
            Compress:   true, // 是否压缩备份日志
        })
    
        log.Info("This is an info message")
    }
    

方法二:使用系统工具

  1. 使用logrotatelogrotate是Linux系统中用于管理日志文件的工具,可以自动分割、压缩和删除旧日志文件。

    • 创建一个logrotate配置文件:

      sudo nano /etc/logrotate.d/myapp
      
    • 添加以下内容:

      /var/log/myapp.log {
          daily
          rotate 7
          compress
          delaycompress
          missingok
          notifempty
          create 640 root root
      }
      
    • 这个配置表示每天分割一次日志文件,保留最近7天的日志,并对旧日志进行压缩。

  2. 重启logrotate服务: 确保logrotate服务已启用并重启:

    sudo systemctl restart logrotate
    

方法三:自定义日志分割逻辑

如果你需要更复杂的日志分割逻辑,可以在Golang代码中实现自定义的日志分割功能。

package main

import (
    "io"
    "log"
    "os"
    "time"
)

type RotatingWriter struct {
    file        *os.File
    maxFileSize int64
    backupCount int
    currentSize int64
    lastRotate  time.Time
}

func NewRotatingWriter(filename string, maxFileSize int64, backupCount int) (*RotatingWriter, error) {
    file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    if err != nil {
        return nil, err
    }
    return &RotatingWriter{
        file:        file,
        maxFileSize: maxFileSize,
        backupCount: backupCount,
        lastRotate:  time.Now(),
    }, nil
}

func (rw *RotatingWriter) Write(p []byte) (n int, err error) {
    n, err = rw.file.Write(p)
    rw.currentSize += int64(n)

    if rw.currentSize >= rw.maxFileSize {
        rw.rotate()
    }

    return n, err
}

func (rw *RotatingWriter) rotate() error {
    if err := rw.file.Close(); err != nil {
        return err
    }

    // 重命名当前日志文件
    newFilename := rw.file.Name() + "." + time.Now().Format("2006-01-02-15-04-05")
    if err := os.Rename(rw.file.Name(), newFilename); err != nil {
        return err
    }

    // 创建新的日志文件
    rw.file, err = os.OpenFile(rw.file.Name(), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    if err != nil {
        return err
    }

    rw.lastRotate = time.Now()
    return nil
}

func main() {
    log.SetOutput(&RotatingWriter{
        filename:    "/var/log/myapp.log",
        maxFileSize: 10 * 1024 * 1024, // 10MB
        backupCount: 3,
    })

    log.Info("This is an info message")
}

这个示例代码实现了一个简单的日志分割功能,当日志文件大小达到指定值时,会自动创建一个新的日志文件,并保留指定数量的旧日志文件。

选择适合你项目需求的方法来实现日志分割。

0
看了该问题的人还看了