如何在Ubuntu 18.04上使用Logrotate设置日志轮换

时间:2020-03-05 15:31:14  来源:igfitidea点击:

日志文件旨在在一段合理的时间内保留有关系统活动的信息,但是系统日志记录守护程序无法提供控制日志文件大小的方法。
因此,如果不进行检查,日志文件可能会增长以占用它们所驻留的所有可用分区空间。
为防止日志文件完全填满系统,可以旋转日志消息,这意味着达到特定阈值时,将关闭旧日志文件,并打开一个新日志文件。

其中将介绍如何在Ubuntu 18.04上使用logrotate旋转日志文件。

什么是日志轮转?

日志轮转是通过定期存档当前日志文件并启动一个新文件来解决这些问题的过程。
它重命名并选择压缩当前日志文件,删除旧日志文件,并强制日志系统开始使用新日志文件。
它通常通过cron实用程序自动运行。
通过日志轮转,我们可以

  • 按计划(例如每天,每周或者每月)启动新的日志文件
  • 压缩旧的日志文件以节省磁盘空间
  • 修剪旧档案,以便仅保留一定数量的旧日志。
  • 使用日期戳将旧日志文件重命名,以便我们知道在何处查找较旧的日志。
  • 在轮换一组日志之前或者之后运行命令。

我们可以将日志轮换视为重命名当前日志文件并为新日志条目设置新日志文件的过程。
轮换日志文件时,通常会将旧的日志文件复制到其中具有轮换日期的文件中。

1)logrotate的配置文件

在Ubuntu 18.04上,logrotate的配置文件是'/etc/logrotate.conf',以及'/etc/logrotate.d'中的任何文件。
logrotate.conf主文件指定了所有默认设置和要轮换的系统文件。
该文件包含一些选项,注释对此做了很好的解释。

cat /etc/logrotate.conf 
# see "man logrotate" for details
# rotate log files weekly
weekly
# use the syslog group by default, since this is the owning group
# of /var/log/syslog.
su root syslog
# 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 Jan be configured here

logrotate的主要选项是:

  • weekly:每周轮播一次日志文件
  • su root syslog:将使用特定用户(root)和组(syslog)归档日志,以防止权限问题
  • rotate 4确保已保存文件的四个旧版本。在删除给定日志之前,请先对其旋转四次,这样可以使四个星期的日志保持在线状态。
  • create:旧文件以新名称保存并创建新文件
  • compress:compress导致logrotate压缩日志文件以节省空间。默认情况下,这是使用gzip完成的,但是我们可以指定其他程序
  • include:此重要选项可确保包含目录“ /etc/logrotate.d”的内容。在此目录中,存在指定如何处理某些单个日志文件的文件。

“ /etc/logrotate.d”中的每个文件用于添加其他设置或者覆盖特定文件的默认设置。
该文件夹还包含我们需要日志轮换安装的所有软件包的logrotate配置。

# ls -l /etc/logrotate.d
total 40
-rw-r--r-- 1 root root 120 Nov 2 2016 alternatives
-rw-r--r-- 1 root root 442 Oct 23 2016 apache2
-rw-r--r-- 1 root root 126 Nov 20 16:39 apport
-rw-r--r-- 1 root root 173 Apr 20 10:08 apt
-rw-r--r-- 1 root root 112 Nov 2 2016 dpkg
-rw-r--r-- 1 root root 146 Apr 17 17:35 lxd
-rw-r--r-- 1 root root 845 Jan 12 10:57 mysql-server
-rw-r--r-- 1 root root 501 Jan 14 16:19 rsyslog
-rw-r--r-- 1 root root 178 Aug 15 2016 ufw
-rw-r--r-- 1 root root 235 Apr 17 14:53 unattended-upgrades

我们可以查看例如apache Web服务器的logrotate配置

