跳到主要内容

数据战报模板:周报 / 月报(字段全部可核对)

2026-10-13安全运营 6 分钟阅读 2826 字一份可以直接照着填的周报/月报骨架:每一格都写明它来自哪个公开端点、哪个字段、什么口径,以及「取不到的时候写什么」。模板的价值不在于好看,而在于它逼你回答「这个数字到底是怎么算出来的」。

这份模板是干什么的

安全运营最容易被问倒的一句话是:

“你说这周拦了多少?怎么算出来的?”

大部分周报在这里就崩了 —— 因为数字是从某个界面上抄来的, 而界面背后的口径没人说得清。这份模板的目的是在填数字之前,先被逼着写口径。

三条纪律(比模板本身重要):

  1. 每一格都写清来源:端点 + 字段 + 口径;
  2. 没有相对量就不编:公开端点给不出"上周/上月"的,就如实写"24h / 窗口内 / 近 7 天";
  3. 取不到就写"未接入":不补数、不用 0 冒充、不用样本顶替。

一、指标带(四组,全部来自公开只读端点)

1. 告警

指标来源字段口径取不到时写
24h 告警总量GET /api/public/alertsstats24h.total24 小时未去重上报量未接入
24h 严重 / 高危同上stats24h.bySeverity.CRITICAL / .HIGH同一 24h 桶未接入
24h 逐小时曲线同上stats24h.trend[]25 个小时桶(跨 24h 窗口)服务端未返回逐小时桶
当前窗口聚合条数同上total去重后的聚合条数(不是原始条数)未接入
窗口原始条数同上rawTotal最近 N 条(windowSize)中的原始条数未接入

⚠️ 最容易混的一对:total(去重聚合)与 rawTotal(原始)。 这两个数差好几倍是正常的,混着用就是错的口径。 写周报时必须写明用的是哪一个。

2. 蜜罐

指标来源字段口径取不到时写
蜜罐累计事件GET /api/public/honeypottotal服务端字段原样未接入
连接 / 登录 / 登录失败同上connections / logins / loginFails同一响应内的字段未接入
来源 Top N同上topSources[]采样窗口(sampled)内的真实计数没有来源数据
尝试口令结构同上topCredentials[] 现算长度分桶 / 是否与用户名相同 / 字符构成本次没有可归纳的尝试口令
客户端指纹 Top同上topClients[]采样窗口内计数没有客户端指纹
命令时间线——commandsAvailable=false数据源未接入数据源未接入(永远如此)

3. 护栏 / 处置审计

指标来源字段口径取不到时写
护栏拦下的动作数GET /api/public/auditsummary.blockedByGuard被护栏拦下、没执行的动作未接入
封禁留痕条数同上summary.blockTotal历史留痕总条数未接入
当前生效中的封禁同上summary.blockActive仍在封禁期内未接入
已执行动作数同上summary.executedActions真执行过的处置动作未接入
今日拦截同上blocks[].createdAt 归日现算创建于今天的封禁留痕条数未接入

⚠️ “今日拦截"是现算的:它等于”createdAt 落在今天的留痕条数", 不是“今天的告警数”、也不是“今天的蜜罐攻击数”。 如果后端将来给一个明确的今日字段,这里应改成用那个字段。

4. 通道与指纹

指标来源字段口径
节点在线状态GET /api/public/overviewnodes[].online服务端 probe 结果,不是 ping
数据源是否降级同上dataSource.degradedtrue 表示拿不到真实数据
镜像指纹一致GET /api/healthfingerprintMismatchfalse = 一致(硬证据,不是自述)
固化 commit同上embeddedGitCommitjar 内固化(硬证据)
制品 MD5同上artifactMd5镜像内 jar 的 MD5(硬证据)
环境自述 SHA同上buildSha非证据(接口自己标注了),不要写进周报结论

⚠️ 最后一行是这套接口设计里最值得抄的一点:它自己区分了"自述"与"硬证据"。 周报里引用指纹时,请只引用后三行。


二、本周/本月变化:怎么写才不算编

