Grafana Loki过滤日志时如何保留Stack Trace(堆栈追踪)?
解决Promtail过滤INFO日志时丢失堆栈追踪的问题
问题根源是Promtail默认按单条日志行处理,堆栈追踪的多行内容会被当作独立日志条目,因不含INFO标识被过滤删除。要解决这个问题,需先将主INFO日志行和后续的堆栈行合并为单个日志条目,再执行过滤操作。
核心解决方案:添加multiline阶段
在现有Pipeline中加入multiline阶段,负责把关联的堆栈行合并到主INFO日志行中,确保后续过滤和处理的是完整的日志内容(包含堆栈)。
修改后的完整配置示例
pipeline_stages: - match: selector: '{env="myenv"}' stages: # 第一步:合并多行堆栈到主INFO日志行 - multiline: firstline: '.*INFO.*' # 匹配包含INFO的主日志行作为起始行 max_wait_time: 3s # 等待3秒以收集所有关联的堆栈行 # 可选:根据实际堆栈格式定义匹配规则,比如Java堆栈通常以空格/at开头 line_pattern: '^\s+|^at ' # 第二步:解析JSON日志(保持原有逻辑) - json: expressions: msg: log # 第三步:过滤非INFO日志(此时已处理完整条目) - match: selector: '{status="info"} !~ ".*INFO.*"' action: drop - output: source: msg
关键配置说明
multiline.firstline: 定义主日志行的匹配规则,这里用.*INFO.*匹配所有包含INFO的行作为合并的起始点。如果你的日志有更明确的格式(比如时间戳+[INFO]前缀),可以更精准地写为^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\s+\[INFO\]。multiline.max_wait_time: 设置等待时间,确保所有堆栈行都被收集后再处理,避免遗漏尾部的堆栈内容。multiline.line_pattern: 可选配置,用来匹配堆栈行的特征(比如Java堆栈以at开头、Python堆栈以^\s+File开头),能更准确地关联主行和堆栈行,避免误合并无关行。
注意事项
- 阶段顺序至关重要:
multiline必须放在json解析和match过滤之前执行,否则未合并的多行堆栈会被当作无效JSON解析失败,或者直接被过滤删除。 - 根据日志格式调整匹配规则:不同语言/框架的堆栈格式不同,需要根据实际日志内容修改
firstline和line_pattern的正则表达式,确保合并逻辑准确。
内容的提问来源于stack exchange,提问作者Kavindu Nilshan
相关产品推荐
相关产品推荐

