HC

hu-chenyu/log-ai-compressor

Developer tools
1 stars Качество 66 Тренд 25MIT

本机日志取证层:每条结论带行号出处、可重读原文自校验;拿不出因果链就说证据不足。零出网,附 MCP Server / Agent Skill。

Обзор

拿不出因果链就说证据不足,并精确列出还缺什么才能定论 —— 而且会对这些缺口负责:补上了就把缺口划掉。 大多数日志工具要你**它的结论。这个工具给的是你可以**的东西 —— 每条结论都带原文的**和那段原文的 。 判定只有三档, —— 一份掺了假证据的报告,不该因为大部分 为真就放行。那是取证工具最不能犯的错。 第四行是这份 README 里我最想让你注意的一行:一个** 的项目,它剩下的每个数字才有分量。撤回经过见 docs/BENCHMARK.md 与 docs/FAQ.md Q10。 一个只会报好数字的项目不值得信。下面这些是本文**的地方, 先摆在数字前面,完整版见 §9 它做不到什么。 一个云平台说「我不知道」,在产品上读起来像故障。本工具说「我不知道」, 在方法论上读起来像专业。 绝大多数日志工具(包括带 AI 的)都在优化** —— 尽可能多地给出根因。 但这有个没被解决的问题:,因为值班的人会照着它去查。 按频率排,工具一定会说「根因:连接池耗尽」。 真正的因只出现 10 次,被当成了噪音。

README

log-ai-compressor · 本机日志取证层

我们不把日志交给大模型。我们用确定性算法把日志变成可复核的证据,大模型只读证据。 拿不出因果链就说证据不足,并精确列出还缺什么才能定论 —— 而且会对这些缺口负责:补上了就把缺口划掉。 全部计算在本机完成,日志不出网。


🧾 立场:你不必相信这个工具

大多数日志工具要你相信它的结论。这个工具给的是你可以自己复核的东西 —— 每条结论都带原文的行号区间和那段原文的 sha256。

$ log-ai-compressor run app.log -f json -o report.json
$ log-ai-compressor verify --report report.json
证据:共 8 条引用,匹配 8 条,失配 0 条,源不可读 0 条

事故复盘时,有人把日志里的主机名改了:

$ log-ai-compressor verify --report report.json
证据:共 8 条引用,匹配 7 条,失配 1 条
  ✗ MISMATCH ca0e981df461 app.log 期望 c33aeb824ce67aaf 实际 4a1689f3780880ae
自校验结论:TAMPERED        # 退出码 1

判定只有三档,没有「大部分通过」 —— 一份掺了假证据的报告,不该因为大部分 为真就放行。那是取证工具最不能犯的错。

同一套立场长成了四件具体的事:

我们怎么做 通常的反面
拿不出 Caused by 因果链就只给 LIKELY,并列出还缺什么才能定论,补上了就把那条缺口划掉 给一个听起来很像回事的根因
同一份日志跑两遍,结论指纹逐字节相同(耗时与速率已排除) 每次结论都不一样,没法归档、没法追责
证据摘要只认文件原始字节,剥过 ANSI 的文本不算 同一行原文,两条出口给两个摘要
撤回过一个跑不出来的召回率数字(91.4%),并公开查了哪六条路径 挂着一个复现不了的漂亮数字

第四行是这份 README 里我最想让你注意的一行:一个主动撤回自己招牌数字 的项目,它剩下的每个数字才有分量。撤回经过见 docs/BENCHMARK.md 与 docs/FAQ.md Q10。


📌 先读这一节:本文的数字不能证明什么

一个只会报好数字的项目不值得信。下面这些是本文所有实测结论都覆盖不到的地方, 先摆在数字前面,完整版见 §9 它做不到什么。

本文不能证明 原因
根因准确率高于云平台 RCA100 的结论是 62.5% 的根因案例至少需要两种模态、31% 需要三种。本工具只有日志一种,跟它们不是同一场比赛
在所有日志形态上都优于 Drain3 实测覆盖 Loghub 5 个数据集 + Android_v1。fetch_datasets.py 自 v2.8.1 起能下 10 个(新增 Linux / Mac / HPC / OpenSSH / Hadoop),但本次开发环境连不上 Zenodo,新增的 4 个未实测,表里没有它们的数。最差的一个(OpenStack)证据保留率只有 50%,不是全胜
压缩比能外推到你的日志 12289 倍是 OpenStack 全级别摘要口径下的数字。换个数据集、换个 --context,数量级就变
「召回率 100%」代表真实生产事故 只在 1 个含链真实数据集上测过(Android_v1 全量,131 条链 / 8 个根因类)。样本小,结论未必能外推。原先并列的 Hadoop 91.4% 已于 v2.7.0 撤回(数据集来源不可得)
持续监控与告警 没有 agent 埋点、没有时序库、没有告警队列 —— 这是有意的取舍,不是没做完

一个云平台说「我不知道」,在产品上读起来像故障。本工具说「我不知道」, 在方法论上读起来像专业。但如果你要的是全天候告警,本工具给不了,别选它。



1. 这个工具和别的日志工具有什么不一样

绝大多数日志工具(包括带 AI 的)都在优化命中率 —— 尽可能多地给出根因。 但这有个没被解决的问题:一个自信的错误根因,比没有根因更糟,因为值班的人会照着它去查。

举个实测例子。同一份 20 万行日志里:

出现次数 真实角色
connection pool exhausted 370 症状
Connection is not available 10 真正的因

按频率排,工具一定会说「根因:连接池耗尽」。这是错的。 真正的因只出现 10 次,被当成了噪音。