能写的(真的能算):

  • 同一 24h 窗口内的"最近 1 小时 vs 前 3 小时均值"——两个数字都来自 stats24h.trend, 现算,且把两个原始数字一起写出来(读的人可以自己核);
  • 占比:如"高危占 24h 总量的比例"= bySeverity.HIGH / stats24h.total;
  • 构成:如"来源构成 Suricata × / Wazuh ×"(overview.alerts.bySource);
  • 同一响应内的相对量:如蜜罐的"连接 / 登录 / 登录失败"三个数之间的关系。

不能写的(除非后端先给):

  • ❌ “较上周 +N%” —— 公开端点没有上周口径(stats24h 只有 24 小时,没有日/周桶);
  • ❌ “本月累计” —— 没有月粒度聚合;
  • ❌ “7 天 × 24 小时热力格” —— 没有历史日桶。

取不到相对量时的正确写法(照抄这个句式):

24h 告警 111,308 条(口径:/api/public/alerts · stats24h.total,24 小时未去重)
本周变化:未接入 —— 公开端点只提供 24 小时窗口,没有周粒度聚合,
          因此本项不给"较上周"的比较,避免用一个自造的基准。

这一句比一个编出来的百分比有价值得多 —— 它把"我没编"这件事本身变成了一个可核对的事实。


三、周报骨架(直接用)

# 安全运营周报 · {{YYYY-MM-DD}} ~ {{YYYY-MM-DD}}

## 0. 一句话结论
(本周最重要的一件真实的事。没有就写"本周无重大事件"。)

## 1. 数据(全部来自公开只读端点,口径随数字)

| 指标 | 数值 | 相对量 / 构成 | 口径 | 同步时间 |
|---|---|---|---|---|
| 24h 告警 | | | alerts · stats24h.total(未去重) | |
| 24h 高危占比 | | | stats24h.bySeverity.HIGH / total | |
| 蜜罐事件 | | 连接 / 登录 / 登录失败 | honeypot · total | |
| 蜜罐来源 Top | | | honeypot · topSources(采样窗口) | |
| 护栏拦截 | | 封禁留痕共 N 条 · 生效中 M | audit · summary | |
| 节点 / 数据源 | | 在线 / 降级 | overview · nodes / dataSource | |
| 指纹 | | 一致 / 不一致 | health · fingerprintMismatch | |

## 2. 本周变化
(只写能算的。算不出来的项,写明"未接入 + 原因",不编基准。)

## 3. 值得说的一件事
(挑一件做过的:判据、代价、证据。不要写"加强了监控"这种没有主语的话。)

## 4. 没做到 / 有疑虑
(至少写一条。写不出来通常说明没细看。)

## 5. 口径变更
(本周改过哪些数字的算法或字段。没有就写"无"。)

四、月报要多写的一节

月报和周报的唯一实质区别:月报应该能回答"这个月比上个月怎么样"。 但在公开端点给不出月粒度之前,正确做法是明确说做不到,并给出替代:

## 月度趋势
未接入:公开端点只提供 24 小时窗口(stats24h 没有日/周/月桶),
因此本节不提供"较上月"的比较。替代信息:
  · 本月的极值样本(逐次人工记录的 24h 总量)——
    这与"自动聚合的月度趋势"不是一回事,口径不同,不能混用。
建议后端补:/api/public/overview 增加 dayBuckets[](近 30 天日聚合)。

最后一行是这份模板真正的用途:它把"我想看的数字"变成一条可提交的后端字段需求, 而不是一句"数据不够所以没法做"。


五、自动生成骨架

本仓库提供一键脚本 scripts/new-note.ps1,可以生成一篇带正确 front matter 的 md:

# 生成一篇周报骨架(默认只落盘,不提交、不推送)
.\scripts\new-note.ps1 -Title "安全运营周报 2026-W42" -Category "安全运营" `
  -Tags "周报,安全运营" -Summary "本周数据与口径"

脚本生成的文件带 draft: true,写完了自己把 draft 改成 false 才算发布 —— 这样"忘了检查就发出去"的路径是关的。


小结

这份模板里没有一个数字是示例值 —— 它只提供字段名、口径、和取不到时的写法。

一份好的周报模板,是让人没法在"这个数字怎么来的"这个问题上含糊过去。


本文所有端点、字段名与口径均来自本项目公开接口的真实响应体(2026-10-13 复核)。