logrotate日志轮转工具简介

日志轮转 log rotation 解读:日志轮转是系统管理中使用的一个自动化过程,在此过程中,一旦日志文件太旧或太大,就会对其进行压缩、移动(存档)、重命名或删除。

1. logrotate 简介

  • 管理系统所产生的日志文件。可自动对日志进行截断(或轮转)、压缩以及删除旧的日志文件。
  • 可周期性(按天/周/月)或当所监控文本文件大小超过阈值时(eg. 100MB),对文件进行截断(轮转)、压缩或删除过于老旧备份文件等处理。
  • Linux系统默认安装logrotate工具,判断有无安装logrotate方式:which logrotate
  • logrotate自身为一个命令行工具,需要手动调用或基于计划任务cron调起logrotate工作
    (默认情况已在/etc/cron.daily/logrotate配置了其每天定时执行)

1.1. logrotate 配置文件说明

logrotate 配置文件包括:

  • logrotate 自身的配置文件: /etc/logrotate.conf
  • 需要轮转管理的日志文件各自的配置文件: /etc/logrotate.d/*(统一放置于/etc/logrotate.d/目录下)

1.2. logrotate 手动运行命令

在完成/修改 logrotate 配置后,需重启 logrotate 以使配置生效。

手动运行logrotate的命令:

1
/usr/sbin/logrotate /etc/logrotate.conf

手动执行某个日志的轮转配置文件的命令:

1
/usr/sbin/logrotate -vf /etc/logrotate.d/log-file

1.3. 添加 logrotate 工具的计划任务

/etc/cron.daily目录下,有个logrotate的脚本,系统每天会执行/etc/cron.daily内的脚本,这样只需我们按上述/etc/logrotate.d/example中的配置,即可保证每天日志的生成。

配置宿主机计划任务:以天为周期启动日志轮转工具logrotate工具(无守护进程),内容如下:

1
2
3
4
5
6
admin@host:~$ cat /etc/cron.daily/logrotate
#!/bin/sh

test -x /usr/sbin/logrotate || exit 0
/usr/sbin/logrotate /etc/logrotate.conf
admin@host:~$

1.4. logrotate 命令格式

1
logrotate [OPTION...] <configfile>

OPTION参数说明:

参数(简写) 参数(详细) 功能
-d --debug debug模式,测试配置文件是否有错误。
-f --force 强制转储文件。
-m --mail=command 压缩日志后,发送日志到指定邮箱。
-s --state=statefile 使用指定的状态文件。
-v --verbose 显示转储过程。

2. logrotate 轮转参数配置示例

示例配置文件(/etc/logrotate.d/log-file

1
2
3
4
5
6
7
8
9
10
11
12
/var/log/log-file {
monthly
rotate 5
compress
delaycompress
missingok
notifempty
create 644 root root
postrotate
/usr/bin/killall -HUP rsyslogd
endscript
}

轮转参数解释如下:

配置参数 说明
monthly 日志文件将按月轮转。其它可用值为'daily','weekly'或者'yearly'。
rotate 5 一次将存储5个归档日志。对于第六个归档,时间最久的归档将被删除。
compress 在轮转任务完成后,已轮转的归档将使用gzip进行压缩。
delaycompress 总是与compress选项一起用,delaycompress选项指示logrotate不要将最近的归档压缩,
压缩将在下一次轮转周期进行。这在你或任何软件仍然需要读取最新归档时很有用。
missingok 在日志轮转期间,任何错误将被忽略,例如“文件无法找到”之类的错误。
notifempty 如果日志文件为空,轮转不会进行。
create 644 root root 以指定的权限创建全新的日志文件,同时logrotate也会重命名原始日志文件。
postrotate/endscript 在所有其它指令完成后,postrotate和endscript里面指定的命令将被执行。
在这种情况下,rsyslogd 进程将立即再次读取其配置并继续运行。

其他参数说明:

配置参数 说明
nocompress 不压缩
copytruncate 用于还在打开中的日志文件,把当前日志备份并截断
nocopytruncate 备份日志文件但是不截断
create mode owner group 转储文件,使用指定的文件模式创建新的日志文件
nocreate 不建立新的日志文件
nodelaycompress 覆盖 delaycompress 选项,转储同时压缩。
nosharedscripts (默认项)对于每一个轮转的日志文件都执行prerotate和postrotate脚本。
errors address 专储时的错误信息发送到指定的Email 地址
ifempty 即使是空文件也转储,这个是 logrotate 的缺省选项。
mail address 把转储的日志文件发送到指定的E-mail 地址
nomail 转储时不发送日志文件
olddir directory 转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统
noolddir 转储后的日志文件和当前日志文件放在同一个目录下
prerotate/endscript 在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行
postrotate/endscript 该对字段间的脚本将在日志轮转结束后执行
firstaction/endscript 区间内的脚本在轮转之前、prerotate之前,且至少有一个待轮转日志时,才执行(限制:需要轮转的日志数必须大于1才执行;若此区间出错,将不会执行下方的脚本)
rotate count 指定日志文件删除之前转储的次数,0指没有备份,5指保留5个备份
tabooext [+] list 让logrotate不转储指定扩展名的文件,缺省的扩展名是:.rpm-orig, .rpmsave, v, 和 ~
size size 当日志文件到达指定的大小时才转储,bytes(缺省)及KB(sizek)或MB(sizem)

3. 项目中 logrotate 配置

3.1. logrotate 工具自身配置(宿主机,容器内无)

宿主机的 logrotate 工具自身配置文件/etc/logrotate.conf如下:

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
26
27
28
29
30
31
32
# see "man logrotate" for details
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# uncomment this if you want your log files compressed
#compress

# packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp, or btmp -- we'll rotate them here
/var/log/wtmp {
missingok
monthly
create 0664 root utmp
rotate 1
}

/var/log/btmp {
missingok
monthly
create 0660 root utmp
rotate 1
}

# system-specific logs may be configured here

3.2. 各需日志轮转文件的配置(宿主机中)

各需日志轮转文件的配置文件 /etc/logrotate.d/rsyslog 内容如下:

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# These logs should no longer get created. However, in case they do get created,
# we should keep them to a small size and rotate them also.

/var/log/auth.log
/var/log/cli.log
/var/log/debug
/var/log/telemetry.log
{
size 10M
rotate 1
missingok
notifempty
compress
sharedscripts
postrotate
/bin/kill -HUP $(cat /var/run/rsyslogd.pid)
endscript
}

/var/log/kern.log
/var/log/quagga/bgpd.log
/var/log/quagga/zebra.log
/var/log/syslog
/var/log/teamd.log
/var/log/user.log
{
size 100M
rotate 10
missingok
notifempty
compress
sharedscripts
postrotate
/bin/kill -HUP $(cat /var/run/rsyslogd.pid)
endscript
}

/var/log/cron.log
/var/log/daemon.log
/var/log/messages
{
size 200M
rotate 10
missingok
notifempty
compress
sharedscripts
firstaction
# Adjust NUM_LOGS_TO_ROTATE to reflect number of log files that trigger this block specified above
NUM_LOGS_TO_ROTATE=5

# Adjust LOG_FILE_ROTATE_SIZE_KB to reflect the "size" parameter specified above, in kB
LOG_FILE_ROTATE_SIZE_KB=204800

# Reserve space for btmp, wtmp, dpkg.log, monit.log, etc., as well as logs that
# should be disabled, just in case they get created and rotated
RESERVED_SPACE_KB=4096

VAR_LOG_SIZE_KB=$(df -k /var/log | sed -n 2p | awk '{ print $2 }')

# Limit usable space to 90% of the partition minus the reserved space for other logs
USABLE_SPACE_KB=$(( (VAR_LOG_SIZE_KB * 90 / 100) - RESERVED_SPACE_KB))

# Set our threshold so as to maintain enough space to write all logs from empty to full
# Most likely, some logs will have non-zero size when this is called, so this errs on the side
# of caution, giving us a bit of a cushion if a log grows quickly and passes its rotation size
THRESHOLD_KB=$((USABLE_SPACE_KB - (NUM_LOGS_TO_ROTATE * LOG_FILE_ROTATE_SIZE_KB * 2)))

# First, delete any *.1 or *.11~20.gz files that might be left around from a prior incomplete
find /var/log -type f | egrep '.+\.1?$|.+\.1[1-9]+\.gz?$|.+\.20+\.gz?$' | xargs rm -f

# logrotate execution, otherwise logrotate will fail to do its job
while true; do
USED_KB=$(du -s /var/log | awk '{ print $1; }')

if [ $USED_KB -lt $THRESHOLD_KB ]; then
break
else
OLDEST_ARCHIVE_FILE=$(find /var/log -type f -printf '%T+ %p\n' | grep -E '.+\.[0-9]+(\.gz)?$' | sort | head -n 1 | awk '{ print $2; }')

if [ -z "$OLDEST_ARCHIVE_FILE" ]; then
logger -p syslog.err -t "logrotate" "No archive file to delete -- potential for filling up /var/log partition!"
break
fi

logger -p syslog.info -t "logrotate" "Deleting archive file $OLDEST_ARCHIVE_FILE to free up space"
rm -rf "$OLDEST_ARCHIVE_FILE"
fi
done
endscript
postrotate
/bin/kill -HUP $(cat /var/run/rsyslogd.pid) 2>/dev/null || true
endscript
}

/var/log/swss/swss.rec
/var/log/swss/sairedis.rec
{
size 200M
rotate 10
missingok
notifempty
compress
sharedscripts
postrotate
pgrep -x orchagent | xargs /bin/kill -HUP 2>/dev/null || true
endscript
}

3.3. 各需日志轮转文件的配置(容器中)

容器各需日志轮转文件的配置文件 /etc/logrotate.d/rsyslog 内容如下:

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
26
27
28
29
30
31
32
33
34
35
36
37
/var/log/syslog
{
rotate 7
daily
missingok
notifempty
delaycompress
compress
postrotate
invoke-rc.d rsyslog rotate > /dev/null
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
invoke-rc.d rsyslog rotate > /dev/null
endscript
}

4. 容器中 supervisor 守护进程的配置文件(容器中,宿主机无)

配置文件:/etc/supervisor/conf.d/supervisord.conf

容器中,守护进程配置(各程序的kill重启策略)

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
root@host:/var# cat /etc/supervisor/conf.d/supervisord.conf
[supervisord]
logfile_maxbytes=1MB
logfile_backups=2
nodaemon=true

[eventlistener:supervisor-proc-exit-listener]
command=/usr/bin/supervisor-proc-exit-listener
events=PROCESS_STATE_EXITED
autostart=true
autorestart=unexpected

[program:start.sh]
command=/usr/bin/start.sh
priority=1
autostart=true
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog

[program:rsyslogd]
command=/usr/sbin/rsyslogd -n
priority=2
autostart=false
autorestart=unexpected
stdout_logfile=syslog
stderr_logfile=syslog

[program:syncd]
command=/usr/bin/syncd_start.sh
priority=3
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog

[program:ledinit]
command=/usr/bin/bcmcmd -t 60 "rcload /usr/share/host/platform/led_proc_init.soc"
priority=4
autostart=false
autorestart=false
startsecs=0
stdout_logfile=syslog
stderr_logfile=syslog

[program:linecardd]
command=/usr/bin/linecardd
priority=5
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog

[program:averagerated]
command=/usr/bin/averated
priority=6
autostart=true
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog

参考文档