背景

试水搭建ELK,使用了ELK7.17.13版本,filebeat默认配置的input type已经是filestream而非旧版的log类型,开始了探索之旅。

信任ChatGPT导致的三次失败尝试

ChatGPT3.5介绍说filestream是旧版log类型的替代者,提供了更多的功能和改进,该类型对于新加入文件默认是从尾部开始同步,简单测试后直接上了一台线上机器,log同步QPS破万,马上把ES机器 CPU跑满,妥妥地从文件头部开始读取同步,首次失败,。

ChatGPT继续查询说可以tail_files参数控制log和filestream类型加入新文件时是否从尾部读取的行为,出于谨慎加入tail_files: true参数后尝试同步测试环境的api log,发现依然是从头部开始读取,参数未生效,二次失败。

继续咨询ChatGPT tail_files不生效的可能原因,表示如果之前已经读取过了文件,即便后续修改了tail_files从尾部读取也不会生效,需要删除状态文件registry/filebeat/data.json,最终找到了7.17中对应的log.json文件进行删除,而后重启filebeat发现依然是从头读取整个文件,三次失败。

所谓尽信大模型则不如无大模型确实是有道理的,最终停掉filebeat同步后开始自主探究。

自行探究filestream的尝试

filestream的ignore_inactive参数

查询资料后发现filestream其实并没有tail_files这一参数,只有旧版的log类型才支持tail_files,有不少关于filestream有没有类似log类型的tail_files功能的提问,回答基本都是提到ignore_inactive这个参数,说是可以达到从尾部读取的功能,官方文档介绍如下:

ignore_inactive
If this option is enabled, Filebeat ignores every file that has not been updated since the selected time. Possible options are since_first_start and since_last_start. The first option ignores every file that has not been updated since the first start of Filebeat. It is useful when the Beat might be restarted due to configuration changes or a failure. The second option tells the Beat to read from files that have been updated since its start. The files affected by this setting fall into two categories: Files that were never harvested
Files that were harvested but weren’t updated since ignore_inactive.
For files that were never seen before, the offset state is set to the end of the file. If a state already exist, the offset is not changed. In case a file is updated again later, reading continues at the set offset position. The setting relies on the modification time of the file to determine if a file is ignored. If the modification time of the file is not updated when lines are written to a file (which can happen on Windows), the setting may cause Filebeat to ignore files even though content was added at a later time. To remove the state of previously harvested files from the registry file, use the clean_inactive configuration option.

ignore_inactive有两个选项since_first_start、since_last_start,分别代表filebeat首次启动时间和本次启动时间,filebeat对于首次启动或者本次启动时间之后的文件将直接ignore,即不同步其内容。

重点是后面的

For files that were never seen before, the offset state is set to the end of the file.

这句话直接可以理解为对于filebeat之前没有记录过的文件,offset将被直接置为文件尾部,于是看上去似乎将ignore_inactive设置为since_last_start就能达到tail_files: true的效果。

设置ignore_inactive: since_last_start后一例成功一例失败

在测试环境尝试同步一个微服务的日志文件,验证发现filebeat确实不再从头部读取整个文件内容同步,直到文件尾部有新的内容写入后,尾部的新内容才被filebeat同步最终写入的ES。

再次加入测试环境api主服务的日志文件同步,结果一模一样的配置api的日志文件却是从头开始同步的!!

ignore_inactive源码实现探究

尝试通过源码探究这看似古怪的现象,才算最终捋清了ignore_inactive这一参数的具体作用:

