# 改写标签与补充上下文

重命名或新增标签，或者调用你自己的接口，把返回的内容写回事件。

最后校对于 2026-10-10

这页办完你会得到：一个把事件标签改成你想要的样子的处理器，以及一条从外部系统 （CMDB、值班表、配置库）取信息补到事件上的路子。

两件事都在工作流的处理器里做，怎么建工作流见[事件 Pipeline](https://n9e.github.io/zh/docs/events/pipelines.md)。

## 改写标签：事件标签改写处理器[​](#改写标签事件标签改写处理器 "改写标签：事件标签改写处理器的直接链接")

处理器类型选 **事件标签改写**（分类是「改写」）。它就是 Prometheus 的 relabel， 只不过作用对象是**告警事件的标签**，不是采集上来的时间序列。

开源版有四种动作：

| 动作        | 干什么                                               |
| ----------- | ---------------------------------------------------- |
| `replace`   | 取源标签的值，用正则抽一段，写进目标标签（默认动作） |
| `labelmap`  | 按正则批量重命名标签名                               |
| `labeldrop` | 删掉标签名匹配正则的那些标签                         |
| `labelkeep` | 只保留标签名匹配正则的那些标签，其余全删             |

`replace` 的五个字段：

| 字段     | 默认值 | 说明                                    |
| -------- | ------ | --------------------------------------- |
| 源标签   | 空     | 可以填多个，按分隔符拼成一个串再做匹配  |
| 分隔符   | `;`    | 多个源标签之间的连接符                  |
| 正则     | `(.*)` | 对拼出来的串做匹配，用捕获组取值        |
| 值       | `$1`   | 写进目标标签的内容，`$1` 是第一个捕获组 |
| 目标标签 | 空     | **留空的话这个处理器什么都不做**        |

## 常用的四种写法[​](#常用的四种写法 "常用的四种写法的直接链接")

**给事件盖一个固定标签。** 只填目标标签和值，源标签和正则都不用管：

```
目标标签: team

值:       infra
```

**把一个标签复制成另一个名字。** 下游只认 `host`，事件上却是 `ident`：

```
源标签:   ident

目标标签: host

值:       $1
```

**从一个标签里抽一段出来。** 从 `n9e-web-01` 里抽出环境前缀：

```
源标签:   ident

正则:     ^([a-z0-9]+)-.*$

目标标签: cluster

值:       $1
```

**把两个标签拼成一个。** 用默认分隔符 `;`：

```
源标签:   env, service

正则:     (.*);(.*)

目标标签: scope

值:       $1/$2
```

改写发生在**屏蔽之前**，所以这里造出来的标签，屏蔽规则和订阅规则都能匹配到。

## 从外部系统取上下文：事件更新处理器[​](#从外部系统取上下文事件更新处理器 "从外部系统取上下文：事件更新处理器的直接链接")

开源版没有内置的字典表可查，补上下文的做法是**让夜莺去问你的服务**： 处理器类型选 **事件更新**，填一个 HTTP 地址。

它做的事情是：

1. 把整条事件序列化成 JSON，`POST` 到你填的地址；
2. 拿到响应体，**反序列化回这条事件**；
3. 事件带着新内容继续往下走。

所以你的服务只要做一件事：读入事件 JSON，按 `ident` 之类的标签去 CMDB 里查一把， 把查到的负责人、机房、业务线塞进事件的标签里，再把**完整的事件 JSON** 原样返回。 返回体不是一条完整事件，覆盖回去的字段就会缺。

配置项：

| 字段                   | 说明                     |
| ---------------------- | ------------------------ |
| URL                    | 必填，你的服务地址       |
| 授权用户名 / 密码      | Basic Auth，留空表示不带 |
| Header                 | 键值对，可以加多行       |
| HTTP Proxy             | 走代理时填               |
| Callback Timeout       | 毫秒，默认 10000         |
| TLS InsecureSkipVerify | 自签证书时打开           |

## 回调和事件更新的区别[​](#回调和事件更新的区别 "回调和事件更新的区别的直接链接")

两个处理器的表单长得一模一样，语义完全不同：

|            | Webhook 回调           | 事件更新                   |
| ---------- | ---------------------- | -------------------------- |
| 分类       | 外呼                   | 改写                       |
| 响应体     | **不看**，发出去就算完 | **读回来覆盖事件**         |
| 用来干什么 | 开工单、调自动化系统   | 补充上下文、修正字段       |
| 接口挂了   | 事件照常往下走         | 这个节点报错，事件不会被改 |

要「顺手通知一下外部系统」用回调；要「拿外部系统的答案改事件」用事件更新。

## 几个容易踩的点[​](#几个容易踩的点 "几个容易踩的点的直接链接")

* **目标标签留空 = 白配。** `replace` 不填目标标签时处理器静默什么都不做， 执行记录里的节点消息是「无变化」。
* **先改写，再按新标签做别的。** 处理器从上往下跑，顺序错了后面的条件就匹配不上。
* **外部服务要快。** 事件更新是同步阻塞的，超时默认 10 秒，这段时间通知一直等着。 查询慢的接口先加缓存，别把告警链路拖住。
* **别在回调里塞密钥。** 认证信息填在授权用户名/密码或 Header 里， 不要拼进 URL——URL 会出现在执行记录里。
* **改写的是事件标签，不是原始数据。** 时序库里的序列一个字没动，只有事件这一份变了。

## 下一步[​](#下一步 "下一步的直接链接")

* 改完怎么验证：[用模拟事件试跑](https://n9e.github.io/zh/docs/events/try-workflow.md)
* 看改写前后的差异串：[查看 Pipeline 执行记录](https://n9e.github.io/zh/docs/events/execution-records.md)
* 让新标签影响通知去向：[条件路由](https://n9e.github.io/zh/docs/events/routing.md)
* 标签本身的设计：[标签与附加信息](https://n9e.github.io/zh/docs/concepts/labels-annotations.md)