本工具的做法:

判定:可能原因 —— 统计推断,非因果证明
不可作为根因输出

最可能的原因:connection pool exhausted —— 但这是统计推断,不是因果证明

补齐下列证据才能定论:
  · 缺少确定性因果链   —— 带完整异常堆栈的日志(尤其是 Caused by: 链)
  · 存在难以区分的并列候选 —— 能区分二者的额外信号(调用链先后、指标对比)
  · 无异常堆栈        —— 未做异常栈裁剪的完整堆栈

这就是本项目与全品类工具的核心差异,完整论证见 docs/POSITIONING.md §3.4。

而这个差异,是可以被第三方复算的 —— 本项目只认领这一个独占叙事

上面讲的是立场。立场不值钱,能被复算的立场才值钱。

这个方向上目前公开的判断是:Resolve.ai 和 Rootly 都发过自有的 LLM 基准文章, 但没有一个带可复现数据集(来源)。

于是本项目做了一件笨事:不宣传自己的压缩比,去打一张公开的榜。

证据保留率(Loghub 2.0 真实数据 + 人工标注,每一行都有 EventId):

数据集 标注事件 本项目(全级别) Drain3 LogsLop (AMD) tail @32k grep @32k
Apache 29 100.0% 93.1% 44.8% 27.6% 34.5%
HealthApp 156 87.8% 83.3% 7.1% 32.1% 3.8%
OpenStack 48 50.0% 41.7% 18.8% 20.8% 8.3%
Proxifier 11 100.0% 72.7% 27.3% 63.6% 45.5%
Zookeeper 89 92.1% 76.4% 23.6% 79.8% 9.0%

对照的三个都是真工具,不是稻草人:

  • Drain3 —— 学术标准日志模板抽取(ICWS’17, 800+★),Loghub 官方用来算 PA 的那个
  • LogsLop —— AMD 2026-07 的 ROCm 博客开源工具,目前最接近的正面竞品, 同样用 Loghub + Drain3 做对照。它是去重工具,优化的是「别让我看两遍一样的」, 而证据保留要的是「别弄丢根因证据」——两个目标方向相反,所以它把文本相似的 不同事件合并掉了,且几乎不随预算增长(Apache @500tok 37.9% → @32k 仍是 44.8%)
  • tail / grep —— 最朴素的两条基线

复现命令、数据来源、口径说明、以及这个数不能证明什么,全在 docs/BENCHMARK.md。

至于本地优先、零出网、MCP Server、Agent Skill —— 这些都是行业里越来越多人在做的事, 我们有,但不是护城河,不当卖点讲。


被质疑时请直接看 docs/FAQ.md —— 那里逐条回答了 「凭什么比 Drain3 强」「自信错误率是不是门槛设高了」「证据引用能不能防结论本身错」 「压缩比是不是挑了口径」「为什么 Drain3 的 PA 99.75% 你不比」等问题, 每一条都附实测依据和「本项目做不到什么」。



每条结论都能被独立复核 —— 这是本项目最硬的一条

上面那三档置信度,如果无法验证,就只是三张标签。所以每条结论都绑定一份 证据引用:文件、行号区间、该段原文的 sha256 摘要。

$ log-ai-compressor run app.log -f json -o report.json
$ log-ai-compressor verify --report report.json
模式:复核已导出报告
证据:共 8 条引用,匹配 8 条,失配 0 条,源不可读 0 条
确定性指纹:37a53c71…139ae06a8a17

摘要不是装饰。它让「结论来自这段原文」从一句断言变成可验证的命题:

# 事故复盘时,有人把日志里的主机名改了
#   db-primary:5432  →  db-replica:6432
$ log-ai-compressor verify --report report.json
证据:共 8 条引用,匹配 7 条,失配 1 条
  ✗ MISMATCH ca0e981df461 app.log 期望 c33aeb824ce67aaf 实际 4a1689f3780880ae
自校验结论:TAMPERED        # 退出码 1

判定只有三档,没有「大部分通过」 —— 一份掺了假证据的报告不该因为大部分 为真就放行,那是取证工具最不能犯的错。粘贴文本没有可回读的源文件时如实报 NO_SOURCE,不谎称通过。

这个工具不需要你相信它。 你可以自己跑这一步。

确定性:同一份日志跑两遍,结论逐字节相同

报告头部与 API 都带一个 sha256「确定性指纹」(耗时、速率这类每次都不同的 数字已排除)。同一份输入跑两次指纹不一致,就是回归。CI 里跑三次:

$ python scripts/adversarial_eval.py    # 见下
$ # CI: 同一份日志连跑三次,指纹必须唯一

这条约束是「结论可写进事后复盘」的前提 —— 不能复现的结论没法归档、没法追责。


对抗性评测:专门设计来误导这个工具的场景

上面所有数字都由本项目自己产出,所以另配了一组专门用来让本工具出错的 场景,按四条硬规则打分。这是本项目唯一能证明自己没在自说自话的方式。

$ python scripts/adversarial_eval.py
● structured_trace_not_causal   [4/4]  verdict=LIKELY  簇=3 CONFIRMED=0
  ✓ abstain_correctly       verdict=LIKELY, can_conclude=False, CONFIRMED 簇 0 个
  ✓ causal_language_ok      非 CONFIRMED 簇未使用因果措辞
  ✓ trace_chain_found       最长链路覆盖 3 个服务(要求 ≥3)
  …
