记一次logrotate自动切割日志不成功问题排查
问题描述
环境:
操作系统:ubuntu 14.04.4 LTS
内核版本:4.2.0-27-generic
问题描述:在 /etc/logrotate.d/
中新增加了切割日志的配置后,本应由 crontab
调用 logrotate
执行的日志分割在第二天查看时发现并未进行操作。
思路
使用
logrotate -d /etc/logrotate.d/mongod
调试运行,查看是否配置有误使用
logrotate -fv /etc/logrotate.d/mongod
强制执行,查看日志是否分割查看
crontab
日志、logrotate
日志
logrotate
在 crontab
中自动执行的大致流程图如下
一、执行logrotate查看运行结果
执行
logrotate -d /etc/logrotate.d/mongod
shell 1
2
3
4
5
6
7
8logrotate -d /etc/logrotate.d/mongod
reading config file /etc/logrotate.d/mongod
Handling 1 logs
rotating pattern: /var/log/mongodb/*.log after 1 days (180 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/mongodb/mongod.log # 开始处理mongod.log
log does not need rotating # 因为时间未到,不需要更动!
not running postrotate script, since no logs were rotated
看上去好像没什么问题
强制执行
logrotate -fv /etc/logrotate.d/mongod
shell 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15logrotate -fv /etc/logrotate.d/mongod
reading config file /etc/logrotate.d/mongod
Handling 1 logs
rotating pattern: /var/log/mongodb/*.log forced from command line (180 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/mongodb/mongod.log
log needs rotating
rotating log /var/log/mongodb/mongod.log, log->rotateCount is 180
dateext suffix '-20200108'
glob pattern '-[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
copying /var/log/mongodb/mongod.log to /var/log/mongodb/mongod.log-20200108
truncating /var/log/mongodb/mongod.log # 截断日志
running postrotate script # 运行相关脚本
看结果强制执行是可以执行的,那么只能接着往下排查
二、查看crontab
查看crontab日志
有日志记录情况
查看日志,发现有相关执行记录:
1 | grep -w "cron.daily" /var/log/cron.log |
通过日志知道 cron
成功执行了的,直接跳至三、查看logrotate
无日志记录情况
默认情况下 ubuntu
下并未开启 crontab
日志,CentOS
下启动有相关日志
开启 crontab
日志请参考:linux下开启crontab日志
先查看
crontab
的是否有相关任务计划命令:
cat /etc/crontab
/etc/crontab 1
2
3
4
5
6
7
8
9
10
11
12
13# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#查看
cron.daily
中是否包含logrotate
命令:
cat /etc/cron.daily/logrotate
/etc/cron.daily/logrotate 1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Clean non existent log file entries from status file
cd /var/lib/logrotate
test -e status || touch status
head -1 status > status.clean
sed 's/"//g' status | while read logfile date
do
[ -e "$logfile" ] && echo "\"$logfile\" $date"
done >> status.clean
mv status.clean status
test -x /usr/sbin/logrotate || exit 0
/usr/sbin/logrotate /etc/logrotate.conf
一路看下来发现 crontab
与 logrotate
配置并无异常,并且 crontab
是正确的定时执行了的,看来只能接着查看 logrotate
日志了。
三、查看logrotate
确认 /etc/logrotate.conf 中是否
include /etc/logrotate.d
shell 1
2# grep -w "include" /etc/logrotate.conf
include /etc/logrotate.d再次确认
mongod
配置文件是否正确的位于上述的/etc/logrotate.d
文件中命令:
cat /etc/logrotate.d/mongod
/etc/logrotate.d/mongod 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25{
# 添加日志后缀;格式为:YYYYMMDD
dateext
# 按天轮询:daily;按周轮询:weekly;按月轮询:monthly;按年轮询:yearly
daily
# 忽略执行错误,例如无法找到问题
missingok
# 存档保留最大份数(每轮询一次算一份)
rotate 180
# 完成分割的日志使用gzip归档
compress
# 与compress一起使用,指示logrotate不要将近期的归档文件压缩,压缩在下一次轮询
delaycompress
# 如果日志文件为空,轮询不会进行
notifempty
# 创建新的.log副本后,截断源.log文件
copytruncate
# 将循环日志文件保持在特定目录。该目录必需与现有日志文件在同一文件系统。
# olddir /data/log-bak/
sharedscripts
# 在分割日志时执行命令
postrotate
-f /var/run/mongod.pid ] && kill -USR1 `cat /var/run/mongod.pid`
endscript
}
配置并无异常,并且最开始强制执行也能成功。只能接着查看相关日志了
1 | grep -w "mongod" /var/lib/logrotate/status |
可以看到有相关的日志记录。
后面根据网上查找资料得知问题根本原因就出现在这个 /var/lib/logrotate/status
文件中
/var/lib/logrotate/status
这个文件用以记录日志文件的最后处理日期。 每次执行 logrotate
,其都会检查这个文件,如果发现配置周期内已经执行了切分, 就不会再次切分。
比如配置文件写了 weekly
,且昨天刚刚切分了文件,则这次切分会被 logrotate
记录进文件 /var/lib/logrotate/status
。 在此后一周内,无论手动执行 logrotate
命令,还是通过 cron
执行,都不会再次执行切分动作。(如果使用 -v
参数打印执行详情,会发现要处理的日志文件下有 log does not need rotating 这句)
如果指定 -f (force)
参数执行 logrotate
命令, 则会强制再次执行切分。
当然以上都是配置了日志按时间周期切分的情况, 按文件大小切分的配置不受此影响。
因此,在第一次为某日志文件(假设为 /var/logs/nginx/access.log
)配置了 logrotate
时,由于 /var/lib/logrotate/status
这个文件里没有 /var/logs/nginx/access.log
这个文件的记录,所以 logrotate
不知道是否要切分该文件。于是在第一天时,logrotate
仅把 /var/logs/nginx/access.log
这个文件记录在案,其他啥也没做。
- CentOS下日志文件路径为:
/var/lib/logrotate/logrotate.status
解决方法
等待第二天系统自动切割日志,用上所述新添加的配置项第一天是不会切分的。
如果需要切分,建议手动使用 logrotate -f logfile
强制切分。
- 本文标题:记一次logrotate自动切割日志不成功问题排查
- 本文作者:akiya
- 本文链接:https://little-star.love/posts/bf6840ca/
- 版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!