深色模式
多行日志合并
Java/C# 的异常堆栈会跨多行,默认按行采集会把一条异常拆成几十条事件,检索和告警都失灵。本文演示在 Filebeat、Fluent Bit、Promtail 中合并多行。
适用环境
bash
# 准备一段测试堆栈日志
cat > /tmp/trace.log <<'EOF'
2026-10-09 10:00 ERROR c.App - boom
java.lang.NullPointerException
at c.App.run(App.java:10)
at c.Main.main(Main.java:5)
EOF1
2
3
4
5
6
7
2
3
4
5
6
7
操作步骤
1. Filebeat:用 multiline
yaml
filebeat.inputs:
- type: filestream
paths: ["/var/log/app/*.log"]
multiline:
type: pattern
pattern: '^\d{4}-\d{2}-\d{2} ' # 以时间戳开头的行是新事件
negate: true
match: after1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
2. Fluent Bit:用 multiline 过滤器
ini
[INPUT]
Name tail
Path /var/log/app/*.log
Multiline On
Parser_Firstline java_firstline1
2
3
4
5
2
3
4
5
3. Promtail:pipeline 的 multiline
yaml
pipeline_stages:
- multiline:
firstline: '^\d{4}-\d{2}-\d{2} '
max_wait_time: 3s1
2
3
4
2
3
4
WARNING
match: after 表示把后续行追加到上一行之后;若设成 before 会反向拼接。先用 --dry-run/本地试跑确认拼接方向正确。
验证
bash
# Filebeat 测试输出,确认异常成一整条
filebeat run -e -c filebeat.yml -d publish 2>&1 | grep -A5 'NullPointerException' | head -n 81
2
2
常见坑
DANGER
多行「等待窗口」过长会延迟事件入库,max_wait_time 建议 3–5s;过短则并发日志会黏在一起,需在延迟与准确间权衡。