────────────────────────────────────────────────────────────
  场景数              : 10
  评分项 / 通过        : 35/35  (100.0%)
  正确弃权率           : 100.0%  (5 个应弃权场景)
  自信错误率           : 0.0%    ← 最该压到 0 的那个数
  总判定               : PASS

10 个场景包括:红鲱鱼部署、关键词堆砌的良性日志、共现无因果、单模块无栈、 无时间戳、反向场景(证据其实够了,不该虚报缺口)、结构化日志调用链、 有完整调用链但无 Caused-by、以及普通文本被误吞成 logfmt。

两条口径写死在脚本里,评审前先看这两条:

  • 弃权算通过,不算失败。 在确实无法定论的事件上正确弃权是这个工具想要 的行为。只算命中率的评测会偏好猜得最自信的系统 —— 那正是要淘汰的。
  • 自信错误率权重最高。 值班的人会照着一个自信的错误根因去排查。

这套评测已经抓出过真 bug:原实现把「时间上紧邻在前的另一个错误簇」当成 因果因,标成 CONFIRMED,一条 INFO request started 因此被判成确定性根因。

已接入 CI(.github/workflows/ci.yml):评分卡不过,CI 变红。

一条命令验证本文所有数字

上面每个数字都可以自己复现,不需要相信作者:

$ python scripts/prove.py
==========================================================================
自证:sample_system.log —— 不必相信作者,自己跑
==========================================================================
  PASS  确定性:同输入同结论
        3 次运行产生 1 个指纹 (一致)
  PASS  证据可复核:每条结论带行号出处且核对通过
        8/8 个簇带出处;自校验 VERIFIED,匹配 8/8
  PASS  置信档位:无因果链时零确定性断言
        日志含 Caused-by:True;判 CONFIRMED 0 个;verdict=LIKELY
  PASS  压缩:投喂口径远小于原文,且完整报告体积如实报出
        原始 ≈934 tok → summary ≈453 tok (2.1x)→ md ≈9,204 tok
  PASS  对抗性评测:该弃权时确实弃权
        10 场景 35/35 通过;正确弃权率 100.0%;自信错误率 0.0%
  PASS  结构化日志:JSON 认领 / 普通文本不误判
  PASS  轻量安装:硬依赖不含 Web/MCP/AI
        硬依赖 ['PyYAML>=6.0']

尚无数据的主张(刻意列出,不藏)
  ?  根因判定的真实数据集覆盖度
  ?  与云平台根因准确率的对比

注意压缩那一行:在这个 52 行的小日志上,完整 md 报告比原文大 9.9 倍。 脚本不回避这一点 —— 完整报告带样例与上下文,小文件上必然比原文长,这是事实。 压缩比 15x–388x 那组数字来自 Loghub 真实数据集,口径见 §6.1 与 docs/BENCHMARK.md,不要拿本节的小文件数字去宣称压缩比。

prove.py 也是 CI 门禁之一:README 与产品不允许漂移。



实测:5 个真实故障日志上的「压缩比 vs 证据保留率」

在 Loghub-2.0(ISSTA’24 配套数据集, 事件模板为人工标注,不是任何工具的输出)上实测 5 个真实系统日志, 与 Drain3(ICWS’17 论文,821★)同场对比:

数据集 原始 本项目输出 Drain3 输出 本项目保留率 Drain3 保留率
Proxifier 624K tok 743 317 100% 72.7%
Apache 1.2M tok 548 431 100% 93.1%
Zookeeper 2.6M tok 470 980 92.1% 76.4%
HealthApp 5.1M tok 499 566,802 87.8% 83.3%
OpenStack 15.3M tok 746 73,569 50.0% 41.7%

证据保留率 5 个数据集全部领先(保留率 = 输出中仍可识别的标注事件类型占比)。

表中「本项目输出」是首轮跑分(旧版代码与旧估算器口径)。输出规模的 当前复测值与统一口径见 docs/BENCHMARK.md「结果二」 (Zookeeper 517 / Apache 564 / Hadoop 708 tokens,结论形状不变)。

两个差异,以及各自的口径:

  • 输出规模有上界(口径:summary,投喂 LLM 用)。与日志行数、事件类型数 无关 —— 当前代码复测:日志从 12 万行涨到 18 万行(原始 tokens 6.4 倍), summary 仍在数百 token(313–788);Drain3 从 317 涨到 566,802(跨度 1789 倍)。 HealthApp 上它压缩比只有 9x、耗时 578 秒 —— 一个 56 万 token 的"压缩结果"等于没压缩。
  • 但人读的完整报告(md,CLI 默认格式)不是恒定的:复测 4.8 万–9.7 万 tokens, 压缩 28x–85x,取决于簇数与实例展开。两种口径不能混用 —— 拿 md 去宣称 「几百 token」是夸大。详见 docs/BENCHMARK.md。

这个领先不是算法更强,是补了两个真实日志格式的解析洞。 首轮实测只有 3 胜 2 负;逐条追查后补上 ZooKeeper 的 - LEVEL [模块] - 与 HealthApp 的 YYYYMMDD-HH:MM:SS:mmm|模块|ID|内容 两种格式。在解析正常的日志上 领先,靠的是每簇保留一行原始样例作为可引用证据,不是分得更准。

置信档位实测:零因果链时零确定性断言

「敢不敢说我不知道」这句话需要数据支撑。评测方式:完全独立于本项目, 直接扫原始日志的 Caused by: 链构造地面真相,再与工具输出对账。

数据集 行数 真实因果链 工具判 CONFIRMED 自信错误率
Zookeeper 74,273 0 0 0%
其余 4 个 455,324 0 0 0%

