当你想对一个应用程序跟踪使用状况或者进行故障排除的时候,日志是十分有用的。然而,随着越来越多的信息被记录,日志文件占据的硬盘空间也会越来越大。久而久之,一个日志文件能变得相当的大。一个巨大的日志文件不但会导致硬盘空间不足,还可能减慢对虚拟服务器调整大小或备份的过程。除此之外,你很难在一百万条日志中查找某个特定事件。因此,最好将日志文件的大小控制在可管理的范围内,并在日志文件过旧以致无法使用时对其进行删除。
所幸,logrotate 工具让日志轮换(log rotation)变得简单。“日志轮换”指的是归档应用程序的当前日志、启动新日志并删除旧日志的做法。系统通常每天运行一次 logrotate,并且在运行时会检查可以基于每个目录或日志进行自定义的规则。
logrotate 工作原理
系统按计划运行 logrotate,一般来说是每天。在大多数发行版中,每天运行 logrotate 的脚本位于 /etc/cron.daily/logrotate 中。也有一些发行版不太一样。比如,在 Gentoo 中,logrotate 脚本位于 /etc/cron.daily/logrotate.cron。如果你想更频繁地运行 logrotate(比如每小时),那你需要使用 cron 通过 /etc/cron.hourly 下的脚本运行 logrotate。当 logrotate 运行时,它将读取其配置文件,以确定需要轮换的日志文件位置、需要轮换的频率以及需要保留的归档日志的数量。
logrotate.conf
logrotate 的主要配置文件存放在 /etc/logrotate.conf。这个文件包含 logrotate 在轮换日志时使用的默认参数。这个文件包含注释,所以你可以浏览一下看看是如何配置的。本文稍后将描述该文件中的几个特定命令。注意文件有一行如下:
include /etc/logrotate.d
这个目录包含大多数特定应用程序(application-specific)的配置文件。
logrotate.d
使用以下命令列出包含特定应用程序日志配置的目录内容:
ls /etc/logrotate.d
这个目录下可能没有文件或者有多个文件,这取决于你的服务器安装了多少东西。一般来说,通过你的包管理器安装的应用程序会在 /etc/logrotate.d 中创建一个配置文件。通常,这个目录包含一个用于 syslog 服务的配置文件,这个文件会在 logrotate 轮换系统日志时读取。这个文件包含各种系统日志的条目,以及一些类似于 logrotate.conf 包含的命令。
注意:在 Karmic Koala(9.10)之前的 Ubuntu 操作系统版本中,没有用于 syslog 服务的条目。在该发行版之前,系统日志是通过从 /etc/cron.daily/sysklogd 脚本中运行的 savelog 命令来轮换的。
走进应用程序的配置文件
举个例子,考虑有这么个 logrotate 配置文件,它可能是当你在 Fedora 系统上安装 Apache 时放置的:
/var/log/httpd/*log {
missingok
notifempty
sharedscripts
postrotate
/sbin/service httpd reload > /dev/null 2>/dev/null || true
endscript
}
当 logrotate 运行时,它会检查 /var/log/httpd 下所有以 log 结尾的、不为空的文件并轮换它们。如果它在 httpd 目录下没有找到任何日志文件,它不会产生一个异常。接着它会执行 postrotate/endscript 块中的命令(在这个例子里,是一个通知 Apache 重启的命令),但只会在它处理完所有指定日志之后才会执行。
这个示例文件没有包含 logrotate.conf 文件中的某些配置。logrotate.conf 中的命令充当日志轮换的默认配置。当你想覆盖默认配置时,你可以为任意应用程序指定不同的。例如,当你有一个比较忙的 web 服务时,你可能想在 Apache 的配置块中引入 daily 命令,这样 Apache 的日志会按天轮换,而不是默认的按周轮换。
下一节将介绍一些在 logrotate 配置文件中实际执行的更常用的命令。
配置命令
你可以通过 man 手册查看 logrotate 配置文件使用的完整命令列表:
man logrotate
这一节介绍更常用的命令。
请记住,/etc/logrotate.d 中的应用程序配置文件从 /etc/logrotate.conf 文件中继承默认配置。
Log files
通过列出一个(或多个)日志文件,然后列出用大括号括起来的一组命令来定义日志文件及其轮换行为。大多数应用程序配置文件只包含这些块(block)之一,不过也可以在文件中放置多个块,或者把日志文件块放到 logrotate.conf 文件中去。
你可以通过在名称中使用通配符,或者使用空格分隔日志文件来在一个块中列出多个日志文件。例如,指定 /var/foo 下所有以 .log 结尾的文件以及 /var/bar/log.txt 文件,你可以如下设置这个块:
/var/foo/*.log /var/bar/log.txt {
rotate 14
daily
compress
delaycompress
sharedscripts
postrotate
/usr/sbin/apachectl graceful > /dev/null
Endscript
}
Rotate count
rotate 命令确定在 logrotate 开始删除较旧的日志之前,返回多少归档日志。例如:
rotate 4
这个命令告诉 logrotate 一次保留 4 个归档日志。当日志再次被轮换时,如果已经有 4 个归档日志了,最老的将被删除以给新的归档留出空间。
Rotation interval
你可以指定一个命令来告诉 logrotate 多久来轮换特定日志。合理的命令包括:
daily
weekly
monthly
yearly
如果没有指定轮换间隔,则日志在每次 logrotate 运行时都会被轮换(除非设置了比如 size 等其他命令)。
如果要使用除定义的时间间隔以外的时间间隔,则需要使用 cron 创建单独的配置文件。例如,如果你想每小时轮换特定的日志文件,你可以在 /etc/cron.hourly 下创建一个文件(你可能还需要创建这个目录),包含如下的一行内容:
/usr/sbin/logrotate /etc/logrotate.hourly.conf
然后,将需要每小时运行一次的 logrotate 配置(日志文件位置、是否要压缩旧文件等)放入 /etc/logrotate.hourly.conf 中。
Size
你可以使用 size 命令为 logrotate 指定文件大小,以便在确定是否执行轮换时进行检查。命令的格式告诉 logrotate 你用来指定大小的单位是什么:
size 100k
size 100M
size 100G
第一个示例将在日志大于 100KB 时轮换日志,第二个示例大于 100MB,第三个示例大于 100GB。我不建议使用 100G 的限制,提醒你一下,这个示例有些失控。如果同时设置了大小和轮换间隔,则 size 命令具有更高优先级并取代轮换间隔。
Compression
如果你想压缩归档的日志文件(使用 gzip 格式),你可以包含以下命令,这一般在 /etc/logrotate.conf 中有:
compress
压缩通常是一个好主意,因为日志文件通常是所有文本,而文本能很好地压缩。但是,如果你有一些不想压缩的归档日志,但你又希望默认情况下启用压缩,则可以在特定于应用程序的配置中包括以下命令:
nocompress
关于压缩的另一个需要注意的命令如下:
delaycompress
这个命令在你想压缩归档文件,但又想推迟压缩时很有用。当 delaycompress 开启时,归档日志会在日志下次轮换时被压缩。当你有一个程序,在轮换了新日志文件之后仍可能在一段时间内写入其旧日志文件时,这一点可能很重要。注意 delaycompress 只有在你配置了 compress 时才生效。一个很好的使用 delaycompress 的例子是,当 logrotate 被告知使用 “graceful” 或 “reload” 指令重启 Apache 时。因为旧的 Apache 进程直到连接完成才结束,所以它们可能会在重新启动后的一段时间内尝试将更多项记录到旧文件中。延迟压缩可确保在轮换日志时不会丢失这些额外的日志条目。
Postrotate
Logrotate 在每次轮换配置块中指定的日志时会执行 postrotate 脚本。通常,你希望在轮换日志后使用这个脚本重新启动应用程序,以便该应用程序可以切换到新日志。
postrotate
/usr/sbin/apachectl restart > /dev/null
endscript
> /dev/null
告知 logrotate 丢弃命令的输出。在这个例子里,你不需要查看应用程序重启成功的输出。
Sharedscripts
通常 logrotate 在每次轮换完一个日志后都会执行 postrotate 脚本。对于使用同一配置块的多个日志也是如此。举个例子,同时引用访问日志和错误日志的 Web 服务配置块,如果它两个都要轮换,将运行两次 postrotate 脚本(每次轮换文件时一次)。如果两个文件都轮换了,则 Web 服务将重新启动两次。为了防止logrotate为每个日志运行该脚本,可以包括以下命令:
sharedscripts
此命令告诉 logrotate 在运行 postrotate 脚本之前检查该配置块的所有日志。如果一个轮换或这两个都轮换了,则 postrotate 脚本仅运行一次。如果没有日志轮换,则后轮转脚本不会运行。
链接:https://juejin.cn/post/6870025365281046542