Filebeat 收集日志的过程中,默认是按行收取的,也就是每一行都会默认是一个单独的事件并添加时间戳。但是在收集一些特殊日志的时候,往往一个事件包含有多行,例如 Java 的堆栈跟踪日志:

20-09-25 09:09:01.866 ERROR - {"traceId":"","where":{"methodName":"doFilter","className":"com.sohu.smc.channel.news.filter.ResponseTimeFilter","lineNumber":47},"message":"ResponseTimeFilter error","error":"org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer
at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:309)
at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:272)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:65)
"}

所以针对多行日志需要对 filebeat 进行特殊的配置。

官方文档:https://www.elastic.co/guide/en/beats/filebeat/current/multiline-examples.html

首先对部分配置项进行说明:

  • multiline.pattern:希望匹配到的结果(正则表达式)
  • multiline.negate:值为 true 或 false。使用 false 代表匹配到的行合并到上一行;使用 true 代表不匹配的行合并到上一行
  • multiline.match:值为 after 或 before。after 代表合并到上一行的末尾;before 代表合并到下一行的开头
  • multiline.max_lines:合并的最大行数,默认 500
  • multiline.timeout:一次合并事件的超时时间,默认为 5s,防止合并消耗太多时间导致 filebeat 进程卡死

一、Java 堆栈跟踪日志

1. 示例一

堆栈跟踪日志由多行组成,每一行在初始行之后以空格开头,示例如下:

Exception in thread "main" java.lang.NullPointerException
at com.example.myproject.Book.getTitle(Book.java:16)
at com.example.myproject.Author.getBookTitles(Author.java:25)
at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

要将这些行整合到 Filebeat 的单个事件中,可以在 Filebeat 中添加如下配置:

multiline.pattern: '^[[:space:]]'
multiline.negate: false
multiline.match: after

这个配置会将以空格开头的行合并到上一行内容。

2. 示例二

接下来使用一个比较复杂的堆栈日志格式:

20-09-25 09:09:01.866 ERROR - {"traceId":"","where":{"methodName":"doFilter","className":"com.sohu.smc.channel.news.filter.ResponseTimeFilter","lineNumber":47},"message":"ResponseTimeFilter error","error":"org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer
at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:309)
at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:272)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
... 72 more
"}

使用如下配置可以将这些行整合到一个事件中:

multiline.pattern: '^[[:space:]]+(at|\.{3})\b|^Caused by:|^"}'
multiline.negate: false
multiline.match: after # 或者如下格式 multiline:
pattern: '^[[:space:]]+(at|\.{3})\b|^Caused by:'
negate: false
match: after # 如果日志中有 ... 72 more 这样的结尾,可以用如下匹配方式:
multiline.type: pattern
multiline.pattern: '^[[:space:]]+(at|\.{3})[[:space:]]+\b|^Caused by:|^"}'
multiline.negate: false
multiline.match: after

这个配置会将以空格开头的行和以 Caused by 开头的行合并到上一行内容中。

二、C 风格日志

一些编程语言在一行末尾使用反斜杠()字符,表示该行仍在继续,如下所示:

printf ("%10.10ld  \t %10.10ld \t %s\
%f", w, x, y, z );

使用如下配置可以将这些行整合到单个事件中:

multiline.pattern: '\\$'
multiline.negate: false
multiline.match: before

这个配置会将以 \ 字符结尾的行与后面的行合并。

三、带有时间戳的日志

一般的日志中单个事件都会带有时间戳,但是有时单个事件的日志会被截成两行或者多行,这样就需要匹配时间戳来合并行。示例如下:

例如一个有关于新闻内容的日志,如果新闻的正文中包含换行符,那么在默认情况下,日志中记录的事件会由于换行符的存在被截断

[2015-08-24 11:49:14,389][INFO ][env                      ] [Letha] using [1] data paths, mounts [[/
(/dev/disk1)]], net usable_space [34.5gb], net total_space [118.9gb], types [hfs]

使用如下配置可以将这些行整合到一个事件中:

multiline.pattern: '^\[[0-9]{4}-[0-9]{2}-[0-9]{2}'
multiline.negate: true
multiline.match: after

此配置使用negate: true和match: after设置来指定任何不符合指定模式的行都属于上一行。

四、应用程序事件

有时应用程序日志包含以自定义标记开始和结束的事件,示例如下:

[2015-08-24 11:49:14,389] Start new event
[2015-08-24 11:49:14,395] Content of processing something
[2015-08-24 11:49:14,399] End event

使用如下配置可以将这些行整合到一个事件中:

multiline.pattern: 'Start new event'
multiline.negate: true
multiline.match: after
multiline.flush_pattern: 'End event'

此配置把指定字符串开头,指定字符串结尾的多行合并为一个事件。