这个评测第一跑就抓到一个真 bug:原实现把「时间上紧邻在前的另一个错误 簇」当成因果因,然后标成 CONFIRMED —— 一条 INFO request started 因此 被判成确定性根因,正是这个功能声称要消灭的「自信的错误答案」。已修复为 只认条目内 Caused by: 链,并把根因指向链上最内层的异常。

召回率(真出现因果链时能否找到):复现语料(自建故障场景 + 真实 Java 异常/栈帧/日志格式,非生产日志)上已可复跑 —— 5 条因果链,精确率 100%、 召回率 100%、自信错误率 0%,无链对照组 0 CONFIRMED:

$ python scripts/eval_rootcause.py --repro
  合计:真实因果链 5,CONFIRMED 5
    精确率 100.0%   自信错误率 0.0%   召回率 100.0%

真实数据集:一个,全量可复现

数据集 含链文件 真实链 CONFIRMED 精确率 自信错误率 召回率·报告口径
Loghub Android_v1(全量 1,555,005 行) 1 131 10 100.0% 0.0% 100.0%
$ python scripts/eval_rootcause.py
  合计:真实因果链 131,CONFIRMED 10
    精确率 100.0%   自信错误率 0.0%
    召回率·报告口径 100.0% (131/131)
    召回率·簇文本 100.0% (131/131)
    召回率·宽松 100.0% (131/131)

v2.7.0 撤回了一组数字:Loghub Hadoop 的 91.4%。 那份数据的来源已确认 不可得 —— 两个 Zenodo 记录、logpai/loghub 仓库、本项目 data/ 下全部真实 日志都查过,均无 YARN / application_*/container_*.log,且本地每个 Loghub 日志逐文件实测 Caused by 出现次数为 0(只有 Android_v1 有链)。一个跑不 出来的数字留着只会在被追问时塌台。撤回经过见 docs/BENCHMARK.md 与 FAQ.md Q10。

三个召回口径必须说清差别:报告口径(对外只认这个)要求 CONFIRMED 簇 对外报告的根因文本(root_cause_reason + 全部内层因变体)点名该链的根因 类名 —— 答的是「用户照着报告能不能查到这一条」;簇文本只查簇的样例原文 里有没有出现过这个类名(文本里有过 ≠ 工具把它说了出来);宽松只要求行区间 盖住,只证明位置对得上。

v2.7.0 把对外口径换成「报告口径」的理由:旧口径查的是样例原文,而一个簇的样例 恰好是 SocketException 时,后面 29 次同类的链全被算作"被点名",可报告里根因 那一行写的是另一个类 —— 用户照着报告查,报告里没有。更要紧的是,旧口径 检测不出 v2.6.0 那个「一簇只报一因」缺陷(变体不存在,簇文本照样满分)。 指标看不见自己该管的缺陷,比指标偏低更危险。

Android_v1 那一行是被真实 bug 逼出来的:最初实测召回率是 0%(131 条真实 链、CONFIRMED 零个)。根因是 Android logcat 把整个异常压在一行里 (E Tag: com.x.PushException: boom Caused by: java.net.SocketException: abort), 而本工具既没有 logcat 解析模式(无年份 / 单字母级别 / PID+TID),Caused by 的 两条正则也都锚在行首 —— 链整条看不见。现在两种形态都认, 见 docs/BENCHMARK.md 与 CHANGELOG 2.3.0。

样本限制照实说:

  • Android_v1 在 v2.4.0 已补跑全量 —— 1,555,005 行 / 131 条链,链密度与原文件 一致(1 / 11,870 行),报告口径召回 100%。原先切片时那条「密度高 6.8 倍、 方向偏保守」的免责声明已删除,因为结论没有随密度回落而翻转。
  • Hadoop 那组数字已在 v2.7.0 撤回 —— 数据集来源不可得(两个 Zenodo 记录、 logpai/loghub 仓库、本地全部数据都查过),且本地每个 Loghub 日志逐文件实测 Caused by 出现次数为 0。撤回经过见 docs/BENCHMARK.md。
  • 只有一个含链的真实数据集 —— 这是本项目最实在的一条短板,且代码解决不了: 131 条链、8 个根因类,样本量不大,「召回 100%」不能外推到别的日志形态。

复现语料与真实数据分开列,不混。

复现:python scripts/benchmark_loghub.py · python scripts/eval_rootcause.py · python scripts/eval_rootcause.py --repro · 完整方法学、对照组公平性说明与「本文不能证明什么」见 docs/BENCHMARK.md



2. 它到底做什么

一句话:把一个日志文件,变成一份带行号引用、压缩到几百 token 的证据包。

场景 痛点 解法
日志压缩投喂大模型 几十 MB 的日志远超 LLM 上下文窗口,直接粘贴要么截断要么爆 token 聚类去重 + Top N + 典型样例。实测 10 万行 / 7MB → 150 tokens
快速故障排查 上百万行人工翻找,同类错误刷屏干扰判断 根因排序 + 异常检测 + 堆栈降噪,直接指出「先查哪里」
给 AI Agent 当后端 Agent 查日志只能 grep + 硬塞上下文 内置 MCP Server,Claude Code / Codex / mavis 直接调用
判定「这个问题能不能定论」 所有工具都硬给答案 证据充分性评估:敢说我不知道,并说清缺什么

为什么是「本地」

主流可观测平台(阿里云 SLS、Datadog、Dynatrace…)必须把日志上传到云上, 按 GB 或按主机计费,还要求先装 Agent 埋点。

