发布于2026-06-30 阅读(0)
扫一扫,手机访问
日志切割这事儿,在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个备份文件。当然生产环境可能需要考虑更完善的并发控制、压缩、过期清理等功能,但核心思路就是这样。
三种方案各有侧重:第三方库功能丰富、开箱即用;系统日志服务稳定可靠、统一管理;自定义实现灵活可控、无外部依赖。具体选择哪个,取决于项目的实际需求和运维习惯。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8