使用Filebeat 5.6.4收集业务日志,配置文件比较简单:
filebeat.prospectors:
- input_type: log
paths:
- /path/logs/access.log
output.elasticsearch:
hosts: ["http://x.x.x.x:9200"]
index: "accesslog-%{+yyyy.MM.dd}"
其中,access.log是业务主日志,按天进行滚动,日志文件最大为128MB, 当天日志超出128MB后也进行滚动,最多保留15个日志文件;滚动后的日志文件会立即进行压缩。
启动filebeat后几个月过去了,发现filebeat目录下的data/registry文件容量越来越大。registry本身是用来记录日志文件的state信息,比如记录读取到文件位置的的offset,文件的inode、modify time等,通过查看registry文件内容看到,该文件中保存了从filebeat启动后的所有经过滚动并删除的日志文件的state信息,registry文件大小也到了几百KB,虽然看起来问题不大,但是越来越大的文件势必在每次更新时要消耗更多的系统资源,所以需要想办法优化,解决registry文件越来越大的问题。
通过查看filebeat 5.6.4文档看到,有两个参数clean_removed和clean_inactive可以清除掉registry文件中无用的state信息。
既然clean_removed参数是默认打开的,并且可以清除掉已经被删除文件的state信息,那为什么在上述场景下并没有生效呢?原因就是日志滚动时是先rename重命名了access.log文件为acess.log.1, 然后把acess.log.1文件压缩成了acess.log.1.gz之后再删除acess.log.1文件,也就是说并没有直接删除掉access.log文件,而clean_removed参数对重命名的文件是不起作用的,所以state信息没有被清除。
5.6版本中有关clean_removed参数的描述:
This setting does not apply to renamed files or
files that were moved to another directory that is still visible to Filebeat
但是这个问题已经在6.0之后的版本得到了修复,即使文件被重命名,在收集完该文件后后续state信息也会被清理。
6.0版本中有关clean_removed参数的描述:
When this option is enabled, Filebeat cleans files from the registry if they
cannot be found on disk anymore under the last known name. This means also files
which were renamed after the harvester was finished will be removed.
通过使用6.4.3版本的filebeat重新采集access.log日志,发现registry文件越来越大的问题已经得到了解决,所以最好的解决办法是把filebeat升级到6.4.3版本。
如果不能立即升级filebeat怎么办?那就可以通过配置ignore_older+clean_inactive参数解决问题.
解释一下ignore_older参数:
最终针对业务场景,新的基于5.6.4版本的filebeat的配置文件如下:
filebeat.prospectors:
- input_type: log
paths:
- /path/logs/access.log
ignore_older: 24h
clean_inactive: 36h
output.elasticsearch:
hosts: ["http://x.x.x.x:9200"]
index: "accesslog-%{+yyyy.MM.dd}"
因为日志文件是按天滚动的,ignore_older设置为24h,clean_inactive设置为36h,清理掉registry文件中距离最近一次更新超出36小时的日志文件的state信息.
根据上述配置,分别验证了两个场景,证明registry文件是可以正常清理旧的state,并且日志采集也不受影响:
这种场景下,因为日志文件一直没有更新,registry中始终记录的有日志文件的state信息,offset指向文件末尾。为什么日志文件的state信息一直没有被清理,因为更新registry文件是在读取文件之后进行的,filebeat每次扫描文件时发现文件没有被更新,就直接结束本次scan了。经过了十天半月,日志文件中产生了日志,此时会先根据registry中的state信息从文件末尾读取日志,不会从头开始读取,从而不会造成日志重复读取的情况。
这种场景下,每次滚动后新产生的日志文件被从头开始读取,旧的日志文件被重命名后即便被删除,因为filebeat此时并没有释放文件句柄,所以也可以被持续读取直至文件末尾。旧的日志文件的state信息在滚动发生后36h会被清理掉,从而避免了registry文件越来越大的情况发生。另外需要注意的是,这种场景下因为filebeat会占用已经删除文件的句柄直至文件读取完毕并且close_inactive到期,整个过程中磁盘资源是不会释放的,所以可以通过合理配置close_timeout参数及时释放掉文件句柄。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。