这不是懒于做云版本,而是有具体理由:2026 年 7 月 Hugging Face 遭攻击事件中, 他们的取证分析一开始尝试调用商业 LLM API,被安全策略拦截了 —— 护栏无法判断提交者是攻击者还是应急响应人员,最终只能自托管模型完成分析, 并因此保住了「凭据从未离开环境」。

涉密/内网日志根本不能上云,这是结构性的需求,不会被技术进步消除。

代价是它不做「持续监控」:它是取证工具,不是 APM 平台。这是有意的取舍。


3. 快速开始

安装

# 本地 Web 界面(推荐:自动开浏览器,端口 8765 起,被占用自动顺延)
pip install "log-ai-compressor[web]"
log-ai-compressor web

只在命令行里压缩日志、不需要界面:pip install log-ai-compressor(硬依赖只有 PyYAML)

Windows:双击运行

从源码运行时,项目根目录的 start.bat 会自动定位 Python、首次运行自动装依赖、 启动本地服务并打开浏览器。

命令行

log-ai-compressor web               # 本地 Web 界面
log-ai-compressor web --port 9000   # 指定端口
log-ai-compressor web --no-browser  # 不自动开浏览器

log-ai-compressor run app.log --top 20 -o report.md   # 分析并导出 Markdown

# 复核一份报告的结论出处(推荐:报告发出去后日志可能已被改动或轮转清理)
log-ai-compressor verify --report report.json
log-ai-compressor verify --report report.json --json    # 机器可读
log-ai-compressor verify app.log                        # 当场自检

从源码运行(开发者)

git clone https://github.com/hu-chenyu/log-ai-compressor.git
cd log-ai-compressor
pip install -r requirements-dev.txt
python -m pytest                        # 1,043 个测试
python scripts/adversarial_eval.py      # 对抗性评测评分卡(CI 门禁之一)
python scripts/benchmark_loghub.py      # 复现上面的实测表(需先下载数据集)

让 AI Agent 直接调用本机日志(MCP / Agent Skills)

pip install "log-ai-compressor[mcp]"
log-ai-compressor mcp                  # 打印现成的客户端配置

已收录于官方 MCP Registry(registry.modelcontextprotocol.io),MCP 客户端可直接发现并安装:

mcp-name: io.github.hu-chenyu/log-ai-compressor

提供 8 个只读工具:analyze_log_file、analyze_log_text、compare_log_files、 export_report、get_cluster_detail、verify_evidence、list_rules、check_environment。 全部在本机执行,日志不出网。

verify_evidence 是取证层的关键工具:它重读原始日志逐条核对结论出处, 返回 VERIFIED / TAMPERED。Agent 不需要相信这个工具,可以自己复核。

同时提供 SKILL.md(Agent Skills 开放标准),任意支持该标准的 agent 可一条命令安装:

npx skills add /log-forensics

4. 核心特性

分析引擎(全部本地算法,零出网)

  • 双输入模式:文件导入(超大文件、编码自动适配 UTF-8/GBK/GB2312/UTF-16/UTF-32,.gz/.zip 透明解压)+ 文本粘贴
  • 结构化日志原生解析:JSON Lines 与 logfmt 开箱即用,零配置零新依赖。 2026 年主流框架的默认输出已经是 JSON(Spring Boot 4.x 原生支持 ECS / Logstash / GELF,内置 OpenTelemetry starter),拿正则去刮纯文本的工具在真实生产日志面前是残废的。 级别、时间、服务、trace_id / request_id 全部按字段认领, 兼容 OTel log.level 点号命名空间、ECS severity_text、真嵌套 {"service":{"name":…}}
  • 调用链重建:结构化日志里存在关联键时,按 trace_id / request_id 还原 跨服务链路与首个失败点 —— 不需要装 agent、不需要接拓扑、不需要第二模态。 这让工具能把自己列出的证据缺口真的补上(见下)
  • 通用文本日志解析:时间戳 / 级别 / 模块 / 内容 / 堆栈(Java、Python、C/C++、gdb 帧全兼容)
  • 模糊指纹聚类去重:行号、参数、十六进制 ID、路径差异全部抹平,同类错误只留一份典型样例 + 前后上下文
  • 三档相似度:严格 ≥0.95(簇更准)/ 标准 ≥0.85(默认)/ 宽松 ≥0.70(簇更少更狠)
  • 证据引用:每条结论绑定 evidence_id + 文件 + 行号区间 + 原文 sha256 摘要, 可用 verify --report 重读原文逐条核对;日志被修改或轮转清理会报 TAMPERED
  • 确定性指纹:同一份日志两次分析,结论部分逐字节相同
  • 智能辅助分析:
    • 证据充分性评估(v2 核心):根因置信三档 CONFIRMED / LIKELY / INSUFFICIENT。只有 Caused-by 因果链直连才算 CONFIRMED;关键词投票、 时间连锁这类统计线索只到 LIKELY。证据不足时不输出「根因」措辞, 改为列出「还缺什么才能定论」—— 见第 1 节
    • 缺口自闭环:缺口清单由日志里实际有什么驱动。日志带 trace_id → 调用链重建成功 → 「缺少调用链关联」这条缺口自动关闭;一条都没有 → 如实申报并说清补什么格式就能补上。只加不减的缺口清单同样是不可信的
    • 错误因果关联(Caused-by 链 / 时间连锁 / 根因关键词)自动区分根因与连锁衍生
    • 统计异常检测(中位数 + MAD 稳健基线):集中爆发 / 周期发作 / 新型错误 / 罕见异常
    • 优先级综合评分(级别 35% + 频次 25% + 根因 20% + 异常 10% + 持续 5% + 新生 5%),按级别分档钳制
    • 堆栈降噪:折叠 java.base / site-packages / node_modules 等系统库与第三方帧,高亮业务栈帧
  • 多文件对比:2~3 个文件的新增 / 消失 / 共同错误与数量变化率,适配版本对比与修复验证
  • 可插拔解析规则引擎:YAML 声明规则,改配置不改代码即可接入新格式;内置 generic / embedded / jenkins 三套模板
  • 脱敏:内置规则(邮箱/手机号/身份证/密钥)+ 自定义正则,导出与复制时自动生效
  • 纯流式逐行处理:内存占用只与错误种类数相关,与日志总行数无关

