chaihongjun.me

使用logrotate切割inotify自定义监控日志文件

2019年写过一篇文章《inotify-tools工具inotifywatch实时监控网站目录》,当时为的是监控在敏感目录是否有木马文件生成,随着时间的推移,那篇文章介绍的监控方法会导致监控文件越来大,这样弊端是非常明显的,首先浪费的是服务器空间,在发现了木马文件之后第一时间处理完毕,监控日志基本就没必要保存之前的内容,另外,对于查询异常文件比较的麻烦,逐行读日志效率太低。于是想到能否像切割nginx的日志一样,每天切割,并且只保留最近5天记录的日志。

依稀记得oneinstack里面nginx的日志切割配置文件是/etc/logrotate.d/nginx,打开这个文件之后:

/data0/logs/*nginx.log {
  daily
  rotate 5
  missingok
  dateext
  compress
  notifempty
  sharedscripts
  postrotate
    [ -e /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
  endscript
}

简单分析一下,第一行是需要切割日志的路径,后面几行则是具体的配置,比如`daily`每天切割,`rotate 5`应该是轮询5天

也就是5天一个循环。

而 [ -e /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid

则是判断nginx是否正在运行,并且执行关闭并再次启动正在运行的nginx,这里有一个关闭并且再次打开的过程。

根据上面的简单分析,我们也可以依样画葫芦给出监控日志的切割配置写法:(/etc/logrotate.d/monitor),这里的配置文件名(monitor)可以随意命名

/data/logs/monitor.log {  # 监控文件
  daily
  rotate 5
  missingok
  dateext
  compress
  notifempty
  sharedscripts
  postrotate
  
  PIDS=`ps -ef |grep inotifywait |grep -v grep | awk '{print $2}'`   # 查询进程 inotifywait 的ID
  if [ "$PIDS" != "" ]; then   # 如果 inotifywait 存在
      kill -9 $PIDS            # 则关闭 inotifywait
     /bin/sh /root/monitor.sh &  # 再次在后台启动  inotifywait
  fi
  endscript

说明一下,monitor.sh里面是监控命令和参数,可以参看之前的文章,另外涉及的文件及其路径,请依据实际情况调整修改。

以上配置写完了之后,记得重启服务器或者logrotate服务

#centos 6
service rsyslog restart
#centos 7
systemctl restart rsyslog

20211215 更新

以上的配置,会把几天之前的日志打包成gz压缩包格式,虽然方便存储,节省了服务器的存储空间,但是却不便于直接在线查询日志内容,可以稍微改动一下:

/data/wwwlogs/monitor.log {
  daily
  rotate 5
  missingok
  dateext
  notifempty
  create 644 www www  
  sharedscripts
  postrotate
  PIDS=`ps -ef |grep inotifywait |grep -v grep | awk '{print $2}'`
  if [ "$PIDS" != "" ]; then
      kill -9 $PIDS
     /bin/sh /root/monitor.sh &
  fi
  # 添加下面一行,将生成的monitor.log-xxxxxx格式的日志文件添加一个.log的后缀
  # 这样可以在浏览器直接浏览,无需下载再解压
  find /data/wwwlogs/  -name "monitor.log-*" | xargs  -t  -i mv  {} {}.log
  endscript
}

注意:上面的/data/wwwlogs/ 是监控日志存放的路径

20211216 更新

上次的跟新有个BUG,随着时间的推移,生成的文件可能会出现多个.log的后缀,形如monitor.log-20211215.log.log,时间越久远,早先的日志文件后缀.log就会愈多,因此修改一下查找日志文件的逻辑,最后完整的脚本应该是这样的:

/data/wwwlogs/monitor.log {
  daily
  rotate 5
  missingok
  dateext
  notifempty
  create 644 www www  
  sharedscripts
  postrotate
  PIDS=`ps -ef |grep inotifywait |grep -v grep | awk '{print $2}'`
  if [ "$PIDS" != "" ]; then
      kill -9 $PIDS
     /bin/sh /root/monitor.sh &
  fi
  # 添加下面一行,将生成的monitor.log-xxxxxx格式的日志文件添加一个.log的后缀
  # 这样可以在浏览器直接浏览,无需下载再解压
  
  # 修改了查找日志文件的逻辑,匹配更精准
  find /data/wwwlogs/ -type f -regextype 'posix-egrep' -regex '/data/wwwlogs/monitor.log-[0-9]{8}$'| xargs -t -i mv {} {}.log
  endscript
}


知识共享许可协议本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。作者:chaihongjun»