// beats/filebeat/input/filestream/prospector.go
167 func (p *fileProspector) onFSEvent(
168 log *logp.Logger,
169 ctx input.Context,
170 event loginp.FSEvent,
171 src loginp.Source,
172 updater loginp.StateMetadataUpdater,
173 group loginp.HarvesterGroup,
174 ignoreSince time.Time,
175 ) {
176 switch event.Op {
...
190 if p.isFileIgnored(log, event, ignoreSince) {
191 err := updater.ResetCursor(src, state{Offset: event.Descriptor.Info.Size()})
192 if err != nil {
193 log.Errorf("setting cursor for ignored file: %v", err)
194 }
195 return
196 }
...

如上可以看到onFSEvent函数在190行调用了isFileIgnored函数判定文件是否符合ignore条件,若符合则直接将其OffSet置为文件实际Size,亦即设置为从文件尾部开始读取,而isFileIgnored函数实现如下:

224 func (p *fileProspector) isFileIgnored(log *logp.Logger, fe loginp.FSEvent, ignoreInactiveSince time.Time) bool {
225 if p.ignoreOlder > 0 {
226 now := time.Now()
227 if now.Sub(fe.Descriptor.Info.ModTime()) > p.ignoreOlder {
228 log.Debugf("Ignore file because ignore_older reached. File %s", fe.NewPath)
229 return true
230 }
231 }
232 if !ignoreInactiveSince.IsZero() && fe.Descriptor.Info.ModTime().Sub(ignoreInactiveSince) <= 0 {
233 log.Debugf("Ignore file because ignore_since.* reached time %v. File %s", p.ignoreInactiveSince, fe.NewPath)
234 return true
235 }
236 return false
237 }

可以看到若ignoreInactiveSince有值--since_first_start/since_last_start,且当前时间>=ignoreInactiveSince则返回true,于是调用方onFsEvent将读取offset设置为文件尾,至于ignoreOlder对应于filestream的配置参数ignore_older,其判定机制类似,区别在于配置时是采用5m、5h这样的相对时间格式。

测试环境用于测试的微服务日志更新很少,可能几分钟才有新内容,所以filebeat重启后其更新时间小于since_last_start,也就被isFileIgnored判定为true,于是从尾部开始读取文件;而测试环境主api服务的log则是秒级更新,其会被isFileIgnored判定为false,所以会从头读取文件。

也就是说ignore_inactive能够对于新出现的文件设置为从尾部读取的前提是:该文件的最后更新时间小于ignore_inactive设置时间,但是对于秒级甚至ms级持续更新的在线服务日志文件,这个条件判定正常是无法满足的,其并不能完成log类型tail_files对于全部新文件从尾部读取的功能。

总结

最终得出结论:新filestream类型目前并没有提供旧log类型tail_files参数类似的可以控制新加入文件是否从尾部读取的功能,对于持续读写的大log文件首次接入filebeat,可能会由于从头开始同步导致短时QPS飙升进而导致一系列负载飙升,需充分考虑相应的处理方案以防万一。

转载请注明出处,原文地址:https://www.cnblogs.com/AcAc-t/p/filebeat_filestream_read_offset.html

参考

https://www.elastic.co/guide/en/beats/filebeat/7.17/filebeat-input-filestream.html

filebeat新filestream类型是否支持tail_files类似功能探究的更多相关文章

  1. 检测浏览器对HTML5新input类型的支持

    HTML5新增加了很多input元素类型,比如color,date,datetime,datetime-local,email,month,number,range,search,tel,time,u ...

  2. 【AspNetCore】【WebApi】扩展Webapi中的RouteConstraint中,让DateTime类型,支持时间格式化(DateTimeFormat)

    扩展Webapi中的RouteConstraint中,让DateTime类型,支持时间格式化(DateTimeFormat) 一.背景 大家在使用WebApi时,会用到DateTime为参数,类似于这 ...

  3. [Google Guava]学习--新集合类型Multiset

    Guava提供了一个新集合类型Multiset,它可以多次添加相等的元素,且和元素顺序无关.Multiset继承于JDK的Cllection接口,而不是Set接口. Multiset主要方法介绍: a ...

  4. 使用AuthDBMType指令支持多种类似DBM的数据库

    Unix线程 在支持POSIX线程的Unix系统上,现在Apache能在混合的多进程.多线程模式下运行,使很多(但非全部)配置的可伸缩性得到了改善. 新的编译系统 重写了编译系统,现在是基于autoc ...

  5. 【转】解析JDK 7的动态类型语言支持

    http://www.infoq.com/cn/articles/jdk-dynamically-typed-language Java虚拟机的字节码指令集的数量自从Sun公司的第一款Java虚拟机问 ...

  6. guava -- 新集合类型

    Guava引入了很多JDK没有的.但有用的新集合类型.这些新类型是为了和JDK集合框架共存,而没有往JDK集合抽象中硬塞其他概念. 作为一般规则,Guava集合非常精准地遵循了JDK接口契约. 1. ...

  7. Guava集合--新集合类型

    Guava引入了很多JDK没有的.但我们发现明显有用的新集合类型.这些新类型是为了和JDK集合框架共存,而没有往JDK集合抽象中硬塞其他概念.作为一般规则,Guava集合非常精准地遵循了JDK接口契约 ...

  8. atitit.js 各版本 and 新特性跟浏览器支持报告

    atitit.js 各版本 and 新特性跟浏览器支持报告 一个完整的JavaScript实现是由以下3个不同部分组成的 •核心(ECMAScript)--JavaScript的核心ECMAScrip ...

  9. [Guava学习笔记]Collections: 不可变集合, 新集合类型

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3843386.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...

  10. Python3新特性 类型注解 以及 点点点

    Python3新特性 类型注解 以及 点点点 ... Python3 的新特性 Python 是一种动态语言,变量以及函数的参数是 不区分类型 的 在 函数中使用类型注解 相当于 给 形参的 类型 设 ...

随机推荐

  1. Android-NDK开发——基本概念

    在Android开发中,有时候出于安全,性能,代码共用的考虑,需要使用C/C++编写的库.虽然在现代化工具链的支持下,这个工作的难度已经大大降低,但是毕竟万事开头难,初学者往往还是会遇到很多不可预测的 ...

  2. jquery获取框值的数据,收藏一下吧

    效果图: html代码: <!DOCTYPE html> <html> <head> <title></title> <meta ch ...

  3. Windows服务启动exe无界面终极解决方案

      1.前言 我这个方案(C#操作)是彻底解决[从Windows服务启动程序exe,程序无界面]问题的终极解决方案,终极方案,绝对的终极方案,本来打算收钱的,还是算了,你们也不容易,关注我一下就行.后 ...

  4. Java使用joml计算机图形学库,将3D坐标旋转正交投影转为2D坐标

    最近遇到了一个困扰我许久的难题,现将解决方案分享出来 由于我们的项目侧重点在前端绘图,导致了前后端工作量不协调,我后端接口很快就能写完,而前端一个图要画好久,领导见状将前端的任务分到后端一部分用Jav ...

  5. python笔记:第二章基本数据类型

    基本数据类型 Python中的数据类型可以分为五大类:字符串.数字.容器.布尔.None 1.字符串 可以使用单引号或双引号创建字符串,可以用加号将两个字符串合并 name = '小明' age = ...

  6. 【Python】数据可视化利器PyCharts在测试工作中的应用

    PyCharts 简介 PyCharts 是一个基于 Python 的数据可视化库,它支持多种图表类型,如折线图.柱状图.饼图等.PyCharts 提供了简洁的 API,使得用户能够轻松地创建各种图表 ...

  7. MySQL到ClickHouse数据同步方案

    MySQL 同步到 ClickHouse的方案可以看下面的说明,选择合适最近的同步方法. 1. 对比结果概述 整体上,NineData(官网:www.ninedata.cloud )的数据复制功能在功 ...

  8. 基于Taro开发京东小程序小记

    一.小程序基础模型 这里要从微信小程序的历史说起,从前身到现在大概分为3个阶段: 阶段1: 微信网页需要用到app的原生能力,微信官方推出了js-sdk 阶段2: 解决移动端白屏问题,采用微信web资 ...

  9. Unsupervised Learning of Depth and Ego-Motion from Video(CVPR2017)论文阅读

    深度估计问题 从输入的单目或双目图像,计算图像物体与摄像头之间距离(输出距离图),双目的距离估计应该是比较成熟和完善,但往单目上考虑主要还是成本的问题,所以做好单目的深度估计有一定的意义.单目的意思是 ...

  10. 深入Scikit-learn:掌握Python最强大的机器学习库

    本篇博客详细介绍了Python机器学习库Scikit-learn的使用方法和主要特性.内容涵盖了如何安装和配置Scikit-learn,Scikit-learn的主要特性,如何进行数据预处理,如何使用 ...