Web 界面(v2)

  • 零构建、零 CDN:纯 HTML/CSS/JS,直接改完刷新就生效,完全离线可用
  • 三 Tab:文件导入 / 文本粘贴 / 多文件对比
  • 内置文件浏览器:服务与日志同机,直接挑本机文件,无需上传(7MB 日志也不走网络)
  • 实时 SSE 进度 + 可中途取消
  • 错误簇列表(级别/次数/优先级/根因/异常标记)+ 详情面板(典型样例 / 前后上下文 / 降噪堆栈 / 变量分布 / 全部实例)
  • 三张图表:错误时间分布(爆发段标红)/ 级别构成 / 模块分布 Top 10
  • 实时过滤:支持 and / or / not 布尔表达式(例:redis and not debug)
  • 一键导出:Markdown(投喂大模型)/ JSON / JSON 全文 / 纯文本 / HTML / 精简摘要
  • 亮色 / 暗色双主题

AI 解读(可选,不配置也完全可用)

在压缩结果之上再生成一段人话解读:「一句话结论 / 根因链 / 先查哪里 / 证据不足的部分」。

  • 三家通吃的 provider 接入:DeepSeek / 阿里百炼 Qwen / 智谱 GLM / Kimi / OpenAI / 本地 Ollama / 任意 OpenAI 兼容端点
  • 不配 API Key 也能用:聚类、根因判定、异常检测、导出全是本地算法,一分钱不花。AI 只是额外加一层
  • 只上传压缩后的证据摘要,不上传原始日志全文
  • 提示词显式约束「只依据给定证据、不得编造」,避免模型编造不存在的根因
log-ai-compressor ai status                      # 看当前配置
log-ai-compressor ai config --provider deepseek  # 选服务商
log-ai-compressor ai config --provider deepseek --key sk-xxx
log-ai-compressor ai test                        # 测连通性
log-ai-compressor ai explain app.log             # 生成解读
log-ai-compressor ai explain app.log --cluster 3 # 只解读某个错误簇

也可以在 Web 界面右上角「⚙ AI 设置」里点选配置。

MCP 接入(给 AI Agent 用)

2026 年可观测平台几乎都出了 MCP Server(阿里云 SLS、Datadog、Grafana…),MCP 把平台从「人去看的目的地」变成「Agent 可调用的数据源」。但那些平台的数据都在别人的机房里;本工具的数据就在你本机。

8 个只读工具(7 个分析 + 1 个取证):analyze_log_file / analyze_log_text / compare_log_files / export_report / get_cluster_detail / verify_evidence / list_rules / check_environment

log-ai-compressor mcp --install claude-code   # 打印配置片段
log-ai-compressor mcp --install codex
log-ai-compressor mcp --install mavis         # JSON 配置
log-ai-compressor mcp                         # 直接以 stdio 启动

接入后可以直接对 Agent 说:

分析一下 C:\logs\app.log,哪些错误是这次故障的根因?

Agent 会调用本工具做聚类、根因排序,并直接引用压缩后的证据摘要 —— 不需要把几十万行日志塞进上下文。

全部工具只读:没有删除、修改、上传、联网的接口。


5. CLI 使用

# 分析日志并导出 Markdown 报告(默认级别 ERROR,FAIL)
log-ai-compressor run examples/sample_system.log --top 20 -o report.md

# 指定级别、关键字、规则模板
log-ai-compressor run test.log --level ERROR,FAIL,WARN \
    --include "timeout,refused" --rule embedded --top 30 -o report.md

# JSON 格式
log-ai-compressor run test.log --format json -o report.json

# 多文件对比(第一个为基准)
log-ai-compressor compare examples/app_v1.log examples/app_v2.log -o diff.md

# 查看内置解析规则
log-ai-compressor rules list
子命令 用途
web 启动本地 Web 界面(主入口)
mcp 启动 MCP Server / 打印客户端配置
ai AI 解读的 status / config / test / explain
run 分析单个日志文件
compare 多文件对比
verify 复核结论出处:核对报告里的每条结论是否仍与原始日志一致
rules 查看解析规则模板

6. 实测数据

6.1 真实日志上的压缩与证据保留(Loghub 2.0)

数据来自 Loghub-2.0(ISSTA’24 配套数据集), 其 event template 为人工标注。对照组为 Drain3(ICWS’17 论文,821★)、 tail -N、grep。完整方法学、公平性说明与本文不能证明什么, 见 docs/BENCHMARK.md。

数据集 原始 本项目输出 Drain3 输出 本项目保留率 Drain3 保留率
Proxifier 624K tok 743 317 100% 72.7%
Apache 1.2M tok 548 431 100% 93.1%
Zookeeper 2.6M tok 470 980 92.1% 76.4%
HealthApp 5.1M tok 499 566,802 87.8% 83.3%
OpenStack 15.3M tok 746 73,569 50.0% 41.7%

