设置只保留最近七天的日志


学好排除问题的方法,有助于提高生产力。

设置只保留最近七天的日志


1. 问题描述

日志轮转还是非常重要的,不清理容易磁盘满,清理多的话不容易溯源!

早上一同事收到一线反馈说,几台刚上没多久的服务器的磁盘打满了。上去看了一下,果然是日志文件太多而且没有及时清理导致的。本来是可以通过服务自己提供的配置文件进行配置,保留多少个日志文件的。但是因为需要对日志名称定制化导致配置失效,而且现在有需要紧急进行处理。

考虑到这里问题,我第一个想到的就是直接配置一个 crontab 的定时任务,对该服务所产生的日志只保留最近七天的日志就可以了。本来说可以写一个 ShellPython` 脚本,从而精确的对日志时间进行删除,但是要的比较急,所有先处理掉线上的问题,之后再整改。将定时任务,改为一个可扩展的日志处理工具。其实,最好的方式还是通过服务自己的配置文件进行配置,方便管理和使用。


2. 定时任务

可以通过 crontab 定时执行实现日志切割功能

定时任务 crontab 的执行脚本

  • 脚本路径:/var/spool/cron/目录下
  • 注意事项:建议日常备份,避免误删除导致crontab文件丢失

定时任务的日志文件

  • 日志文件路径:/var/log/cron
  • 正确打开方式:tail -f /var/log/cron

额外配置定时任务日志

  • 原本定时任务的日志功能就是由rsyslog提供的,没有则需自行配置
  • vim /etc/rsyslog.conf
  • cron.* /var/log/cron.log

定时任务 crontab 的启停

# 通过脚本启停
[root@node1 ~]# /etc/init.d/crond start
[root@node1 ~]# /etc/init.d/crond stop

# 通过service启停
[root@node1 ~]# service crond start
[root@node1 ~]# service crond stop

3. 核心难点

难点就在于 find 命令查找所需要筛选的时间范围!

通过定时任务的方式配置来处理日志的定时删除工作,就需要熟悉文件的三个属性,分别为:

  • atime(access time)
    • 访问时间 => 文件被访问过
  • mtime(modify time)
    • 修改时间 => 文件内容有修改
  • ctime(change time)
    • 改变时间 => 文件的属性及索引节点发生变化

如果使用vivim去编辑文件的话,可能会发现三个时间戳都发生了变化。因为vivim使用了临时文件保存修改,在wq时替换了原来的文件,导致文件的inode被改变了,可以通过ls -i进行验证。

值得注意的是,对于atime来说,当我们使用cat命令查看文件之后想要看到atime的改变,但可能会让你很失望,因为atimemount的参数以及内核的设置有关。

# atime
Do not use noatime feature, then the inode access time is controlled by kernel defaults. See also the description for strictatime and relatime mount options.
# noatime
Do not update inode access times on this filesystem(eg, for faster access on the news spool to speed up news servers).

# relatime
Update inode access times relative to modify or change time.Access time is only updated if the previous access time was earlier than the current modify or change time.(Similar to noatime, but doesn't break mutt or other applications that need to know if a file has been read since the last time it was modified.)
Since Linux 2.6.30, the kernel defaults to the behavior provided by this option(unless noatime was specified), and the  strictatime option is required to obtain traditional semantics. In addition, since Linux 2.6.30, the file's last access time is always updated if it is more than 1 day old.

# norelatime
Do not use relatime feature. See also the strictatime mount option.

# strictatime
Allows to explicitly requesting full atime updates. This makes it possible for kernel to defaults to relatime or noatime but still allow userspace to override it. <span style="color:#ff0000;">For more details about the default  system mount options see /proc/mounts</span>.

# nostrictatime
Use the kernel's default behaviour for inode access time updates.

我这里简单的进行一下梳理:

  • noatime
    • 即使修改了文件内容,atime也不会发生改变,性能最好。
  • atime
    • 采用内核的默认行为,内核2.6.30之后相当于relatime
  • strictatime
    • 每次文件被读取的时候,atime都会发生改变。每次读取都会更新,但是影响性能。
  • relatime
    • atimectimemtime更早,然后你又去读取了文件,atime才会被更新为当前时间。或者atime比现在早一天,那么atime在文件读取时会被更新。性能和atime折中的选择。
[root@node1 nextlogfiles]# cat /proc/mounts
rootfs / rootfs rw 0 0
proc /proc proc rw,relatime 0 0
sysfs /sys sysfs rw,seclabel,relatime 0 0
devtmpfs /dev devtmpfs rw,seclabel,relatime,size=486908k,nr_inodes=121727,mode=755 0 0
devpts /dev/pts devpts rw,seclabel,relatime,gid=5,mode=620,ptmxmode=000 0 0
tmpfs /dev/shm tmpfs rw,seclabel,relatime 0 0
/dev/sda2 / ext4 rw,seclabel,relatime,barrier=1,data=ordered 0 0
none /selinux selinuxfs rw,relatime 0 0
devtmpfs /dev devtmpfs rw,seclabel,relatime,size=486908k,nr_inodes=121727,mode=755 0 0
/proc/bus/usb /proc/bus/usb usbfs rw,relatime 0 0
/dev/sda1 /boot ext4 rw,seclabel,relatime,barrier=1,data=ordered 0 0

理解了这些东西,如果在我们没有改变挂载方式的前提下,最合理的选择就是使用mtime进行时间的判断。下面就是得到的crontab定时任务的脚本。

[root@node1 ~]# crontab -e
10 0 * * * find /opt/xxx/logs -type f -mtime +7 -exec rm -rf {} \;

文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !
  目录