我们的日志收集系统使用Filebeat来收集日志文件,部署时并没有多想,只配置了一下监控的日志文件名。后来想想其实这里面有很多点需要考虑的

我们试想一下,我们既然使用filebeat收集日志并发送到logstash,那么我们就相当于有两台服务器存在相同日志,那这样我们为了节省磁盘空间就要删除一台服务器上的日志,假如我要删除原日志,那么问题来了,我如果直接操作原文件把读取过的内容删除不就可以了吗?太天真了。
首先,我怎么确定日志读取到了多少字节,当然这个可以通过查看filebeat日志来确定,但是你要怎么截取呢难不成一条日志你拆成两条?这显然行不通
但是我们有一种办法可以轻松做到删除读取过的日志并且保证filebeat正常收集
首先我们要确定filebeat是根据inode读取日志的
那这样我们就可以做日志滚动,因为日志日志滚动的过程其实就是
mv 1.log 1.log.1
touch 1.log
滚动日志请参考本人另外一篇博客
滚动切割日志 这样按照规定时间更改文件名并创建新文件的过程,因为更改文件名不会更改inode,所以filebeat可以完整的收集到所有日志
那么还有一个问题就是,我们滚动出来的日志文件的句柄一直没有释放,要怎么释放呢?还有filebeat是怎么发现是否有新文件产生的呢

实际上,filebeat是通过close_inactive和scan_frequency两个参数(机制)来应对这种情况的:

close_inactive
该参数指定当被监控的文件多长时间没有变化后就关闭文件句柄(file handle)。官方建议将这个参数设置为一个比文件最大更新间隔大的值。比如文件最长5s更新一次,那就设置成1min。默认值为5min.

scan_frequency
该参数指定Filebeat搜索新文件的频率(时间间隔)。当发现新的文件被创建时, Filebeat会为它再启动一个 harvester 进行监控。默认为10s。

综合以上两个机制,当完成日志切割后(即重命名),此时老的harvester仍然在监控重命名后的日志文件,但是由于该文件不会再更新,因此会在close_inactive时间后关闭这个文件的 harvester。当scan_frequency时间过后,Filebeat会发现目录中出现了新文件,于是为该文件启动 harvester 进行监控。这样就保证了切割日志时也能不丢不重的传输数据。