dsh-log-parse
v0.1.0
Published
Log parser for DeepSeek Harness: auto-detect log format (common app logs, line-delimited JSON, syslog, custom regex), parse into structured entries, and summarize level distribution, timeline, top loggers and merged error templates. Zero runtime dependenc
Maintainers
Readme
dsh-log-parse
DeepSeek Harness 的日志解析工具箱:detect_format 抽样判定日志格式,parse_log 把日志解析成结构化条目并按级别 / 关键词过滤,log_stats 汇总级别分布、时间线、logger 与错误消息 Top N。支持常见应用日志、逐行 JSON、syslog 与自定义正则。只读、零运行时依赖。
- 源码:https://github.com/geeklei/dsh-plugins/tree/main/dsh-log-parse
- npm:https://www.npmjs.com/package/dsh-log-parse
功能说明
日志排查的难点往往不在「看」,而在「数」:一小时内错误集中在哪个时段?是同一个错误在刷屏,还是几十个不同错误?哪个模块在报错?纯靠肉眼翻文件很容易看走眼。本插件先把日志变成结构化条目,再把它变成能一眼看懂的统计表。
detect_format —— 先探明这是什么格式
来源:(内联文本)
文件行数:12(抽样前 12 行判定)
推荐格式:common
| 格式 | 匹配行 | 匹配率 |
| ------ | ------ | ------ |
| common | 12/12 | 100.0% |
| json | 0/12 | 0.0% |
| syslog | 0/12 | 0.0% |
解析建议:使用 parse_log / log_stats,可识别的排版形如「时间 [级别] logger: 消息」,未识别的部分会进入消息列。四种内置格式:
| 格式 | 识别对象 | 示例 |
|---|---|---|
| common | 应用日志(时间 + 级别 + logger + 消息) | 2026-10-01 03:12:01 [WARN] db: pool almost full |
| json | 逐行 JSON 日志 | {"time":"...","level":"error","msg":"db down"} |
| syslog | RFC3164 / RFC5424 系统日志 | Oct 1 03:12:01 web01 nginx[231]: upstream timed out |
| custom | 自定义命名分组正则 | 2026-10-01 03:12:01|ERROR|orders|create order failed|abc123 |
json 会按常见字段名自动取字段:级别取 level / lvl / severity / log_level / priority,时间取 time / timestamp / ts / @timestamp,消息取 msg / message / text / log,logger 取 logger / name / module / component / service,其余标量字段自动进入「附加」列,不丢信息。
parse_log —— 捞出错在哪
来源:(内联文本)
格式:common(自动判定,抽样 12 行匹配率 100.0%)
过滤:级别 ≥ WARN;不过滤关键词
行数:12 行(解析 12 行,失败 0 行,空行 0 行)
命中:6 条,按原顺序显示前 6 条
| # | 时间 | 级别 | logger | 消息 |
| --- | ------------------- | ----- | ------ | ------------------------------------------------ |
| 1 | 2026-10-01 03:12:03 | WARN | db | connection pool almost full (used=18/20) |
| 2 | 2026-10-01 03:12:03 | ERROR | db | connection timeout after 30000ms (host=10.0.0.7… |
| 3 | 2026-10-01 03:12:04 | ERROR | db | connection timeout after 30000ms (host=10.0.0.7… |
| 4 | 2026-10-01 03:12:07 | ERROR | http | GET /api/v1/orders 500 in 12000ms |
| 5 | 2026-10-01 03:13:02 | WARN | cache | hit rate below 60% |
| 6 | 2026-10-01 03:14:05 | ERROR | http | POST /api/v1/orders 500 in 1500ms |级别过滤支持列表与阈值两种写法:level="ERROR,WARN" 只看这两级,level=">=warn" 看 WARN 及以上。再叠加 filter 做关键词过滤(默认忽略大小写),就能把范围收窄到具体那条调用。
log_stats —— 一眼看清分布
来源:(内联文本)
格式:common(自动判定,抽样 12 行匹配率 100.0%)
行数:12 行(解析 12 行,失败 0 行,空行 0 行)
条目:12 条;带时间戳 12 条
时间:2026-10-01 03:12:01 ~ 2026-10-01 03:14:05(跨度 2m 4s)
时间桶:hour
| 级别 | 数量 | 占比 | 分布 |
| ----- | ---- | ----- | ---------- |
| INFO | 6 | 50.0% | ########## |
| ERROR | 4 | 33.3% | ####### |
| WARN | 2 | 16.7% | ### |
时间线(hour):
| 时间桶 | 条目 | ERROR+ | WARN |
| ---------------- | ---- | ------ | ---- |
| 2026-10-01 03:00 | 12 | 4 | 2 |
Top 4 logger:
| # | logger | 数量 |
| --- | ------ | ---- |
| 1 | http | 5 |
| 2 | db | 4 |
| 3 | app | 2 |
| 4 | cache | 1 |
Top 3 错误消息(已按模板归并数字 / ID / 引号内容):
| # | 数量 | 消息模板 |
| --- | ---- | ---------------------------------------- |
| 1 | 2 | connection timeout after <n> (host=<ip>) |
| 2 | 1 | GET /api/v<n>/orders <n> in <n> |
| 3 | 1 | POST /api/v<n>/orders <n> in <n> |错误消息表会先把易变部分抹平(数字、UUID、IP、十六进制串、引号内容、多余空白),再按模板计数,因此「同一个错误换了个订单号」不会再被算成两条。bucket 可指定 second / minute / hour / day,默认按时间跨度自动选择:跨度 ≤ 10 分钟用秒桶,≤ 3 小时用分钟桶,≤ 2 天用小时桶,再长用天桶。
关于级别
内置级别为 TRACE / DEBUG / INFO / NOTICE / WARN / ERROR / FATAL,常见别名会归一:warning → WARN,err → ERROR,crit / panic / emergency → FATAL,中文 信息 / 警告 / 错误 / 致命 同样识别。syslog 与部分自定义格式本身没有级别字段,此时级别为 -;需要按级别统计时可开启 infer_level,按消息关键词推断(timeout / failed / exception → ERROR,panic → FATAL,deprecated → WARN,debug → DEBUG)。
安装
npm install dsh-log-parse安装后在 cordis.patch.yml 中加入:
- insert:
- id: log-parse
name: "dsh-log-parse"使用说明
detect_format
| 参数 | 类型 | 说明 |
|---|---|---|
| path | string | 日志文件路径(与 text 二选一) |
| text | string | 内联日志内容(优先于 path) |
| sample | number | 抽样行数,默认 20,上限 500 |
| pattern | string | 自定义正则,提供时会额外统计 custom 匹配率 |
| max_chars / max_size | number | 输出字符上限 / 文件大小上限 |
用户:这个日志文件是什么格式
detect_format(path="app.log")用户:这份日志能不能按自定义正则解析
detect_format(text="2026-10-01 03:12:01|ERROR|orders|create order failed|abc123", pattern="^(?<time>[^|]+)\|(?<level>[^|]+)\|(?<logger>[^|]+)\|(?<message>[^|]+)\|(?<req>[^|]+)$")parse_log
| 参数 | 类型 | 说明 |
|---|---|---|
| path / text | string | 日志来源(二选一,text 优先) |
| format | string | auto(默认)| common | json | syslog | custom |
| pattern | string | 自定义正则,format=custom 时必填,需含命名分组 |
| level | string | 级别过滤:ERROR,WARN 列表或 >=warn 阈值 |
| filter | string | 消息关键词过滤(子串) |
| filter_case_sensitive | boolean | 关键词区分大小写,默认 false |
| infer_level | boolean | 无级别字段时按关键词推断,默认 false |
| limit | number | 最多输出条目数,默认 50,上限 500 |
| max_lines | number | 最多解析行数,默认 20000,上限 200000 |
| max_chars / max_size | number | 输出字符上限 / 文件大小上限 |
用户:今天日志里有哪些错误
parse_log(path="app.log", level=">=error", limit=100)用户:查一下跟订单接口有关的告警
parse_log(path="app.log", level=">=warn", filter="orders")用户:JSON 日志里搜 timeout
parse_log(path="app.jsonl", format="json", filter="timeout")log_stats
| 参数 | 类型 | 说明 |
|---|---|---|
| path / text | string | 日志来源(二选一,text 优先) |
| format | string | 同上,默认 auto |
| pattern | string | 同上 |
| bucket | string | auto(默认)| second | minute | hour | day |
| top | number | logger / 错误消息 Top N,默认 5,上限 50 |
| infer_level | boolean | 是否按关键词推断级别,默认 false |
| timeline_limit | number | 最多输出时间桶数,默认 50,上限 500 |
| max_lines / max_chars / max_size | number | 同 parse_log |
用户:这一天的日志整体情况怎么样
log_stats(path="app.log", bucket="hour")用户:错误都集中在哪个时间段
log_stats(path="app.log", bucket="minute", top=10)典型场景
- 格式摸底:拿到不熟悉的日志先
detect_format,看清是什么排版、是否混合了多行堆栈。 - 故障定位:
parse_log用>=error加关键词缩到具体调用,再用log_stats看错误集中在哪个时间桶。 - 刷屏识别:
log_stats的错误消息模板 Top N 直接告诉你「是同一个错误刷了 3000 次,还是 3000 个不同错误」。 - 服务归属:logger Top N 看出哪个模块最吵;结合时间线判断是某个模块整体异常还是全站抖动。
- syslog 巡检:系统日志没有级别字段时开启
infer_level,按消息关键词补齐级别后再统计。 - 自定义排版:日志格式特殊时用
pattern传命名分组正则,一次说清楚 time / level / logger / message 各在哪。 - 跨语言排查:中文日志的级别词(信息 / 警告 / 错误 / 致命)同样识别。
- 行数盘点:解析成功与失败行数一目了然,避免「以为是全量统计,其实只解析了一半」。
安全边界
- 只读:三个工具都不写入、不修改、不删除文件;测试含源文件 size/mtime 不变的只读性断言。
- 不访问网络:解析与统计全部在本地完成,无任何外部请求。
- 不执行输入:只做文本匹配与数值统计,不做
eval、不加载模块;pattern只用于构造RegExp。 - 正则来源可控:
pattern由使用者显式传入,插件不会从日志内容里动态生成正则。 - 二进制拒绝:读取时检测 NUL 字节,疑似二进制文件直接拒绝解析。
- 多层上限:文件大小上限 51200 KB(默认 20 MB)、输出字符上限 200000、解析行数上限 200000(默认 20000)、抽样行数上限 500、输出条目上限 500。超限即拒绝或截断并显式提示。
- 不脱敏:日志原文进入「消息」列展示,仅按显示宽度截断(影响展示,不影响统计)。日志里可能含密钥、令牌、个人信息,需要分享结果时请先用
dsh-credential-scan检查。 - 不做语义解释:级别只按字段值或关键词推断,不从消息内容推断业务含义;统计口径(哪些字段算 ERROR、模板如何归并)在输出中明确写出。
其他插件集成说明
| 协作插件 | 集成方式 |
|---|---|
| dsh-credential-scan | 分享日志片段前扫描其中是否混入密钥、令牌 |
| dsh-regex-lab | 先在 regex-lab 里调好自定义正则,再作为 pattern 交给 parse_log |
| dsh-text-stats | 日志整体体量、词频统计与结构化统计互补 |
| dsh-similarity | 对错误消息做相似度聚类,进一步合并「像但模板不同」的错误 |
| dsh-table-render | 把统计结果转成更完整的表格视图 |
| dsh-diff-writer | 对比两个时间段的日志统计,输出差异报告 |
| dsh-session-exporter | 把排查过程中的命令与结论归档成记录 |
| dsh-chart-ascii | 把时间线数据画成终端趋势图,直观看峰值时段 |
| dsh-file-search | 先按文件名与大小定位日志文件,再交给本插件解析 |
版本说明
- 0.1.0(2026-10-03):初始版本。
detect_format:抽样判定 common / json / syslog / custom,输出各格式匹配率与解析建议parse_log:解析为结构化条目,支持级别阈值与列表过滤、关键词过滤、条目数上限;json 自动识别 level / time / message / logger 常见字段名log_stats:级别分布与占比、时间范围与跨度、按时间桶的错误 / 警告时间线、logger Top N、错误消息模板 Top N- 时间戳支持 ISO、
YYYY-MM-DD HH:mm:ss、秒 / 毫秒 / 纳秒时间戳、syslog 无年份格式(按当前年份补全) - 自定义正则需含命名分组(time / level / logger / message 与任意附加字段)
- 二进制拒绝、多层上限与多行截断提示
RoadMap
v0.2(计划)
parse_log增加context:命中行附带前后 N 行,保留多行堆栈信息log_stats增加group_by:按 logger / 级别自定义分组的交叉统计- 支持多行日志合并(以时间戳重新分段的堆栈拼接)
- 新增
log_grep:只做过滤不做统计的轻量模式,适合超大文件流式扫描
v0.3(展望)
- 流式读取超大文件(按块解析,不整体载入内存)
- 时间线输出按级别分列的堆叠视图
- 与
dsh-chart-ascii联动,直接输出趋势图 - 结果输出 JSON 结构,便于接入其他工具链
FAQ
Q:为什么解析成功行数比文件行数少?
失败行通常是多行堆栈的续行、启动横幅或格式不一致的行。parse_log 会分别给出「解析行、失败行、空行」三个数字,失败行不会被静默丢弃。需要保留堆栈时可以先用 detect_format 确认排版,或增加 context(RoadMap 中)后用 dsh-line-ops 截取上下文。
Q:auto 判定错了怎么办?
显式传 format 覆盖即可。自动判定是对抽样行做匹配率比较,若日志开头是 banner(如版本号、启动分隔线)会拉低匹配率;此时用 sample 提高抽样行数,或直接指定格式。
Q:syslog 的级别为什么是 -?
RFC3164 格式本身不含级别字段,只有 facility / severity 优先级编码。本插件不猜测优先级编码语义,需要按级别统计时开启 infer_level 从消息关键词推断。
Q:错误消息模板里的 <n>、<ip>、<str> 是什么?
是归一化占位符:<n> 代表数字(含 ms / s / % 等单位)、<ip> 代表 IP 及端口、<uuid> 代表 UUID、<hex> 代表长十六进制串、<str> 代表引号包裹的内容。目的是把「同一个错误 + 不同参数」合并计数。
Q:时间桶为什么自动选了 second?
auto 按日志的时间跨度选:≤ 10 分钟用秒桶,≤ 3 小时用分钟桶,≤ 2 天用小时桶,更长用天桶。想要固定粒度就直接传 bucket。
Q:时间戳没有年份(syslog 常见)会怎样? 按当前年份补全。跨年的历史日志建议在解析前用文本工具补上年份,或改用带年份的自定义正则。
Q:日志文件很大能处理吗?
默认最多解析 20000 行(可用 max_lines 调到 20 万),文件大小默认上限 20 MB(可用 max_size 调整)。超限会截断或拒绝,并在输出中明确提示未解析的行数,不会给出「看起来完整」的假统计。
Q:filter 是正则吗?
不是,是子串匹配(默认忽略大小写)。需要正则时用 pattern 定义字段切分,再用 filter 在消息里做子串筛选。
Q:能直接过滤掉某些日志吗? 可以按级别和关键词收窄;插件只读,不会改写日志文件。
源码与发布地址
- 源码:https://github.com/geeklei/dsh-plugins/tree/main/dsh-log-parse
- npm:https://www.npmjs.com/package/dsh-log-parse
许可证
MIT
