Ubuntu上使用Logrotate管理日志文件
一、前言
当我们使用Ubuntu服务器配置一些分析服务时,经常会用到日志去记录一些信息以便追溯分析过程。但是,时间久了之后,日志文件数量和空间会不断膨胀,这个时候我们就需要考虑如何去管理这些日志文件了。本文的主题便是讨论如何使用Logrotate管理日志文件。
二、Logrotate介绍
Logrotate是一个系统实用程序,用于管理日志文件的自动轮换和压缩。如果未对日志文件进行轮换,压缩和定期修剪,则最终可能会占用系统上的所有可用磁盘空间。
在Ubuntu 20.04上,Logrotate是默认安装的。设置为处理所有已安装软件包的日志轮换需求,包括rsyslog默认系统日志处理器。
通过询问其版本信息来确保安装Logrotate:
mulan@mulan-PowerEdge-R7525:~$ logrotate --version
logrotate 3.14.0
Default mail command: /usr/bin/mail
Default compress command: /bin/gzip
Default uncompress command: /bin/gunzip
Default compress extension: .gz
Default state file path: /var/lib/logrotate/status
ACL support: yes
SELinux support: yes
通过阅读其man页面,查看Logrotate的文档:
man logrotate
接下来我们将看看Logrotate在Ubuntu上的默认配置结构。
2.2 探索Logrotate配置
Logrotate的配置信息一般可以在Ubuntu的两个地方找到:
/etc/logrotate.conf:此文件包含一些默认设置,并为不属于任何系统软件包的几个日志设置轮换。它还使用include语句从/etc/logrotate.d目录中的任何文件中提取配置。/etc/logrotate.d/:这是您安装的需要日志轮换帮助的任何软件包将放置其Logrotate配置的位置。在一个标准的安装下,你应该已经在这里所拥有的文件进行系统的基本工具,如apt,dpkg,rsyslog等等。
默认情况下,logrotate.conf将配置每周日志轮换(weekly),其中包含root用户和syslog组(su root syslog)所拥有的日志文件,其中保留了四个日志文件(rotate 4),并且在轮换当前文件后创建了新的空日志文件(create) 。
我们来看看包中的Logrotate配置文件/etc/logrotate.d:
mulan@mulan-PowerEdge-R7525:~$ cat /etc/logrotate.d/apt
/var/log/apt/term.log {
rotate 12
monthly
compress
missingok
notifempty
}
/var/log/apt/history.log {
rotate 12
monthly
compress
missingok
notifempty
}
此文件包含/var/log/apt/目录中两个不同日志文件的配置块:term.log和history.log。他们都有相同的选择。未在这些配置块中设置的任何选项将继承默认值或设置的值/etc/logrotate.conf。为apt日志设置的选项是:
rotate 12:保留十二个旧日志文件。monthly:每月轮换一次。compress:压缩轮换的文件。默认使用gzip,导致文件以.gz。结尾。可以使用该compresscmd选项更改压缩命令。missingok:如果缺少日志文件,请不要写入错误消息。notifempty:如果日志文件为空,请不要轮换日志文件。
还有更多可用的配置选项。您可以通过在命令行上键入man logrotate 以查看Logrotate的手册页来阅读所有这些内容。
接下来,我们将设置一个配置文件来处理虚构服务的日志。
2.3 设置示例配置
要管理预打包和预配置系统服务之外的应用程序的日志文件,我们有两个选择:
- 创建一个新的Logrotate配置文件并将其放入
/etc/logrotate.d/。这将作为root用户以及所有其他标准Logrotate作业每天运行。 - 创建一个新的配置文件,并在Ubuntu的默认Logrotate设置之外运行它。如果您需要以非root用户身份运行Logrotate ,或者如果您希望每天更频繁地轮换日志(这样
hourly配置/etc/logrotate.d/是无效的,因为系统的Logrotate设置每天只运行一次),这才是真正必要的。
让我们通过一些示例设置来介绍这两个选项。
2.3.1 添加配置到 /etc/logrotate.d/
我们要配置日志轮换为把一个虚构的Web服务器access.log和error.log到/var/log/example-app/。它作为www-data用户和组运行。
要添加一些配置到/etc/logrotate.d/,先在那里打开一个新文件:
sudo nano /etc/logrotate.d/example-app
修改示例配置文件:
sudo vim /home/sammy/logrotate.conf
添加如下内容:
/var/log/example-app/*.log {
daily
missingok
rotate 14
compress
notifempty
create 0640 www-data www-data
sharedscripts
postrotate
systemctl reload example-app
endscript
}
此文件中的一些新配置指令是:
create 0640 www-data www-data:这将在轮换后创建一个新的空日志文件,具有指定的permissions(0640),owner(www-data)和group(alsowww-data)。sharedscripts:此标志表示添加到配置的任何脚本每次运行仅运行一次,而不是每个轮换的文件。由于此配置将匹配example-app目录中的两个日志文件,因此指定的脚本postrotate将在没有此选项的情况下运行两次。postrotatetoendscript:此块包含在日志文件轮换后运行的脚本。在这种情况下,我们正在重新加载我们的示例应用程序 有时需要将应用程序切换到新创建的日志文件。请注意,postrotate压缩日志之前的运行。压缩可能需要很长时间,您的软件应立即切换到新的日志文件。对于需要在压缩日志后运行的任务,请改用lastaction块。
在自定义配置以满足您的需求并将其保存后/etc/logrotate.d,您可以通过运行dry来测试它:
sudo logrotate /etc/logrotate.conf --debug
此调用将logrotate其指向标准配置文件,并打开调试模式。
将打印出有关Logrotate正在处理哪些日志文件以及它们将对它们执行的操作的信息。如果一切顺利,你就完成了。标准Logrotate作业将每天运行一次并包含新配置。
2.3.2 创建独立的Logrotate配置
在这个例子中,我们有一个应用程序作为我们的用户sammy在运行,生成存储在其中的日志/home/sammy/logs/中。我们希望每小时轮换这些日志,因此我们需要在/etc/logrotate.d Ubuntu提供的结构之外进行设置。
首先,我们将在主目录中创建配置文件。在文本编辑器中打开它:
sudo vim /home/sammy/logrotate.conf
添加以下内容:
/home/sammy/logs/*.log {
hourly
missingok
rotate 24
compress
create
}
保存并关闭文件。我们在之前的步骤中已经看到了所有这些选项,但让我们总结一下:此配置将每小时轮换文件,压缩并保留二十四个旧日志并创建一个新的日志文件来替换轮换的日志文件。
您需要自定义配置以适合您的应用程序,但这是一个良好的开端。
为了测试它的工作原理,让我们创建一个日志文件:
$ cd ~ $ mkdir logs $ touch logs/access.log
现在我们在正确的位置有一个空白的日志文件,让我们运行logrotate命令。
因为日志是由sammy拥有的,所以我们不需要使用sudo命令。我们确实需要指定一个状态文件。此文件记录logrotate上次运行时所看到和执行的操作,以便它知道下次运行时要执行的操作。在使用Ubuntu Logrotate设置时可以为我们处理(可以在以下处找到/var/lib/logrotate/status),但我们现在需要手动完成。
我们将Logrotate的状态文件放在我的主目录中,用于此示例。我可以去任何方便的地方:
logrotate /home/sammy/logrotate.conf --state /home/sammy/logrotate-state --verbose
reading config file /home/sammy/logrotate.conf Handling 1 logs rotating pattern: /home/sammy/logs/*.log hourly (24 rotations) empty log files are rotated, old logs are removed considering log /home/sammy/logs/access.log log does not need rotating
--verbose将打印出有关Logrotate正在做什么的详细信息。在这种情况下,看起来它没有轮换任何东西。这是Logrotate第一次看到这个日志文件,所以据他所知,该文件是零小时,不应该轮换。
如果我们查看状态文件,我们会看到Logrotate记录了一些有关运行的信息:
$ cat /home/sammy/logrotate-state
logrotate state -- version 2 "/home/sammy/logs/access.log" 2022-11-18-19:0:0
Logrotate注意到它看到的日志以及它最后一次考虑它们的轮换时间。如果我们在一小时后运行相同的命令,日志将按预期轮换。
如果要强制Logrotate轮换日志文件,否则不要使用该--force标志:
$ logrotate /home/sammy/logrotate.conf --state /home/sammy/logrotate-state --verbose --force
这在测试postrotate和其他脚本时很有用。
最后,我们需要设置一个cron作业来每小时运行一次Logrotate。打开用户的crontab:
$ crontab -e
这将打开一个文本文件。文件中可能已经有一些注释解释了预期的基本语法。将光标向下移动到文件末尾的新空行并添加以下内容:
14 * * * * /usr/sbin/logrotate /home/sammy/logrotate.conf --state /home/sammy/logrotate-state
此任务将在每天每小时的第14分钟运行。它基本上运行logrotate我们之前运行的相同命令,尽管我们扩展logrotate到了/usr/sbin/logrotate安全的完整路径。在编写cron作业时尽可能清晰点是一种好习惯。
保存文件并退出。这将安装crontab,我们的任务将按指定的时间表运行。
如果我们在大约一小时内重新访问我们的日志目录,我们应该找到轮换和压缩的日志文件access.log.1.gz(或者.2.gz,如果您使用的是--force标志运行Logrotate )。
2.4 配置实战
业务需求:将/home/mulan/MulanAlgo/analysis_service/logs/目录下的日志按天分割,并且删除30天前的日志文件。
步骤1.在/etc/logrotate.d目录下新建一个文件:
sudo vim /etc/logrotate.d/analysis_service
添加如下内容:
/home/mulan/MulanAlgo/analysis_service/logs/* {
daily
rotate 30
missingok
notifempty
copytruncate
dateext
olddir /home/mulan/MulanAlgo/analysis_service/old_logs
postrotate
find /home/mulan/MulanAlgo/analysis_service/old_logs -name "*.log" -type f -mtime +30 -exec rm -f {} \;
endscript
}
logrotate 的主要参数如下表:
参数 功能 compress 通过gzip 压缩转储以后的日志 nocompress 不需要压缩时,用这个参数 copytruncate 在创建副本后将原始日志文件截断为零大小,而不是移动旧的日志文件,并创建一个新的。 nocopytruncate 备份日志文件但是不截断 create mode owner group 转储文件,使用指定的文件模式创建新的日志文件 nocreate 不建立新的日志文件 delaycompress 和 compress 一起使用时,转储的日志文件到下一次转储时才压缩 nodelaycompress 覆盖 delaycompress 选项,转储同时压缩。 errors address 专储时的错误信息发送到指定的Email 地址 ifempty 即使是空文件也转储,这个是 logrotate 的缺省选项。 notifempty 如果是空文件的话,不转储 mail address 把转储的日志文件发送到指定的E-mail 地址 nomail 转储时不发送日志文件 olddir directory 转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统 noolddir 转储后的日志文件和当前日志文件放在同一个目录下 prerotate/endscript 在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行 postrotate/endscript 在转储以后需要执行的命令可以放入这个对,这两个关键字必须单独成行 daily 指定转储周期为每天 weekly 指定转储周期为每周 monthly 指定转储周期为每月 rotate count 指定日志文件删除之前转储的次数,0 指没有备份,5 指保留5 个备份 tabootext [+] list 让logrotate 不转储指定扩展名的文件,缺省的扩展名是:.rpm-orig, .rpmsave, v, 和 ~ size size 当日志文件到达指定的大小时才转储,Size 可以指定 bytes (缺省)以及KB (sizek)或者MB (sizem). missingok 如果日志文件丢失,则继续进行下一个日志文件,而不发出错误消息
步骤2.通过下面的命令来测试文件是否正确:
sudo logrotate -f /etc/logrotate.d/analysis_service
结果遇到错误:
error: skipping "/home/mulan/MulanAlgo/analysis_service/logs/XXX.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.
解决方案便是:在 logrotate 的配置中,指定用户和组,su root root
logrotate 完整配置如下:
/home/mulan/MulanAlgo/analysis_service/logs/* {
su root root
daily
rotate 30
missingok
notifempty
copytruncate
dateext
noolddir
postrotate
find /home/mulan/MulanAlgo/analysis_service/logs -name "*.log" -type f -mtime +30 -exec rm -f {} \;
endscript
}
其中,我们涉及到了find mtime参数+号,-号,不带符号的用法:
- atime是指access time,即文件被读取或者执行的时间,修改文件是不会改变access time的。
- ctime即change time文件状态改变时间,指文件的i结点被修改的时间,如通过chmod修改文件属性,ctime就会被修改。
- mtime即modify time,指文件内容被修改的时间。
find . –mtime n中的n指的是24*n, +n、-n、n分别表示:
- +n: 大于n
- -n: 小于n
- n:等于n
-exec rm -f {} \表示:
- -exec表示执行什么命令.后面跟要执行的命令.此处是rm -f,表示不确认删除.
- {} \;表示把查找到的结果发送到此来.
步骤3.我们需要设置一个cron作业来每天运行一次Logrotate。打开用户的crontab:
$ crontab -e

编辑内容:

步骤4.还需要重启cron来应用这个计划任务
mulan@mulan-PowerEdge-R7525:~$ service cron restart
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to restart 'cron.service'.
Authenticating as: mulan,,, (mulan)
Password:
==== AUTHENTICATION COMPLETE ===
mulan@mulan-PowerEdge-R7525:~$ service cron status
● cron.service - Regular background program processing daemon
Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2022-11-19 10:46:21 CST; 14s ago
Docs: man:cron(8)
Main PID: 38071 (cron)
Tasks: 1 (limit: 154127)
Memory: 432.0K
CGroup: /system.slice/cron.service
└─38071 /usr/sbin/cron -f
11月 19 10:46:21 mulan-PowerEdge-R7525 systemd[1]: Started Regular background program processing daemon.
11月 19 10:46:21 mulan-PowerEdge-R7525 cron[38071]: (CRON) INFO (pidfile fd = 3)
11月 19 10:46:21 mulan-PowerEdge-R7525 cron[38071]: (CRON) INFO (Skipping @reboot jobs -- not system startup)
mulan@mulan-PowerEdge-R7525:~$ sudo vim /etc/rsyslog.d/50-default.conf
取消注释
cron.* /var/log/cron.log
mulan@mulan-PowerEdge-R7525:~$ sudo vim /etc/rsyslog.d/50-default.conf
[sudo] password for mulan:
mulan@mulan-PowerEdge-R7525:~$ service rsyslog restart
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to restart 'rsyslog.service'.
Authenticating as: mulan,,, (mulan)
Password:
==== AUTHENTICATION COMPLETE ===
mulan@mulan-PowerEdge-R7525:~$ service rsyslog status
● rsyslog.service - System Logging Service
Loaded: loaded (/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2022-11-19 10:54:46 CST; 16s ago
TriggeredBy: ● syslog.socket
Docs: man:rsyslogd(8)
https://www.rsyslog.com/doc/
Main PID: 38113 (rsyslogd)
Tasks: 4 (limit: 154127)
Memory: 1.0M
CGroup: /system.slice/rsyslog.service
└─38113 /usr/sbin/rsyslogd -n -iNONE
11月 19 10:54:46 mulan-PowerEdge-R7525 systemd[1]: Starting System Logging Service...
11月 19 10:54:46 mulan-PowerEdge-R7525 rsyslogd[38113]: imuxsock: Acquired UNIX socket '/run/systemd/journal/syslog' (fd 3) from systemd. [v8.2001.0]
11月 19 10:54:46 mulan-PowerEdge-R7525 rsyslogd[38113]: rsyslogd's groupid changed to 110
11月 19 10:54:46 mulan-PowerEdge-R7525 systemd[1]: Started System Logging Service.
11月 19 10:54:46 mulan-PowerEdge-R7525 rsyslogd[38113]: rsyslogd's userid changed to 104
11月 19 10:54:46 mulan-PowerEdge-R7525 rsyslogd[38113]: [origin software="rsyslogd" swVersion="8.2001.0" x-pid="38113" x-info="https://www.rsyslog.com"] start
mulan@mulan-PowerEdge-R7525:~$ tail -f /var/log/cron.log
参考:
如何在Ubuntu 16.04上使用Logrotate管理日志文件

浙公网安备 33010602011771号