如何编写Splunk查询查找仅存在Log a缺失Log b的sessionId
Splunk筛选异常中断sessionId实现方案
需求背景
需要筛选符合以下特征的异常sessionId:同一事务链路中存在Log a日志,但不存在对应关联的Log b日志。
对应业务代码逻辑如下:
LOGGER.info("Log a:: setting some details in session"); Response response = handler.transactionMethod(token); // 该方法可能抛出异常导致流程中断 LOGGER.info("Log b:: getting details in session");
场景规则:
- 接口调用成功:同一
sessionId会同时打印Log a、Log b两条日志 - 接口调用异常:
transactionMethod抛出异常时代码执行中断,对应sessionId仅会打印Log a,不会输出后续的Log b - 筛选目标:提取所有仅存在Log a、无对应Log b的异常
sessionId,用于定位代码中断问题
推荐查询语句(高性能版)
日志量大的场景优先用该写法,性能远高于transaction命令:
<替换为你的基础检索条件,比如指定索引、日志来源、时间范围> | fields sessionId, _raw | eval has_log_a = if(like(_raw, "%Log a:: setting some details in session%"), 1, 0) | eval has_log_b = if(like(_raw, "%Log b:: getting details in session%"), 1, 0) | stats sum(has_log_a) as log_a_count, sum(has_log_b) as log_b_count by sessionId | where log_a_count > 0 AND log_b_count = 0 | table sessionId, log_a_count
语句逻辑说明:
- 提取每条日志的
sessionId和原始日志内容 - 给每条日志打标记:匹配到Log a则
has_log_a记为1,匹配到Log b则has_log_b记为1 - 按
sessionId分组,统计两类日志的总条数 - 过滤出存在Log a、完全没有Log b的
sessionId,即为流程中断的异常会话
扩展:查看异常session的全链路日志
如果需要排查每个异常session的具体报错,可以用以下语句直接拉出对应会话的所有日志:
<替换为你的基础检索条件> | fields _time, sessionId, _raw | eval has_log_a = if(like(_raw, "%Log a:: setting some details in session%"), 1, 0) | eval has_log_b = if(like(_raw, "%Log b:: getting details in session%"), 1, 0) | eventstats sum(has_log_a) as log_a_count, sum(has_log_b) as log_b_count by sessionId | where log_a_count > 0 AND log_b_count = 0 | sort sessionId, _time asc | table _time, sessionId, _raw
注意事项
- 如果生产环境的Log a、Log b实际打印文本和示例不一致,把
like函数里的匹配串替换为实际日志特征即可 - 如果日志已经做了字段抽取,存在独立的日志类型、事件名称字段,直接用字段判断代替
like匹配原始日志,查询效率会更高
内容的提问来源于stack exchange,提问作者Ramnarayan Choudhary
相关产品推荐
相关产品推荐