证据保留率 5 个数据集全部领先。 但这个领先是补出来的,不是算法更强 —— 首轮实测是 3 胜 2 负,逐条追查后补了两个解析格式的洞(ZooKeeper 的 - LEVEL [模块] -、HealthApp 的 YYYYMMDD-HH:MM:SS:mmm|模块|ID|内容)。 在解析正常的日志上领先,是因为每簇保留了原始样例行作为可引用证据。详见 docs/BENCHMARK.md。

另一个差异在输出规模(口径:summary):输出有上界、与日志规模无关 —— 当前代码复测 313–788 tokens(上表为首轮旧口径跑分,绝对值已随版本 漂移,形状结论不变);Drain3 从 317 涨到 566,802(跨度 1789 倍)。 HealthApp 上 Drain3 压缩比只有 9x、耗时 578 秒,等于没压缩。

本节没有验证根因判定准确率 —— Loghub 标注的是日志模板,不是故障根因。

6.2 工程指标

指标 实测值
生产代码 7,575 行(32 个模块)
测试 1,043 用例,覆盖率 96%(漏行 156 / 3,883 语句),ruff 全绿
CI Ubuntu 3.11 / Ubuntu 3.12 / Windows 3.12 三矩阵全绿,六道门禁:ruff / 单测+覆盖率 / 对抗性评分卡 / 确定性指纹 / 自证脚本 / 构建可复现性。其中自证脚本现已断言 9 条主张,含「README 工程指标与架构树必须与仓库一致」
内存 与日志总行数无关,只与错误种类数相关
硬依赖 仅 PyYAML(web / mcp / ai 全部为可选 extra)

覆盖率不是目标,只是底线(CI 卡 90%)。真正卡回归的是那套对抗性评分卡 —— 覆盖率衡量「代码被执行过」,它衡量「该出错的时候会不会出错」。

6.3 速度

合成日志,仅供吞吐参考(不代表压缩效果,真实效果见 6.1): ~25 万行/秒,10 万行 / 7.03MB 用时 0.40 秒。复现:python scripts/benchmark.py


7. 技术架构

log_ai_compressor/
├── constants.py              # 全局常量(时间上限 / 内存有界参数 / 展示上限)
├── service.py               # 共享服务层:参数校验 + JSON 序列化 + 导出门面
├── __main__.py              # `python -m log_ai_compressor` 入口(退出码即契约)
├── rules/                   # 可插拔解析规则引擎(YAML 驱动)
│   ├── engine.py            #   规则加载/编译/占位符展开
│   └── presets/             #   generic / embedded / jenkins 三套模板
├── core/                    # 核心处理层(零 UI / 零 Web 依赖)
│   ├── models.py            #   数据模型 + 自适应时间直方图
│   ├── encoding.py          #   编码探测(BOM/严格解码验证/截断容忍)
│   ├── structured.py        #   结构化日志原生解析(JSON Lines / logfmt)
│   ├── parser.py            #   增量解析器(多行聚合:折行/堆栈/Caused-by)
│   ├── causal.py            #   Caused-by 因果链识别原语(摄入层与分析层共用)
│   ├── filters.py           #   级别 + 关键词准入过滤
│   ├── clustering.py        #   模糊指纹聚类(三级匹配)
│   ├── analysis.py          #   根因判定/异常检测/优先级/堆栈降噪/证据评估
│   ├── traces.py            #   调用链重建(trace_id / request_id 跨服务关联)
│   ├── evidence.py          #   证据引用 + 自校验 + 确定性指纹(取证层)
│   ├── pipeline.py          #   流式管线(进度/取消/上下文捕获)
│   ├── comparator.py        #   多文件对比
│   └── redact.py            #   脱敏
├── export/reporters.py      # 导出层(Markdown/JSON/文本/HTML/摘要)
├── web/                     # v2 Web 接入层
│   ├── server.py            #   FastAPI:REST + SSE + 文件浏览
│   ├── jobs.py              #   后台任务 + 进度队列 + SSE 帧
│   └── static/              #   零构建前端(index.html / app.js / style.css)
├── mcp/server.py            # MCP 接入层(8 个只读工具)
├── ai/                      # 可选 AI 解读层
│   ├── config.py            #   服务商配置(三层优先级 + Key 不回显)
│   ├── client.py            #   OpenAI 兼容 / Ollama 原生协议
│   └── prompts.py           #   提示词(显式约束防幻觉)
└── cli.py                   # 命令行入口

分层解耦:rules → core → export → service → web / mcp / cli 单向依赖。

  • core 零 UI 依赖,可独立测试、被脚本直接复用: from log_ai_compressor.core.pipeline import analyze_file
  • core/evidence.py 不 import 任何上层模块 —— 证据是比模型更底层的概念, 模型层反过来引用它。这让取证层可以被单独审计。
  • service 是 core 与接入层之间唯一的转换点,Web 和 MCP 共用同一份序列化逻辑,不会各写一份、各写错一份
  • 前端零构建:不引入 node/webpack,改完刷新即生效,也不需要 npm