使用 Filebeat 对多行日志进行处理(multiline)的更多相关文章

  1. 使用Filebeat传送多行日志

    文章转载自:https://blog.csdn.net/UbuntuTouch/article/details/106272704 在解决应用程序问题时,多行日志为开发人员提供了宝贵的信息. 堆栈跟踪 ...

  2. ELK学习笔记之filebeat合并多行日志示例

    0x00 概述 本节中的示例包括以下内容: 将Java堆栈跟踪日志组合成一个事件 将C风格的日志组合成一个事件 结合时间戳处理多行事件 同理,你可以把如下的正则应用在容器的yaml文件内. 0x01  ...

  3. K8S学习笔记之filebeat采集K8S微服务java堆栈多行日志

    0x00 背景 K8S内运行Spring Cloud微服务,根据定制容器架构要求log文件不落地,log全部输出到std管道,由基于docker的filebeat去管道采集,然后发往Kafka或者ES ...

  4. 转 -Filebeat + Redis 管理 LOG日志实践

    Filebeat + Redis 管理 LOG日志实践 小赵营 关注 2019.01.06 17:52* 字数 1648 阅读 24评论 0喜欢 2 引用 转载 请注明出处 某早上,领导怒吼声远远传来 ...

  5. Filebeat使用模块收集日志

    1.先决条件 在运行Filebeat模块之前: 安装并配置Elastic stack 完成Filebeat的安装 检查Elasticsearch和Kibana是否正在运行,以及Elasticsearc ...

  6. ES & Filebeat 使用 Pipeline 处理日志中的 @timestamp

    使用 Pipeline 处理日志中的 @timestamp Filebeat 收集的日志发送到 ElasticSearch 后,会默认添加一个 @timestamp 字段作为时间戳用于检索,而日志中的 ...

  7. Python正则处理多行日志一例

    正则表达式基础知识请参阅<正则表达式基础知识>,本文使用正则表达式来匹配多行日志并从中解析出相应的信息. 假设现在有这样的SQL日志: SELECT * FROM open_app WHE ...

  8. Logstash——multiline 插件,匹配多行日志

    本文内容 测试数据 字段属性 按多行解析运行时日志 把多行日志解析到字段 参考资料 在处理日志时,除了访问日志外,还要处理运行时日志,该日志大都用程序写的,比如 log4j.运行时日志跟访问日志最大的 ...

  9. ElasticSearch+Logstash+Filebeat+Kibana集群日志管理分析平台搭建

    一.ELK搜索引擎原理介绍 在使用搜索引擎是你可能会觉得很简单方便,只需要在搜索栏输入想要的关键字就能显示出想要的结果.但在这简单的操作背后是搜索引擎复杂的逻辑和许多组件协同工作的结果. 搜索引擎的组 ...

随机推荐

  1. spring的aop编程(半自动、全自动)

    1.spring的半自动代理(从spring中获取代理对象) (1)spring中的通知类型 spring中aop的通知类型有五种: 前置:在目标方法执行前实施加强 后置:在目标方法执行后实施加强 环 ...

  2. Vue 表单拖拽排序

    Vue table表单拖拽 业务需求: 因为数据展示使用的是 elementUI 的 Table进行数据展示的,现在的需求是通过拖拽表单进行表单排序.同时,动态修改表单中的数据排列顺序.查阅了好多资料 ...

  3. C++练习案例1.计算机类(利用多态实现)

    c++简单计算机类 简介 大家好,这里是天天like的博客,这是我发的第一篇随笔,用来记录我的学习日程,大家可以相互学习,多多交流,感谢 今天我要记录的随笔是在学习c++多态的知识点练习改进的一个案例 ...

  4. Python-变量-字符串

    str 字符串如何表示字符串? 单行 单引号 '' 如果字符串中有单引号就需要双引号表示,反之亦然 双引号 " " 换行表示 \ one_str = "简洁胜于优雅&qu ...

  5. Centos-当前登录用户信息- w who

    w who 显示当前登录系统的用户,但w显示的更为详细 who 相关参数 # 默认输出 用户名.登录终端.登录时间 -a 列出所有信息 -b    系统最近启动日期 -m   当前终端信息,相当于 w ...

  6. Python练习题 023:比后面的人大2岁

    [Python练习题 023] 有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁.问第4个人岁数,他说比第3个人大2岁.问第三个人,又说比第2人大两岁.问第2个人,说比第一个人大两岁.最后 问 ...

  7. 092 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 02 static关键字 02 static关键字(中)

    092 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...

  8. 05 sublime环境配置及编译运行后输出中文乱码的解决

    编译后的乱码问题 编译后的输出:中文显示异常: 编译C出现乱码问题解决 解决思路:解决办法很简单,就是先设置文件编码为GBK格式,之后再输入中文文字,运行时的中文就不是乱码了. 首先,sublime中 ...

  9. 【题解】SP1811 LCS - Longest Common Substring

    \(\color{purple}{Link}\) \(\text{Solution:}\) 题目要求找到两个串的最长公共子串.\(LCP\) 我们将两个串中间和末尾插入终止符,并弄到一棵后缀树上去. ...

  10. 【暂咕咕咕】SuffixTree

    #include<bits/stdc++.h> using namespace std; const int MAXN=1e6+10; typedef long long ll; char ...