1. 前言
最近在看logrotate使用,现将一些问题和分析过程记录下.
内核版本和系统信息如下:
Linux xxx 4.10.0-37-generic #41~16.04.1-Ubuntu SMP Fri Oct 6 22:42:59 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
不同版本的不同软件配置信息可能会有差异
2. 基本使用
logrotate基本的使用的流程如下:
创建一个logrotate配置文件
将文件放到/etc/logrotate.d目录下
拿一个官方文档的示例,具体配置不在这里展开,如下:
# sample logrotate configuration file
compress
/var/log/messages {
rotate 5
weekly
postrotate
/usr/bin/killall -HUP syslogd
endscript
}
3. 问题
为什么只要将logrotate配置文件放在logrotate.d下面就会自动执行?
具体什么时候执行呢?
4. 分析
既然跟logrotate命令有关,那就使用man logrotate查看下详情:
1 LOGROTATE(8) System Administrator's Manual LOGROTATE(8)
2
3 NAME
4 logrotate ‐ rotates, compresses, and mails system logs
5
6 SYNOPSIS
7 logrotate [-dv] [-f|--force] [-s|--state file] config_file ..
8
9 DESCRIPTION
10 logrotate is designed to ease administration of systems that generate large numbers of log files.
11 It allows automatic rotation, compression, removal, and mailing of log files. Each log file may be
12 handled daily, weekly, monthly, or when it grows too large.
13
14 Normally, logrotate is run as a daily cron job. It will not modify a log more than once in one day
15 unless the criterion for that log is based on the log's size and logrotate is being run more than
16 once each day, or unless the -f or --force option is used.
可以看到第14行中的: Normally, logrotate is run as a daily cron job,表示logrotate一般是以一个cron job的形式每天执行,而cron的每天任务是放在/etc/cron.daily目录下的,查看该目录:
kk:~$ ll /etc/cron.daily
total 68
drwxr-xr-x 2 root root 4096 10月 10 22:48 ./
drwxr-xr-x 138 root root 12288 10月 25 20:20 ../
-rwxr-xr-x 1 root root 311 12月 29 2014 0anacron*
-rwxr-xr-x 1 root root 372 5月 6 2015 logrotate*
发现该目录下有个logrotate文件,里面内容如下:
1 #!/bin/sh
2
3 # Clean non existent log file entries from status file
4 cd /var/lib/logrotate
5 test -e status || touch status
6 head -1 status > status.clean
7 sed 's/"//g' status | while read logfile date
8 do
9 [ -e "$logfile" ] && echo "\"$logfile\" $date"
10 done >> status.clean
11 mv status.clean status
12
13 test -x /usr/sbin/logrotate || exit 0
14 /usr/sbin/logrotate /etc/logrotate.conf
重点在14行: /usr/sbin/logrotate /etc/logrotate.conf. 打开/etc/logrotate.conf:
1 # see "man logrotate" for details
-----------------------------------------------------------skip----------------------------------------------------------------
18 # packages drop log rotation information into this directory
19 include /etc/logrotate.d
-----------------------------------------------------------skip----------------------------------------------------------------
在第19行看到:include /etc/logrotate.d. 根据include指令的定义,该指令后面所跟的路径的文件会被按顺序读取(除了路径和特殊文件),这样可以解释问题1了.
但是还不完整,现在要找的是这个cron.daily下面的文件什么在哪里被使用到. 使用man cron查看说明:
1 CRON(8) System Manager's Manual CRON(8)
-----------------------------------------------------------skip----------------------------------------------------------------
35 NOTES
36 cron searches its spool area (/var/spool/cron/crontabs) for crontab files (which are named after accounts in
37 /etc/passwd); crontabs found are loaded into memory. Note that crontabs in this directory should not be
38 accessed directly - the crontab command should be used to access and update them.
39
40 cron also reads /etc/crontab, which is in a slightly different format (see crontab(5)). In Debian, the con‐
41 tent of /etc/crontab is predefined to run programs under /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly
42 and /etc/cron.monthly. This configuration is specific to Debian, see the note under DEBIAN SPECIFIC below.
43
44 Like /etc/crontab, the files in the /etc/cron.d directory are monitored for changes. In general, the system administrator should not use /etc/cron.d/, but use the standard system
45 crontab /etc/crontab.
100 DEBIAN SPECIFIC
-----------------------------------------------------------skip-----------------------------------------------------------------
124 Support for /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly and /etc/cron.monthly is provided in Debian
125 through the default setting of the /etc/crontab file (see the system-wide example in crontab(5)). The default
126 system-wide crontab contains four tasks: run every hour, every day, every week and every month. Each of these
127 tasks will execute run-parts providing each one of the directories as an argument. These tasks are disabled if
128 anacron is installed (except for the hourly task) to prevent conflicts between both daemons.
可以看到第40到45行说cron默认会读取/etc/crontab和/etc/cron.d下面的文件(mark一下,下文有用到),先看下/etc/crontab:
# /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,在每天的6:25.但是由于本机是ubuntu,属于DEBIAN分支,看下DEBIAN SPECIFIC,发现第127到128行又说These tasks are disabled if anacron is installed(except for the hourly task),查看下:
kk:~$ dpkg -l | grep anacron
ii anacron 2.3-23 amd64 cron-like program that doesn't go by time
既然anacron有安装,那/etc/crontab的cron.daily就要被disable了,那只能看anacron了,使用man anacron:
1 ANACRON(8) Anacron Users' Manual ANACRON(8)
2
-----------------------------------------------------------skip----------------------------------------------------------------
15
16 When executed, Anacron reads a list of jobs from a configuration file, normally /etc/anacrontab (see anacrontab(5)). This file contains the list of jobs that Anacron controls.
17 Each job entry specifies a period in days, a delay in minutes, a unique job identifier, and a shell command.
从第16行中可以看到anacron的默认配置文件为/etc/anacrontab,看下:
1 # /etc/anacrontab: configuration file for anacron
2
3 # See anacron(8) and anacrontab(5) for details.
4
5 SHELL=/bin/sh
6 PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
7 HOME=/root
8 LOGNAME=root
9
10 # These replace cron's entries
11 1 5 cron.daily run-parts --report /etc/cron.daily
12 7 10 cron.weekly run-parts --report /etc/cron.weekly
13 @monthly 15 cron.monthly run-parts --report /etc/cron.monthly
第11行中的1表示一天执行一次,5表示延迟5分钟
终于在第11行看到cron.daily了,那anacron又是何时执行呢?上文在讲cron默认读取的文件时,除了/etc/crontab之外,还会读取/etc/cron.d/下的文件,将该目录列出:
keith@keith-desktop:/etc$ ll /etc/cron.d
total 28
drwxr-xr-x 2 root root 4096 2月 16 2017 ./
drwxr-xr-x 138 root root 12288 10月 25 20:20 ../
-rw-r--r-- 1 root root 244 12月 29 2014 anacron
发现有个anacron文件,查看下:
# /etc/cron.d/anacron: crontab entries for the anacron package
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
30 7 * * * root test -x /etc/init.d/anacron && /usr/sbin/invoke-rc.d anacron start >/dev/null
可以看到anacron的执行时间为每天的7:30分,这当然是不关机的情况,但如果超过这个点才开机呢?看下开机启动项有没有:
kk:~$ ll /etc/init.d | grep anacron
-rwxr-xr-x 1 root root 2014 12月 29 2014 anacron*
果然有,那就说明它有两种启动方式,一种是开机自启,一种是/etc/cron.d/anacron中编排的. 但是现在又有一个问题,既然都开机自启了,再在cron中编排时间有什么意义呢?打开看下:
1 #! /bin/sh
2 ### BEGIN INIT INFO
3 # Provides: anacron
4 # Required-Start: $remote_fs $syslog $time
5 # Required-Stop: $remote_fs $syslog $time
6 # Default-Start: 2 3 4 5
7 # Default-Stop:
8 # Short-Description: Run anacron jobs
9 # Description: The first purpose of this script is to run anacron at
10 # boot so that it can catch up with missed jobs. Note
11 # that anacron is not a daemon. It is run here just once
12 # and is later started by the real cron. The second
13 # purpose of this script is that said cron job invokes
14 # this script to start anacron at those subsequent times,
15 # to keep the logic in one place.
16 ### END INIT INFO
17
18 PATH=/bin:/usr/bin:/sbin:/usr/sbin
19
20 test -x /usr/sbin/anacron || exit 0
21 test -r /etc/default/anacron && . /etc/default/anacron
-----------------------------------------------------------skip----------------------------------------------------------------
上面说anacron不是一个后台进程,开机自启的目的是为了把遗漏的任务给补上,运行完任务后就退出了,在本次开机后的下一次执行任务就要由cron来编排了,这么说就清楚了. 那么logrotate配置文件的执行时间就是开机时间+延时时间或者7:30加延时时间.
流程总结如下:
logrotate配置文件执行流程 (1).png
是否安装anacron的检查由cron来执行
默认anacron有安装就有设置开机自启
5. 总结
最后回答刚开始提出的问题
为什么只要将logrotate配置文件放在logrotate.d下面就会自动执行? 这个可以上述分析和流程图.
具体什么时候执行呢? 如果anacron有安装,则在刚开机时如果条件满足则是开机时间+延时时间,如果是已经开机后条件满足则是/etc/cron.d/anacron中编排的时间+延时时间;如果没有安装,则时间为/etc/crontab中编排的时间.
注:
以上的分析是跟操作系统有关系的
anacrontab中的还有会影响执行时间的因素如:RANDOM_DELAY等,这里不深究了.
真是刚开始只是一些小小的问题, 如果要深究的话真的会发现一串一串的新东西跑出来. 擦码到现在发现都凌晨了,我还计划最迟9点能搞定然后...never mind.