首页 » 运维 » 正文

logrotate 入门

Introduction简介

Logrotate 是一个用来管理日志文件的工具,可以帮我们自动压缩日志,清理日志,让我们的磁盘不至于爆满

一般情况下linux系统都预装了这个日志管理工具,如果是二般的情况就先手动安装一下吧

Logrotate Configuration 配置文件

Ubuntu下我们可以在如下两个地方找到所有的与logrotate相关的配置文件:

  • /etc/logrotate.conf:这个文件中包含了一些默认的配置,并且一半会include下边的路径下的所有的配置文件
  • /etc/logrotate.d/: 这个文件夹是所有我们的logrotated配置文件所在的位置,按照文件名进行区分,例如一半情况下会有如下文件bootlog  chrony  syslog  wpa_supplicant  yum.

默认情况下,logrotate.conf 回设定按照7天为周期的的配置,我们找一个系统自带的例子看一下配置文件的写法

  • cat /etc/logrotate.d/apt
Output

 

这个配置文件包含了两个模块,分别定义了/var/log/apt路径下两个日志文件的配置,两个配置文件参数完全相同,如果有一些参数我们没有指定,那么配置文件会自动继承/etc/logrotate.conf中的配置,我们详细看一下每一项:

  • rotate 12: 保留12个旧的文件
  • monthly: 每个月执行一次rotate操作
  • compress: 压缩我们的旧的日志文件,默认情况下会使用gzip压缩,当然也可以自己指定
  • missingok: 不输出错误日志
  • notifempty: 如果日志为空则不进行rotate操作

更多的参数设置可以参考 man logrotate

创建一个新的logrotate

如果我们想新增一个需要logrotate帮我们管理的日志文件我们有两个选资额:

  1. 在/etc/logrotate.d/目录下创建一个新的配置文件,默认情况下,logrotate会以root 的身份每天运行
  2. 如果我们不想使用系统自带的配置,例如我们不想使用root用户,或者我们不希望每天执行,我们想每个小时执行,我们需要额外创建新的配置文件及路径

我们详细的了解下两种方式的添加方式

使用 /etc/logrotate.d/

We want to configure log rotation for a fictional web server that puts an access.log and error.log into /var/log/example-app/. It runs as the www-data user and group.

如果我们想对一个路径/var/log/example-app/下的access.log(用户组为 www-data)进行管理

首先我们创建一个新的文件:

  • sudo nano /etc/logrotate.d/example-app

例子:

/etc/logrotate.d/example-app

 

几处特殊的地方:

  • create 0640 www-data www-data: 这行的意思是每次rotate完成以后会创建一个新的空的文件,并且用户组是我们想要的www-data
  • sharedscripts: 每个脚本只执行一次,无论我们上边的正则匹配几个日志文件(*.log),如果这个目录下有有两个匹配到的日志文件,我们不设置这个值,每个文件rotate完后都会触发一次下边的脚本
  • postrotate to endscript:  这段的脚本是每次rotate完后调用的脚本,例如,我们把旧文件rotate完并且创建了新的空的文件以后,我们需要重启服务让服务来写入新文件中,否则服务还是会写到旧文件中,这个问题设计的问题就不深入探讨了,注意一点,postrotate执行的时间是在压缩之前,因为压缩可能很耗费时间,我们需要我们的程序立刻切换写入的文件,如果你想在压缩完以后跑一些命令,可以使用lastaction模块

我们可以通过如下命令进行测试,不会真正的修改,只会模拟:

  • sudo logrotate /etc/logrotate.conf –debug

 

 设置一个特例的情况

假设我们有一个用户sammy 启动了一个app, 生成的日志都保存在/home/sammy/logs/文件夹下,我们想每个小时进行rotate,所以,我们需要/etc/logrotate.d意外的目录配置我们的需求

创建一个新的文件:

  • nano /home/sammy/logrotate.conf

文件内容:

/home/sammy/logrotate.conf

 

准备测试换件:

  • cd ~
  • mkdir logs
  • touch logs/access.log

这样我们有两个空的日志文件了

因为日志文件属于sammy,我们不需要sudo,但是我们确实需要指定一个状态文件,状态文件就是用来记录logrotate上一次都干了啥,这样logrotate就知道下次做什么了

我们可以执行如下命令

Output

--verbose 会打印详细的信息

如果我们查看一下状态文件,我们可以看一下状态文件的内容:

  • cat /home/sammy/logrotate-state
Output

剩下的我们就可以让crontab 来帮我们每个小时执行这个命令了:

  • crontab -e

 

强制执行的命令:

关于新的log文件的两种创建方式,可以参考https://jin-yang.github.io/post/logrotate-usage.html ,写的非常详细易懂

create

这也就是默认的方案,可以通过 create 命令配置文件的权限和属组设置;这个方案的思路是重命名原日志文件,创建新的日志文件。详细步骤如下:

  1. 重命名正在输出日志文件,因为重命名只修改目录以及文件的名称,而进程操作文件使用的是 inode,所以并不影响原程序继续输出日志。
  2. 创建新的日志文件,文件名和原日志文件一样,注意,此时只是文件名称一样,而 inode 编号不同,原程序输出的日志还是往原日志文件输出。
  3. 最后通过某些方式通知程序,重新打开日志文件;由于重新打开日志文件会用到文件路径而非 inode 编号,所以打开的是新的日志文件。

如上也就是 logrotate 的默认操作方式,也就是 mv+create 执行完之后,通知应用重新在新文件写入即可。mv+create 成本都比较低,几乎是原子操作,如果应用支持重新打开日志文件,如 syslog, nginx, mysql 等,那么这是最好的方式。

不过,有些程序并不支持这种方式,压根没有提供重新打开日志的接口;而如果重启应用程序,必然会降低可用性,为此引入了如下方式。

copytruncate

该方案是把正在输出的日志拷 (copy) 一份出来,再清空 (trucate) 原来的日志;详细步骤如下:

  1. 将当前正在输出的日志文件复制为目标文件,此时程序仍然将日志输出到原来文件中,此时,原文件名也没有变。
  2. 清空日志文件,原程序仍然还是输出到预案日志文件中,因为清空文件只把文件的内容删除了,而 inode 并没改变,后续日志的输出仍然写入该文件中。

如上所述,对于 copytruncate 也就是先复制一份文件,然后清空原有文件。

通常来说,清空操作比较快,但是如果日志文件太大,那么复制就会比较耗时,从而可能导致部分日志丢失。不过这种方式不需要应用程序的支持即可。

 

参考地址:

https://www.digitalocean.com/community/tutorials/how-to-manage-logfiles-with-logrotate-on-ubuntu-16-04

https://jin-yang.github.io/post/logrotate-usage.html

Zhiming Zhang

Senior devops at Appannie
一个奔跑在运维路上的胖子
Zhiming Zhang

Latest posts by Zhiming Zhang (see all)