核心算法

  1. 模糊指纹聚类(两级性能保护)

    • 指纹 = 级别 + 掩码消息(数字→N、十六进制→H、UUID→U、路径→P、引号串→S)+ 堆栈前 3 行特征
    • 匹配路径:完整指纹精确命中(O(1))→ (级别, 消息模板) 精确命中 → 同级别桶内编辑距离相似度(上限 256 次比较)
    • 变体命中后回写精确表,后续重复变体继续 O(1)
  2. 内存控制

    • 逐行流式读取,簇内只存「模板 + 计数 + 一份样例 + 有界直方图」
    • 时间直方图桶数上限固定(簇 96 / 全局 512),超限自动 8 倍扩宽桶宽合并旧桶
  3. 根因判定(三路证据融合):Caused-by 链回溯 + 60 秒窗口内首发且含根因关键词 + 强关键词命中;含 retry/after/downstream 等被动词的簇标记为连锁衍生


8. 开发与测试

pip install -r requirements-dev.txt

ruff check log_ai_compressor tests scripts     # 代码规范
python -m pytest                                # 全量测试
python -m pytest --cov=log_ai_compressor --cov-report=term-missing

测试分层:

文件 覆盖 速度
test_service.py 参数归一化、序列化、导出门面 < 1s
test_web.py REST 契约、SSE 帧格式、参数拦截、文件浏览边界 < 2s
test_mcp.py 工具注册、只读标注、各工具行为与错误路径 < 1s
test_ai.py 配置优先级、提示词、客户端(mock 网络)、可选性 < 1s
test_forensics.py 证据引用确定性、篡改/删除检测、指纹稳定性、CLI/MCP 入口 < 1s
test_structured_logs.py JSON/logfmt 字段别名、命名空间、误判防护、调用链与越界防线 < 1s
test_correctness_fixes.py 18 个已复现缺陷的回归测试(每条断言写成"修好后必须成立") < 1s
test_sdist_contents.py 交付物完整性:README 引用的每个文件都得在 sdist 里 < 1s
test_packaging.py 可选依赖契约、轻装可跑、降级不炸 ~2s
test_*.py(core) 解析 / 聚类 / 分析 / 导出 / 编码 / 对比 ~2s

另有一个不在 pytest 里的门禁:scripts/adversarial_eval.py。它测的不是 “函数返回什么”,而是"这个工具在该闭嘴的时候会不会闭嘴" —— 这类问题写不成 单元测试,只能用场景 + 评分表来表达。

CI(GitHub Actions)三矩阵:ubuntu-3.11(requires-python 下限)、 ubuntu-3.12(最常用版本)、windows-3.12(行尾 / shell / 路径处理与 unix 不同,且 start.bat 是 Windows 一等入口)。六道门禁:ruff → pytest + 覆盖率 ≥90% → 对抗性评分卡 → 确定性指纹 → 自证脚本 → 构建可复现性。 自证脚本内部已扩到 9 条主张(v2.8.0 起新增「README 工程指标与仓库一致」, v2.8.1 再加「README 架构树必须列全包内模块」)。

启动脚本的硬约束

start.bat 必须是纯 ASCII + CRLF 行尾,测试会强制校验。原因见 tests/test_launcher.py 顶部注释:cmd.exe 逐字节按控制台代码页解析批处理文件,用裸 LF 或含非 ASCII 字节都会导致解析错位、每行开头被吞,程序永远起不来。所有中文提示都放在 Web 界面里,不放 bat。


9. 它做不到什么

这一节比上面所有功能列表加起来都重要。看不下去可以不看了,但你会高估它。

它做不到 为什么 谁行
比云平台更高的根因准确率 多模态根因需要指标 + 链路 + 拓扑。RCA100 数据集的结论是 62.5% 的案例至少需要两种模态,31% 需要三种。本工具只有日志一种 Datadog / SLS / Dynatrace
持续监控与告警 没有 agent 埋点、没有时序库、没有告警队列。这是有意的取舍 全部 APM 平台
调用链追踪 traces 是从日志里的 trace_id 重建出来的,不是采集的。没有采样就没有精确耗时、没有 span 树 Jaeger / Tempo
「召回率」实测 只有 1 个含链真实数据集:Android_v1 全量(1,555,005 行 / 131 链 / 8 个根因类,报告口径召回 100%,精确率 100%、自信错误率 0%,可从公开来源完整复现)。原先并列的 Hadoop 91.4% / 5,921 链已于 v2.7.0 撤回 —— 该数据集来源不可得(见 BENCHMARK 撤回经过)。一个真实数据集撑不起「召回率」这个说法,这是本项目最实在的短板 —
隐私合规认证 它不处理合规,只保证「数据不出本机」 —

还有一条是方法论上的硬约束,写在代码里而不只是文档里:

调用链只证明顺序,不证明因果。 有完整 trace 但没有 Caused by: 时, 工具仍然只给 LIKELY、can_conclude=false。 CONFIRMED 的唯一来源始终是条目内 Caused-by 链。这条线一松, 「拿不出因果链就说不知道」的立场就作废了。 对抗评测里有一个场景专门盯它(structured_trace_not_causal)。


10. 自定义解析规则

新建 my_format.yaml:

name: my_format
description: 自研日志格式
patterns:
  - name: main
    # {LEVEL} 为引擎占位符,自动展开为标准级别令牌
    regex: '^\d+)>\s*\[(?P\w+)\]\s*(?P{LEVEL})\s*(?P.*)$'

stack_indicators:
  - '^\s*at\s+[\w$.]+\('

level_hints:            # 无级别字段的行按关键词推断(可选)
  ERROR: ['\bERROR\b', '\berror\b']

使用:log-ai-compressor run app.log --rule my_format.yaml


11. License

MIT

View this README on GitHub

Рекомендуемые инструменты

Попробуйте другой запрос или уберите фильтр.

Установка

npx skillfish add hu-chenyu/log-ai-compressor