商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > CentOS下Golang日志如何切割

CentOS下Golang日志如何切割

  发布于2026-06-30 阅读(0)

扫一扫,手机访问

日志切割这事儿,在CentOS环境下用Golang来实现,其实有不少路子可走。从成熟的第三方库,到系统自带的日志服务,再到自己动手造轮子,各有各的适用场景。下面把这几种方案拆开聊聊。

CentOS下Golang日志如何切割

方案一:借助第三方日志库

现在社区里成熟的日志库基本都内置了日志切割功能,像logrus、zap这些主流选择。用起来很方便,日志切割、级别控制、格式化输出都一并解决了。

以logrus为例,搭配file-rotatelogs这个hooks库,实现起来非常直观:

package main

import (
    "github.com/sirupsen/logrus"
    "github.com/lestrrat-go/file-rotatelogs"
    "time"
)

func main() {
    log := logrus.New()
    
    // 设置日志级别
    log.SetLevel(logrus.InfoLevel)
    
    // 配置日志切割
    log.SetReportCaller(true)
    log.SetFormatter(&logrus.JSONFormatter{})
    log.Out = rotatelogs.New(
        "/var/log/myapp.log.%d{yyyy-MM-dd}.gz",
        rotatelogs.WithLinkName("/var/log/myapp.log"),
        rotatelogs.WithRotationTime(24*time.Hour),
    )
    
    log.Info("This is an info log")
}

这段配置实现了按天切割并自动压缩,日志文件会保留为.gz格式,同时通过软链接指向当前最新的日志文件,查询起来很方便。

方案二:交给系统日志服务

如果不想在应用层面操心日志管理,还有一种省心的思路:把日志直接输出给系统的日志服务,比如syslog或journald。这样一来,日志的切割、轮转、压缩全交由系统层面的logrotate工具来处理,与应用完全解耦。

使用go-syslog这类库将日志输出到syslog:

package main

import (
    "github.com/RackSec/srs-lib-go/log"
)

func main() {
    log.SetLogger("srs.log", 
        log.LOG_INFO|log.LOG_NOTICE|log.LOG_ALERT|log.LOG_CRIT|log.LOG_ERR|log.LOG_WARNING|log.LOG_DEBUG, 
        log.LOG_PID)
    log.Info("This is an info log")
}

然后在/etc/logrotate.d/下配置对应的轮转规则:

/var/log/srs.log {
    daily
    missingok
    rotate 7
    compress
    notifempty
    create 640 root adm
}

这里配置了按天轮转、保留7天、自动压缩,空文件不轮转。系统级别管理日志,稳定可靠,运维同学也比较熟悉。

方案三:自己动手实现

当然,如果对第三方库有顾虑,或者项目对依赖管理比较严格,完全可以自己写一个简单的日志切割逻辑。核心思路就是定期检查当前日志文件的大小,超过阈值就执行轮转操作。

下面是一个参考实现:

package main

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

const maxLogSize = 10 * 1024 * 1024 // 10 MB

func main() {
    logFile, err := os.OpenFile("myapp.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    if err != nil {
        log.Fatalf("Failed to open log file: %v", err)
    }
    defer logFile.Close()
    
    logger := log.New(logFile, "", log.LstdFlags)
    
    for {
        info, err := logFile.Stat()
        if err != nil {
            log.Fatalf("Failed to get log file info: %v", err)
        }
        
        if info.Size() > maxLogSize {
            logFile.Close()
            
            // 执行轮转:将旧文件依次后移
            for i := 9; i >= 1; i-- {
                src := fmt.Sprintf("myapp.log.%d", i)
                dst := fmt.Sprintf("myapp.log.%d.bak", i+1)
                os.Rename(src, dst)
            }
            os.Rename("myapp.log", "myapp.log.1")
            
            // 创建新的日志文件
            logFile, err = os.OpenFile("myapp.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
            if err != nil {
                log.Fatalf("Failed to open log file: %v", err)
            }
        }
        
        logger.Println("This is an info log")
        time.Sleep(1 * time.Second)
    }
}

这个示例的逻辑很清晰:每秒钟检查一次文件大小,超过10MB就执行轮转,把当前文件重命名为myapp.log.1,旧文件依次后移,最多保留10个备份文件。当然生产环境可能需要考虑更完善的并发控制、压缩、过期清理等功能,但核心思路就是这样。

三种方案各有侧重:第三方库功能丰富、开箱即用;系统日志服务稳定可靠、统一管理;自定义实现灵活可控、无外部依赖。具体选择哪个,取决于项目的实际需求和运维习惯。

本文转载于:https://www.yisu.com/ask/33031017.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

产品推荐

热门关注