日志对于发现一个应用程序正在做什么或排除一个可能的问题是非常好的。几乎每一个与我们打交道的应用程序都会产生日志,我们也希望我们自己开发的应用程序也能产生这些日志。日志越冗长,我们就有越多的信息。但如果任其自生自灭,日志可能会增长到无法管理的规模,而且它们反过来也会成为自身的问题。因此,最好的办法是对它们进行精简,保留我们需要的那些,其余的归档。
基础知识
logrotate 工具在管理日志方面非常出色。它可以旋转它们、压缩它们、用电子邮件发送它们、删除它们、归档它们,并在你需要时启动新的日志。
运行logrotate 是非常简单的,只要运行logrotate -vs state-file config-file 。在上面的命令中,v 选项启用了verbose模式,s 指定了一个状态文件,最后的config-file 提到了配置文件,在那里你可以指定你需要做什么。
实践
让我们检查一下在我们的系统上默默运行的logrotate 配置,管理我们在/var/log 目录中发现的大量日志。检查一下该目录中的当前文件。你是否看到很多*.[number].gz 文件?这就是logrotate 正在做的事情。你可以在/etc/logrotate.d/rsyslog 下找到这个的配置文件。我的文件看起来像这样。
/var/log/syslog
{
rotate 7
daily
missingok
notifempty
delaycompress
compress
postrotate
reload rsyslog >/dev/null 2>&1 || true
endscript
}
/var/log/mail.info
/var/log/mail.warn
/var/log/mail.err
/var/log/mail.log
/var/log/daemon.log
/var/log/kern.log
/var/log/auth.log
/var/log/user.log
/var/log/lpr.log
/var/log/cron.log
/var/log/debug
/var/log/messages
{
rotate 4
weekly
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
reload rsyslog >/dev/null 2>&1 || true
endscript
}
该文件以定义旋转/var/log/syslog 文件的指令开始,这些指令包含在后面的大括号中。以下是它们的意思。
rotate 7:保留过去七次轮换的日志。然后开始删除它们。daily:每天轮换日志。与rotate 7一起,这意味着将保留过去七天的日志。其他选项有:weekly,monthly,yearly。还有一个size参数,如果日志文件的大小超过了指定的限制,它将旋转日志文件--例如,size 10k,size 10M,size 10G, 等等。如果没有指定任何参数,只要运行logrotate,日志就会被旋转。你甚至可以在cron中运行logrotate,以便在更具体的时间间隔内使用它。missingok:如果日志文件丢失也没关系。不要惊慌。notifempty:如果日志文件是空的,不要旋转。delaycompress:如果压缩打开了,延迟压缩,直到下一次旋转。这允许至少有一个旋转的但未压缩的文件存在。如果你想让昨天的日志保持未压缩的状态以排除故障,这很有用。如果某些程序在重启/重载之前仍然写到旧文件,比如Apache,这也很有帮助。compress:压缩是打开的。使用nocompress来关闭它。postrotate/endscript:轮换后运行本节中的脚本。在做清理工作时很有帮助。还有一个prerotate/endscript,用于在旋转开始前做一些事情。
你能想出下一节对上述配置中提到的所有这些文件做什么吗?第二部分中唯一的额外参数是sharedscripts ,它告诉logrotate ,在所有的日志轮换完成之前,不要运行postrotate/endscript 中的部分。它可以防止脚本在每一个旋转的日志中被执行,并在最后运行一次。
新的东西
我正在使用下面的配置来处理我系统中的Nginx访问和错误日志。
/var/log/nginx/access.log
/var/log/nginx/error.log {
size 1
missingok
notifempty
create 544 www-data adm
rotate 30
compress
delaycompress
dateext
dateformat -%Y-%m-%d-%s
sharedscripts
extension .log
postrotate
service nginx reload
endscript
}
上述脚本可以使用运行。
logrotate -vs state-file /tmp/logrotate
第一次运行该命令时,有这样的输出。
reading config file /tmp/logrotate
extension is now .log
Handling 1 logs
rotating pattern: /var/log/nginx/access.log
/var/log/nginx/error.log 1 bytes (30 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/nginx/access.log
log needs rotating
considering log /var/log/nginx/error.log
log does not need rotating
rotating log /var/log/nginx/access.log, log->rotateCount is 30
Converted ' -%Y-%m-%d-%s' -> '-%Y-%m-%d-%s'
dateext suffix '-2021-08-27-1485508250'
glob pattern '-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
glob finding logs to compress failed
glob finding old rotated logs failed
renaming /var/log/nginx/access.log to /var/log/nginx/access-2021-08-27-1485508250.log
creating new /var/log/nginx/access.log mode = 0544 uid = 33 gid = 4
running postrotate script
* Reloading nginx configuration nginx
第二次运行它。
reading config file /tmp/logrotate
extension is now .log
Handling 1 logs
rotating pattern: /var/log/nginx/access.log
/var/log/nginx/error.log 1 bytes (30 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/nginx/access.log
log needs rotating
considering log /var/log/nginx/error.log
log does not need rotating
rotating log /var/log/nginx/access.log, log->rotateCount is 30
Converted ' -%Y-%m-%d-%s' -> '-%Y-%m-%d-%s'
dateext suffix '-2021-08-27-1485508280'
glob pattern '-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
compressing log with: /bin/gzip
renaming /var/log/nginx/access.log to /var/log/nginx/access-2021-08-27-1485508280.log
creating new /var/log/nginx/access.log mode = 0544 uid = 33 gid = 4
running postrotate script
* Reloading nginx configuration nginx
然后第三次运行。
reading config file /tmp/logrotate
extension is now .log
Handling 1 logs
rotating pattern: /var/log/nginx/access.log
/var/log/nginx/error.log 1 bytes (30 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/nginx/access.log
log needs rotating
considering log /var/log/nginx/error.log
log does not need rotating
rotating log /var/log/nginx/access.log, log->rotateCount is 30
Converted ' -%Y-%m-%d-%s' -> '-%Y-%m-%d-%s'
dateext suffix '-2021-08-27-1485508316'
glob pattern '-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
compressing log with: /bin/gzip
renaming /var/log/nginx/access.log to /var/log/nginx/access-2021-08-27-1485508316.log
creating new /var/log/nginx/access.log mode = 0544 uid = 33 gid = 4
running postrotate script
* Reloading nginx configuration nginx
状态文件的内容看起来是这样的。
logrotate state -- version 2
"/var/log/nginx/error.log" 2021-08-27-9:0:0
"/var/log/nginx/access.log" 2021-08-27-9:11:56