带重复启停事件的案例状态日志会话统计方案咨询
核心优化实现思路
第一步:前置清洗日志,从根源消除无效重复记录
- 对每个
case_id的全量日志,先按time_created升序做全局排序 - 执行相邻状态去重:逐行遍历排序后的序列,如果当前记录的
state和上一条同case_id下的记录状态完全一致、且中间没有其他状态穿插,直接判定为重复冗余记录剔除- 例:连续2条
REVIEW_NEEDED、连续2条CLOSED这类无状态跳变的重复,全部只保留最早出现的那条 - 例:
REVIEW_NEEDED -> REVIEW -> REVIEW_NEEDED这类带状态跳变的重复,属于真实的状态回退业务流程,完全保留不做清洗
- 例:连续2条
- 经过这步处理后,每个case的状态流就变成无连续冗余的有效事件序列,从根源减少重复记录带来的计数偏差
第二步:替换原“分状态独立编号+等值关联”的逻辑,改为单序列流式配对
原方案的本质缺陷是把三类目标状态从日志中拆分出来、各自单独排序编号、再按编号值做等值关联,一旦某类状态的事件数量和其他类不对等,就会出现跨会话的错误匹配。优化后不需要拆分日志流,顺着清洗后的全量状态流做一次遍历,按业务流转规则直接完成会话切分和字段匹配:
- 首先明确固定的状态流转顺序:
REVIEW_NEEDED(触发等待起点)→REVIEW(触发处理起点)→WAITING/CLOSED(触发处理终点) - 给每个
case_id维护一个会话游标,顺着时间往前扫描每一条有效状态记录,按规则填充字段:- 遇到
REVIEW_NEEDED:初始化一条新的报表记录,把当前日志的case_id、id(作为open_id)、time_created(作为waiting_time_start)填入,把游标标记为「已等待起点、待处理起点」 - 遇到
REVIEW:如果当前游标是「已等待起点、待处理起点」,就把当前日志的time_created填入对应记录的handling_time_start,把游标标记为「已填全起点、待处理终点」;如果游标已经是其他状态,先把当前没填完字段的不完整记录落表,再重新执行第1步的初始化逻辑 - 遇到
WAITING/CLOSED:如果当前游标是「已填全起点、待处理终点」,就把当前日志的time_created填入对应记录的handling_time_end,把当前日志的id(作为close_id)填入对应字段,直接闭合这条记录、重置游标准备接收下一段会话
- 遇到
- 全程不做跨状态的编号匹配,遇到状态断档(比如没有
REVIEW直接跳CLOSED、没有终点状态就跳回REVIEW_NEEDED)时,直接把当前未闭合的不完整记录按现有字段落表,绝不硬凑编号做错位匹配
优化后的适配效果
- 遇到
case_id=100有2条带状态跳变的REVIEW_NEEDED、2条REVIEW的场景,会顺着状态流自然切分成2条独立的会话记录,不会因为两类状态各2条就硬凑编号匹配错位 - 遇到
case_id=101连续2条CLOSED的场景,前置去重后只会保留1条有效闭合事件,不会因为重复日志多生成无效的会话记录 - 当三类目标状态的事件数量不对等时,不会因为硬关联编号产生交叉匹配的脏数据,所有字段值都严格对应当前会话段内的真实触发事件
内容的提问来源于stack exchange,提问作者Miki
相关产品推荐
相关产品推荐

