cyntra360hub/alert-dedupe
GitHub: cyntra360hub/alert-dedupe
一个纯 Python 的确定性告警去重与分组代理,从可插拔的 webhook 文件源读取告警并输出按噪声排名的合并摘要,无需 LLM 或服务器。
Stars: 0 | Forks: 0
[](https://aiopsenabler.com/agents/alert-dedupe)
# alert-dedupe
一个小巧、确定性的 Python agent,它从可插拔的源读取告警流,并输出一个**去重、分组后的摘要** —— 不需要 LLM 调用,不需要付费 API,也不需要运行服务器。
## 功能
1. 从包含 webhook 格式 JSON 文件的目录中加载告警(参见下文的“Webhook 文件格式”)—— 默认情况下,会读取 `src/alert_dedupe/data/sample_feeds/` 中内置的示例数据源。
2. 为每个告警计算一个确定性指纹:如果源提供了该字段,则使用告警自身的 `fingerprint` 字段(大多数真实的告警系统都会提供 —— 例如 PagerDuty 的 `dedup_key`),否则根据 `(source, service, severity, normalized title)` 派生。
3. 将共享相同指纹的告警进行分组,按组的大小进行排名(最嘈杂的排在最前),并报告每个组的最高严重级别和贡献源。
## 安装
要求 Python 3.12+。
```
pip install .
```
## 用法
```
alert-dedupe
```
或者作为模块运行:
```
python -m alert_dedupe.cli
```
### Webhook 文件格式
将 `ALERT_DEDUPE_INPUT_DIR` 指向一个包含 `*.json` 文件的目录 —— 每个文件是一个 JSON 对象(或一个纯数组,被视为 `generic`)。一个可选的顶级 `"format"` 键用于选择由哪个适配器来解析文件的其余部分(如果省略则为 `"generic"`),这样一个目录就可以混合存放来自多个真实告警源的文件:
```
// generic (default) — a flat list matching Alert's own fields
{
"format": "generic",
"alerts": [
{"id": "1", "source": "datadog", "title": "CPU high", "severity": "warning", "service": "api"}
]
}
```
开箱即用地提供了两个说明性的、特定源形状的适配器
(`src/alert_dedupe/adapters.py`)—— `"pagerduty"` 和 `"datadog"`,
它们是这些系统真实 webhook 形状的简化替代品,用于展示该模式,而不是精确匹配 schema。**添加你自己的适配器只需要一次函数调用:**
```
from alert_dedupe.adapters import register_adapter
def my_source_adapter(raw: dict) -> list[Alert]:
...
register_adapter("my-source", my_source_adapter)
```
然后在该源的文件中设置 `"format": "my-source"` 即可。
### 配置(环境变量)
| 变量 | 默认值 | 含义 |
|---|---|---|
| `ALERT_DEDUPE_INPUT_DIR` | 内置示例数据源 | 存放 webhook 格式 JSON 文件的目录 |
| `ALERT_DEDUPE_ESCALATE_THRESHOLD` | `5` | 达到或超过此规模的组会被标记为 `[ESCALATE]` 并报告为 `escalated` |
复制 `.env.example` 为 `.env` 以在本地设置这些变量;`.env` 已被 gitignore,永远不会被提交。
## 可选:AiOps Enabler 集成
alert-dedupe 可以选择将每次运行作为已签名的任务事件报告给
[AiOps Enabler](https://aiopsenabler.com),这是一个记录已验证 AI agent 性能的公共利益注册表。**这是可选的,且默认关闭** ——
除非你显式配置凭证,否则该 agent 绝不会主动进行外部网络请求。
报告功能被实现为**原始的 HMAC 签名 REST 请求**
(`src/alert_dedupe/signing.py` + `reporting.py`),直接根据
平台自身发布的规范([skill.md](https://aiopsenabler.com/skill.md) §3,
[api-guide.md](https://aiopsenabler.com/api-guide.md) §2)构建,仅使用
标准库。这是对官方文档记录的 Python SDK(`aiops-enabler`)的有意替代:其安装命令
指向 `github.com/cyntra360hub/aiops-enabler`,目前这是一个**私有**仓库,尽管它是为外部集成商记录的官方途径,但公众无法安装。原始的签名 REST 请求绕过了这个问题,且在功能上是等效的(相同的 headers、相同的签名方案、
相同的已发布测试向量 —— 详见 `tests/test_signing.py`)。
要启用它,请设置两个环境变量(在本地设置于 `.env` 中,或者在 CI 中设置为
GitHub Actions secrets —— 参见 `.github/workflows/scheduled.yml`):
```
ALERT_DEDUPE_AGENT_KEY_ID=ak_...
ALERT_DEDUPE_AGENT_SECRET=...
```
两者均设置后,每次运行都会向 `POST /api/v1/events` 发送一对已签名的 `task_started` / `task_completed` 事件,当任何组达到 `ALERT_DEDUPE_ESCALATE_THRESHOLD` 时,`outcome` 将被设置为 `escalated`,否则为 `success`。
### README 徽章
此文件顶部的徽章是 AiOps Enabler 公开、CDN 缓存、无需身份验证的徽章端点 —— `GET /badge/{slug}.svg` —— 可以安全地嵌入到任何没有 API key 的第三方 README 中。发布后,它会显示该 agent 的实时评分;**在操作员发布此 agent 的配置信息之前,它会返回 404**(参见 [skill.md](https://aiopsenabler.com/skill.md)
第 2 节 —— 在发布之前,已签名的请求仍然会成功并被记录,只有*公开*的徽章/配置需要这个额外步骤)。如果你 fork 了此项目,请将徽章 URL 中的 `alert-dedupe` 替换为你自己 agent 的 slug。
### 评分微件
除了静态徽章外,AiOps Enabler 还为 agent 的 UI 提供了一个可嵌入的
“Rate me 👍👎”(给我评分 👍👎)微件,以便最终用户可以直接对交互进行评分:
- **脚本嵌入:** `GET https://api.aiopsenabler.com/widget/{slug}.js`
- **Iframe 嵌入:** `GET https://api.aiopsenabler.com/widget/{slug}`
- 提交的数据会发送到 `POST /api/v1/agents/{slug}/widget-rating` —— 公开且
**未签名**(改为通过 IP + slug 进行限流),因为它旨在直接从无法保证密钥安全的浏览器中调用。这与本仓库自身签名的 `POST /api/v1/ratings`
路径不同(该路径由 agent 的*后端*使用,在这里不适用,因为 alert-dedupe 是一个 CLI 工具,没有可嵌入微件的最终用户界面)—— 此处记录是为了保持完整性,供确实有界面的 fork 版本使用。
## 开发
```
pip install -e ".[dev]"
pytest
```
所有测试均在完全离线状态下运行 —— 没有任何网络调用;内置的示例数据源将直接从磁盘读取。
## 许可证
MIT —— 详见 [LICENSE](LICENSE)。
标签:AIOps, Python, 告警去重, 安全规则引擎, 无后门, 自动化代理, 运维, 逆向工具