在 CentOS 上运行 Go 应用时,日志最常见的问题不是“怎么写”,而是“写久了怎么收”。如果程序一直向同一个文件追加内容,几天后就可能出现日志暴涨、磁盘告警、排障反而更麻烦的情况。下面按安装、配置、验证和代码配合四个环节梳理一遍,帮助你判断这套 logrotate 方案是否已经真正落地,而不是只写了配置文件却没有生效。
为什么要给 Go 应用做日志轮转
很多 Go 服务上线后会直接把日志持续写入单个文件,例如 /var/log/myapp.log。这种做法短期内没问题,但随着运行时间增加,日志文件会不断变大,带来几个直接风险:
- 磁盘空间被持续占用,严重时会影响业务进程和系统稳定性。
- 单个日志文件过大,查看、传输和归档都会变慢。
- 旧日志缺少压缩和清理策略,排障数据越来越难管理。
在 CentOS 上,logrotate 是最常用的系统级日志轮转工具。它适合接管“定期切分、压缩、保留和清理”这类工作,而 Go 程序只需要继续把日志写到指定文件即可。
先确认系统已安装 logrotate
第一步是确认系统里已经安装 logrotate。CentOS 可以直接执行:
sudo yum install logrotate
安装完成后,工具本身通常会通过系统的定时任务机制自动执行,但真正决定它是否处理你的应用日志的,还是后续放在 /etc/logrotate.d/ 里的配置文件。
确定 Go 应用的日志输出文件
在配置轮转前,先把日志路径定下来。本文示例使用:
/var/log/myapp.log
这个路径不是强制要求,但放在 /var/log/ 下更符合常见 Linux 运维习惯,也便于统一管理。关键点不在于路径本身,而在于后面的 logrotate 配置和 Go 程序都要指向同一个文件。
配置 logrotate 规则
CentOS 通常把单独应用的轮转规则放在 /etc/logrotate.d/ 目录中。你可以为应用创建一个独立配置,例如 myapp:

sudo nano /etc/logrotate.d/myapp
写入以下内容:
/var/log/myapp.log {
daily
missingok
rotate 7
compress
notifempty
create 640 root root
}
这份配置各项参数是什么意思
daily:每天轮转一次。如果日志量不大,也可以改成weekly或monthly。missingok:当日志文件不存在时不报错,避免定时任务因为缺文件而产生无意义告警。rotate 7:保留最近 7 份历史日志,超过数量后自动删除更旧文件。compress:旧日志轮转后压缩成.gz,减少磁盘占用。notifempty:如果当前日志文件为空,就不执行轮转。create 640 root root:轮转后新建日志文件,权限为640,属主和属组都是root。
这里最容易出问题的是最后一项。如果你的 Go 应用并不是以 root 身份运行,就不能照搬 create 640 root root。例如应用用户是 myapp,那就应该调整为:
create 640 myapp myapp
否则轮转之后虽然新文件创建成功,但应用可能因为没有写权限而无法继续写日志。
配置完成后先手动测试
不要只等系统自动执行,配置写好后最好立刻手动验证一次:
sudo logrotate -f /etc/logrotate.d/myapp
其中 -f 表示强制轮转,即使还没到设定的时间周期也会执行。这个步骤的作用很直接:尽早暴露语法错误、路径错误或权限问题。如果命令执行时没有报错,说明这份配置基本可用。
查看自动轮转是否真的在运行
logrotate 一般通过 cron 按天执行,因此除了手动测试,还应该确认系统有没有正常记录轮转状态。可以查看状态文件:
cat /var/lib/logrotate/status
这个文件会记录各个日志文件最近一次轮转的时间。看到你的目标日志出现在其中,通常说明自动化机制已经接管了该文件;如果没有记录,就需要继续检查配置文件路径、文件名以及定时任务是否正常。
让 Go 程序把日志写到目标文件
系统侧规则配好了,程序侧也必须配合。也就是说,Go 应用需要明确把日志输出到前面定义的 /var/log/myapp.log。标准库 log 配合 os.OpenFile 就可以完成这件事:

package main
import (
"log"
"os"
)
func main() {
logFile, err := os.OpenFile("/var/log/myapp.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("error opening log file: %v", err)
}
defer logFile.Close()
log.SetOutput(logFile)
log.Println("This is a test log entry.")
}
程序权限和轮转权限要保持一致
这一节是整套方案里最关键的判断点。Go 程序能否持续写日志,取决于两件事是否匹配:
- 应用进程当前使用的运行用户。
logrotate在轮转后创建新日志文件时设置的属主、属组和权限。
如果应用是非 root 用户运行,那么日志文件本身的权限要允许该用户写入,create 参数也必须按同一用户调整。否则就会出现“轮转前正常、轮转后突然不写日志”的典型问题。
部署后重点检查这 3 件事
完成配置后,可以按下面的顺序快速复核:
- 日志路径是否统一:Go 代码和
logrotate都指向/var/log/myapp.log。 - 手动强制轮转是否成功:执行
sudo logrotate -f /etc/logrotate.d/myapp没有报错。 - 轮转后的新文件是否仍可写:尤其检查
create 640 root root是否与实际运行用户一致。
只要这三点都没有问题,CentOS 下 Go 应用的日志轮转基本就算配置完成。后续如果日志增长速度变化较大,再根据实际情况调整 daily、rotate 7 这类参数即可。