# cat /etc/logrotate.d/apache2 
/var/log/apache2/*.log {
	daily
	missingok
	rotate 14
	compress
	delaycompress
	notifempty
	create 640 root adm
	sharedscripts
	postrotate
                if invoke-rc.d apache2 status > /dev/null 2>&1; then \
                    invoke-rc.d apache2 reload > /dev/null 2>&1; \
                fi;
	endscript
	prerotate
		if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
			run-parts /etc/logrotate.d/httpd-prerotate; \
		fi; \
	endscript
}

Logrotate包含一些其他选项,我们可以在上面看到:

  • 每天:在基准日轮换记录
  • missingok:如果缺少日志,则不会引发错误
  • delaycompress:在文件旋转之前不要对其进行压缩。如果守护程序没有立即关闭日志文件,这是为了防止损坏。
  • notifyempty:日志文件为空时不要旋转
  • 创建640个root adm:这将创建具有设置的权限,所有者和组的新日志文件
  • sharedscripts:如果通配符匹配多个文件,则对所有文件运行一次任何脚本
  • postrotate/endscript:指定一些命令或者脚本,这些命令或者脚本应在日志旋转后执行,直到endscript关键字为止。
  • prerotate/endscript:作为postrotate/endscript,它指定在日志轮换开始之前应执行的命令或者脚本。

我们可以通过使用手册获得有关其他选项的一些信息。

man logrotate

2)使用logrotate配置日志轮换

logrotate命令通常以循环方式重命名(或者旋转)日志文件。
日志文件将被重命名为包含数字或者日期扩展名,并且将创建一个新的日志文件以接受系统信息。
如果将logrotate配置为仅保留旧日志文件的两个副本,则在轮流进行两次日志之后,将自动删除最旧的日志文件。

通常,在默认情况下,Ubuntu 18.04上默认安装了logrotate命令,我们可以检查以下版本

# logrotate --version
logrotate 3.11.0

默认情况下,logrotate通过执行shell脚本'/etc/cron.daily/logrotate'每天运行。
我们将看到其他cron文件不包含任何logrotate文件。

cat /etc/cron.daily/logrotate 
#!/bin/sh
# 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

我们可以看到如果使用命令的-d参数执行应用程序的logrotate配置,它将执行什么操作

# logrotate -d /etc/logrotate.d/mysql-server 
reading config file /etc/logrotate.d/mysql-server
Reading state from file: /var/lib/logrotate/status
Allocating hash table for state file, size 64 entries
Handling 1 logs
rotating pattern: /var/log/mysql.log /var/log/mysql/*log  after 1 days (7 rotations)
empty log files are rotated, old logs are removed
considering log /var/log/mysql.log
error: skipping "/var/log/mysql.log" because parent directory has insecure permissions (It's world writable or writable by group which is not "root") Set "su" directive in config file to tell logrotate which user/group should be used for rotation.
Creating new state
considering log /var/log/mysql/error.log
Creating new state
  Now: 2016-05-22 06:02
  Last rotated at 2016-05-22 06:00
  log does not need rotating (log has been already rotated)

我们可以将日志轮换配置为root用户和非root用户。

a)为已安装的服务器软件包设置logrotation

每天都会在'/etc/logrotate.d'文件夹中以root用户身份创建Logrotate配置文件。
例如,我们将为监视工具主管配置日志轮换。

首先,我们将创建日志轮换文件,在该文件上将指示用于存储日志的配置文件

# vim /etc/logrotate.d/supervisor
/var/log/supervisor/superviz.log {
        daily
        create 0640 root root
        missingok
        dateext
        rotate 3
        size=1M
        notifempty
        sharedscripts
        mail [email protected]
}

让我们解释一些选项:

  • dateext:使用日期作为日志文件旧版本的扩展名
  • size:记录大于此处指定大小的文件
  • 邮件:指示logrotate在覆盖之前将其内容通过电子邮件发送到指定地址。我们必须有一个邮件服务器正常工作

现在,我们可以通过在调试模式下调用logrotate来测试配置,该模式指向包含我们文件夹的主配置。
该命令将显示一些信息,但我们只会对有关我们的配置的信息进行排序

# logrotate /etc/logrotate.conf --debug
reading config file /etc/logrotate.conf
including /etc/logrotate.d
reading config file alternatives
reading config file apache2
reading config file apport
reading config file apt
reading config file dpkg
reading config file lxd
reading config file mysql-server
reading config file rsyslog
reading config file supervisor
reading config file ufw
reading config file unattended-upgrades
Reading state from file: /var/lib/logrotate/status
...
...
rotating pattern: /var/log/supervisor/supervisord.log  1048576 bytes (3 rotations)
empty log files are not rotated, old logs mailed to [email protected]
switching euid to 0 and egid to 106
considering log /var/log/supervisor/supervisord.log
Creating new state
  Now: 2016-05-22 08:16
  Last rotated at 2016-05-22 08:00
  log does not need rotating (log size is below the 'size' threshold)
switching euid to 0 and egid to 0
....
....

我们可以看到我们的配置还不需要旋转。
这是因为条件大小尚未验证。
该命令一旦运行就没有任何错误,这意味着配置看起来不错。

b)设置自定义应用程序的日志轮换

我们可以为生成日志并以非root用户身份运行的自定义应用程序配置日志轮转。
默认情况下,logrotate每天运行一次,因此,如果我们需要每小时运行一次应用程序,则将在默认文件夹之外创建logrotate配置。

让我们举一个例子,为不和谐配置日志轮换。

我们将创建一个个人文件夹,其中将包含主要logrotate配置文件和一个用于日志文件的文件夹。
此应用程序不了解日志轮换,因此logrotate将通过使用copy和truncate实现来解决此问题。

$vim apps/logrotate.conf
/home/alain/apps/logs/discord.log {
        hourly
        copytruncate
        missingok
        dateext
        rotate 10
        compress
}

我们使用了新选项copytruncate,该选项在创建副本后将旧日志文件截断到位,而不是移动旧文件并创建一个新文件。
这对于无法告知其关闭日志文件的服务很有用。

我们可以测试我们的配置,但是我们需要指定一个状态文件。
该文件记录了logrotate看到的内容以及上次运行时执行的操作,以便它知道下次运行时该怎么做。
请注意,我们以非root用户身份运行命令

$logrotate /home/alain/apps/logrotate.conf --state /home/alain/apps/logrotate-state --verbose
reading config file /home/alain/apps/logrotate.conf
Reading state from file: /home/alain/apps/logrotate-state
Allocating hash table for state file, size 64 entries
Handling 1 logs
rotating pattern: /home/alain/apps/logs/discord.log  hourly (10 rotations)
empty log files are rotated, old logs are removed
considering log /home/alain/apps/logs/discord.log
Creating new state
  Now: 2016-05-22 10:09
  Last rotated at 2016-05-22 10:00
  log does not need rotating (log has been already rotated)

如果我们在几个小时后尝试使用同一命令,则会在输出中看到一些其他信息,例如截断和压缩信息

logrotate /home/alain/apps/logrotate.conf --state /home/alain/apps/logrotate-state --verbose
reading config file /home/alain/apps/logrotate.conf
Reading state from file: /home/alain/apps/logrotate-state
Allocating hash table for state file, size 64 entries
Creating new state
Handling 1 logs
rotating pattern: /home/alain/apps/logs/discord.log  hourly (10 rotations)
empty log files are rotated, old logs mailed to [email protected]
considering log /home/alain/apps/logs/discord.log
  Now: 2016-05-22 22:52
  Last rotated at 2016-05-22 10:23
  log needs rotating
rotating log /home/alain/apps/logs/discord.log, log->rotateCount is 10
dateext suffix '-2016052222'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
copying /home/alain/apps/logs/discord.log to /home/alain/apps/logs/discord.log-2016052222
truncating /home/alain/apps/logs/discord.log
compressing log with: /bin/gzip

我们必须保留logrotate配置是由与日志文件匹配的文件组定义的,然后是大括号内的一系列指令。
如果未在日志文件名称所附的节中指定选项,则以“ /etc/logrotate.conf”中的顶级选项为准。
已轮换的日志文件不会存储在任何地方;它们只是消失了,所以我们应该考虑采取措施。