filebeat输出到es,日志顺序乱了?

新手上路,请多包涵
主要是想使用filebeat 直接输出到es,不使用logstash。用于日志抓取。

问题:filebeat把日志输出到es后,查看日志的时候发现日志里面的顺序是乱的。
开发人员看起来非常费劲。
例如:

        April 12th 2018, 15:44:29.443   2018-04-12 15:44:25 871 DEBUG xxx
        April 12th 2018, 15:44:29.443   2018-04-12 15:44:25 871 DEBUG 
        April 12th 2018, 15:44:29.443   2018-04-12 15:44:25 872 INFO 
        April 12th 2018, 15:44:29.443   2018-04-12 15:44:25 869 INFO 
        April 12th 2018, 15:44:29.443   2018-04-12 15:44:25 871 DEBUG
        April 12th 2018, 15:44:29.443   2018-04-12 15:44:25 871 INFO 
        April 12th 2018, 15:44:29.443   2018-04-12 15:44:25 869 INFO  
        April 12th 2018, 15:44:29.443   2018-04-12 15:44:25 869 DEBUG 
        April 12th 2018, 15:44:29.443   2018-04-12 15:44:25 870 DEBUG

后面的毫秒是乱的没有正常排序输入到es。

请哪位对filebeat比较了解的帮忙解答下!

谢谢!

阅读 16.8k
2 个回答

那得看你的日志采集自一台机器, 还是多台机器; 你的 filebeat 和你的 es 是在一台机器, 还是分属两台机器.

按我的理解, 如果 filebeat 配置中没有开启 publish_async 选项, 那么单一 filebeat 实例的输出总是和文件顺序一致的.
但如果你在多台服务器上部署了多个 filebeat, 因为各个系统时钟未必时刻完全一致(导致日志记录的时间在各个服务器上未必一致), 且中间经过网络传输, 就没法保证 es 接到的数据和日志中标明的时序一样.
即使只有一个 filebeat 实例, 如果和 es 部署在不同服务器上, 那也只排除了系统时钟问题, 但网络问题依然可能导致后发的日志先被 es 收到.

如果对日志时序有要求, 最好还是过一道 logstash, 把日志时间解析成 es 的 timestamp.

最近刚解决过这个问题,我们的场景是在docker环境下输出json-file的,日志驱动是纳秒级精度,但是应用(比如java)是毫秒级的,在es中,timestamp是date类型,精度就是毫秒级,这意味着——即使你将纳秒级的日志传递给es,也会因为数据类型而丢失精度。我们的场景比这个更复杂,因为同一个毫秒中有非常多的纳秒级日志,如果只是交给es去排序,那么悲剧就会发生,丢失精度之后,日志就出现了乱序。
解决方案:

  1. 通过source获取日志本身的来源,确保日志源之间不会相互串序
  2. 保留纳秒级日志的精度,传递给es时,使用pipeline将纳秒级日志单独存成一个string类型的时间戳(原因如上)
  3. 如果es通过timestamp排序发现乱序,再通过这个纳秒级的时间做字符串排序

解决方案经过测试,已经实装

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进