Filebeat工作原理

反思

先上官网链接 How Filebeat Works
首先感谢filebeat的默认配置很给力,我们的日志收集系统使用Filebeat来收集日志文件,部署时并没有多想,只配置了一下监控的日志文件名。上线测试,日志采集这块从没出过问题。自己就没有深入考虑过Filebeat工作原理,只知道filebeat是根据文件系统文件名关联到inode信息,根据inode信息进行日志文件的监听的。并没有深入的结合配置及filebeat原理深入思考过Filebeat。

1 How Filebeat Works

Filebeat由两个主要组件组成:input 组件和文件监听器(harvester,下文都用"harvester"代替)。这俩组件一起工作以跟踪文件并将事件数据发送到指定的输出模块。
下面我们来介绍一下input 和 harvester两个模块的作用、生命周期、和原理进行描述:

1.1 harvester 简介和生命周期

harvester负责读取单个文件的内容。harvester逐行读取每个文件,并将内容发送到输出模块。每个文件启动一个harvester线程。harvester负责打开和关闭文件,这意味着file descriptor在harvester运行时保持打开状态。如果在获取文件时删除或重命名该文件,Filebeat将继续读取该文件。这样做的影响是,在harvester关闭之前,磁盘上的空间将被保留。默认情况下,Filebeat会保持文件打开状态,直到到达close_inactive。

应用 harvester 日志文件 inode info registry文件 输出模块 创建 写 scan relate inode 返回inode信息 返回日志事件 relate inode 重命名 loop [ 监听日志文件变化 ] 如果原有的inode 对应的文件没有读 取完成或没有完成 达到close_inactive 的阈值,那么将会 保持监听 发送日志事件 ack 记录状态 应用 harvester 日志文件 inode info registry文件 输出模块

关闭harvester有以下影响:

  • 文件句柄被关闭,如果文件在harvester仍在读取文件时被删除,则会释放基础资源。
  • 只有通过scan重新开始获取文件,scan操作的频率根据scan_frequency配置的值。
  • 如果在harvester关闭时移动或移除文件,则不会继续监听文件。

想要控制harvester的关闭请使用close_*相关配置

1.2 input 简介及配置

input负责管理harvester,并查找所有要读取的文件。
如果输入类型是log,则input将查找驱动器上与定义的glob路径匹配的所有文件,并为每个文件启动一个harvester。每个input都在自己的Go routine中运行。下面是配置的例子

filebeat.inputs:
- type: log
  paths:
    - /var/log/*.log
    - /var/path2/*.log

Filebeat当前支持多种input类型( 输入类型配置文档请点击链接)。每个input类型可以定义多次。当input类型为log时,filebeat会根据配置的路径检查每个文件,来判断是否需要启动harvester、是否已经有harvester在监听文件或是否可以忽略该文件(ignore_older配置详见)。在harvester关闭后,只有文件大小发生变化时,才会重新创建harvester监听新的数据。

1.3 Filebeat记录文件状态

Filebeat保存每个文件的状态,并经常将文件状态刷新到磁盘中的registry文件中(7.*以后版本的registry文件路径:./data/registry/filebeat/data.json)。该状态用于记录harvester读取文件的最后一个偏移量,并确保发送所有日志行。如果无法访问输出模块(如Elasticsearch或Logstash等),Filebeat将跟踪最后发送的偏移量,并在输出模块再次可用时继续读取文件。当Filebeat运行时,状态信息也保存在每个输入的内存中。当Filebeat重新启动时,使用registry文件来重建状态,Filebeat根据registry文件中的记录来恢复harvester。
对于每个输入,Filebeat都会保留它找到的每个文件的状态。由于文件可以重命名或移动,文件名和路径不足以标识文件。对于每个文件,Filebeat存储唯一的标识符,以检测文件是否以前被捕获。
如果每天创建大量新日志文件,您可能会发现registry文件变得太大,可以参考通过clean_*配置减少registry文件大小相关内容。

1.4 Filebeat如何保证消息最少发送一次(at-least-once 特性)

Filebeat保证日志事件将至少传递一次到配置的输出,并且不会丢失数据(个人理解不能完全保证详见2.1)。因为它将每个事件的传递状态存储在registry文件中(上述流程图中有描述)。在已定义的输出被阻止且未确认所有事件的情况下,Filebeat将继续尝试发送事件,直到输出模块确认已接收到事件为止。
如果Filebeat在发送事件的过程中关闭,它不会等待输出确认所有事件后再关闭。当Filebeat重新启动时,将再次发送关闭前未确认的所有事件到输出模块。这样可以确保每个事件至少发送一次,但未确认的事件就可能成为重复事件,故只能保证至少传递一次。通过设置shutdown_timeout选项,可以将Filebeat配置为在结束进程前等待特定时间,来尽可能地多的收到确认消息。

2 Filebeat异常场景及应对办法

2.1 文件滚动时异常中断

问题描述:
通过阅读官方文档,以及自己的使用,个人认为filebeat并不能保证消息的at-least-once 特性,因为filebeat的input会在根据scan_frequency来扫描文件,如果日志滚动过于频繁且小于scan_frequency的时间就会发生滚动,这样就有可能出现个别文件不能被Filebeat的input模块扫描到,导致数据丢失,当然这种情况出现的概率极低,因为一般很少有系统的日志会在几秒内频繁滚动。
应对办法:
这种情况的出现我们需要调整两个地方:

  1. 日志滚动策略,降低日志滚动频率
  2. 减小scan_frequency的值,最小不能小于1s

2.2 日志文件滑动策略与大量日志文件产生导致registry文件过大

问题描述:
首先解释下日志文件滑动生成策略,单个日志文件达到某种阈值(时间或容量),就会将生成一个新的文件名继续记录,而滚动生成就是将这个日志文件重命名,新的日志仍然使用原有文件名。只不过指向了新的inode信息。
所以滑动生成日志的策略会导致,Filebeat在registry中产生大量的记录,滚动生成可以通过exclude_file的方式排出已经监听过的文件。
应对办法
如果你监听的日志文件是滑动策略,或没有办法配置exclude_file导致大量,那么需要配置clean_inactive或clean_removed,不然filebeat的registry文件的容量会不断增多。参考通过clean_*配置减少registry文件大小相关内容。
elastic官方也给出了跟丰富的troubleshooting文档,供参考。

你可能感兴趣的:(ELK)