> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flashduty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# LibreNMS 告警集成

> 通过 LibreNMS 的 API 告警通道将设备告警同步到 Flashduty On-call，告警规则恢复时自动关闭告警。

LibreNMS 通过 **API** 类型的告警通道（Alert Transport）推送告警：每次告警规则触发、变化或恢复，LibreNMS 按本文给出的请求体模板向 Flashduty 发送一条 JSON。每个「设备 + 告警规则」对应一条 Flashduty 告警：规则触发时打开，规则恢复时自动关闭。

<div className="hide">
  ## 在 Flashduty On-call

  ***

  您可通过以下两种方式获取集成推送地址，任选其一即可。

  ### 使用专属集成

  1. 进入 Flashduty 控制台，选择 **协作空间**，打开一个协作空间
  2. 选择 **配置** → **集成数据** → **专属集成**，点击 **新增一个集成**
  3. 选择 **LibreNMS**，点击 **保存**
  4. 打开生成的集成卡片，复制 **推送地址**

  ### 使用共享集成

  1. 进入 Flashduty 控制台，选择 **集成中心 → 告警事件**
  2. 选择 **LibreNMS**，填写集成名称
  3. 配置默认路由并选择协作空间；创建后可在 **路由** 中增加更多规则
  4. 点击 **保存**，复制生成的 **推送地址**
</div>

## 在 LibreNMS 中配置

***

以下步骤需要 LibreNMS 25.7.0 或更高版本：请求体模板用 `json_encode` 过滤器转义文本字段，这个过滤器从 25.7.0 开始提供。

<Steps>
  <Step title="创建告警通道">
    进入 **Alerts → Alert Transports**，点击 **Create alert transport**，按下表填写：

    | 字段                 | 填写内容                                                                     |
    | :----------------- | :----------------------------------------------------------------------- |
    | **Transport name** | 自定义名称，例如 `Flashduty`                                                     |
    | **Transport type** | `API`                                                                    |
    | **API Method**     | `POST`                                                                   |
    | **Send as form**   | 不勾选                                                                      |
    | **API URL**        | 推送地址中 `?` 之前的部分，即 `https://api.flashcat.cloud/event/push/alert/librenms` |
    | **Options**        | `integration_key=<推送地址中 integration_key 的值>`                             |
    | **headers**        | `Content-Type=application/json`                                          |
    | **body**           | 下方的请求体模板                                                                 |

    <Warning>LibreNMS 会丢弃 **API URL** 中 `?` 之后的参数，只把 **Options** 中的内容作为查询参数发送。`integration_key` 必须填在 **Options** 中，写在 **API URL** 里会导致请求被拒绝。</Warning>

    请求体模板：

    ```json theme={null}
    {
      "alert_id": "{{ $alert_id }}",
      "rule_id": "{{ $rule_id }}",
      "device_id": "{{ $device_id }}",
      "state": "{{ $state }}",
      "severity": "{{ $severity }}",
      "rule": {{ $name|json_encode }},
      "hostname": {{ $hostname|json_encode }},
      "sys_name": {{ $sysName|json_encode }},
      "os": {{ $os|json_encode }},
      "location": {{ $location|json_encode }},
      "msg": {{ $msg|json_encode }}
    }
    ```

    模板中带 `|json_encode` 的字段不要再加引号：过滤器会输出带引号并已转义的 JSON 字符串，规则名称或告警正文中的引号、换行不会破坏 JSON。

    其余字段保持默认，点击 **Save** 保存。
  </Step>

  <Step title="将通道关联到告警规则">
    LibreNMS 26.4.0 起，告警规则通过 **Operation** 指定通知通道；更早的版本在规则中直接选择 **Transports**。按您的版本操作：

    **LibreNMS 26.4.0 及以上**

    1. 进入 **Alerts → Operations**，新建一个 Operation，或编辑规则已使用的 Operation
    2. 在一个分段（segment）中加入上一步创建的通道；新建时可设置 **Steps from** 为 `1`、**Steps to** 为 `1`、**Start (s)** 为 `0`，规则匹配后立即发送一次
    3. 进入 **Alerts → Alert Rules**，编辑需要推送的规则，在 **Operation** 中选择该 Operation

    没有关联 Operation 的规则只在 LibreNMS 中产生告警，不发送任何通知。

    **LibreNMS 25.7.0 至 26.3.x**

    进入 **Alerts → Alert Rules**，编辑需要推送的规则，在 **Transports** 中选择上一步创建的通道。也可以在通道上勾选 **Default Alert**，让未指定通道的规则都使用它。

    两种版本都要确认规则的 **Recovery alerts** 为开启状态，否则规则恢复时 LibreNMS 不发送通知，Flashduty 中的告警不会关闭。最后点击 **Save Rule**。
  </Step>

  <Step title="验证生命周期">
    在 **Alerts → Alert Transports** 列表中点击该通道右侧的测试按钮（黄色对勾图标，提示为 **Test transport**），确认 LibreNMS 提示测试成功。测试通知使用 LibreNMS 固定的测试数据（`alert_id` 为 `000`），Flashduty 返回成功，不会生成告警。

    然后让一条规则真正触发（例如让一台被监控设备不可达，使 **Devices up/down** 规则告警），确认 Flashduty 收到活动告警；恢复设备后，确认原告警关闭。LibreNMS 在每次轮询后检查告警规则，告警和恢复通常在一个轮询周期（默认 5 分钟）内送达。
  </Step>
</Steps>

## Alert Key

***

Flashduty 使用 `alert_id` 作为 Alert Key。`alert_id` 是 LibreNMS `alerts` 表中的行 ID，每个「设备 + 告警规则」只有一行，触发、变化和恢复通知都携带同一个值；LibreNMS 自带的 PagerDuty 通道也用它作为去重键。因此同一台设备上同一条规则的通知落在同一条告警上，规则恢复后再次触发会打开一条新告警。

告警等级、规则名称、主机名、告警正文的变化都不会改变 Alert Key。`alert_id` 只在一个 LibreNMS 实例内唯一：多个 LibreNMS 实例请分别使用不同的 Flashduty 集成。

请求缺少 `alert_id` 或 `state` 时，Flashduty 会拒绝该请求。

## 告警生命周期

***

Flashduty 按 `state` 字段处理通知：

| LibreNMS `state` | 含义            | Flashduty 处理 |
| :--------------- | :------------ | :----------- |
| `1`              | 告警触发          | 触发告警，或更新已有告警 |
| `3`              | 告警恶化（匹配的对象增多） | 更新告警         |
| `4`              | 告警好转（匹配的对象减少） | 更新告警         |
| `5`              | 告警变化          | 更新告警         |
| `0`              | 告警恢复          | 恢复告警         |
| `2`              | 告警已确认         | 忽略           |

使用 Operation 的规则（LibreNMS 26.4.0 及以上）只发送触发、确认和恢复通知，不发送 `state` 为 `3`、`4`、`5` 的通知；这三种通知只在规则直接选择 **Transports** 时发送（25.7.0 至 26.3.x）。

规则开启 **Acknowledgement alerts** 后，LibreNMS 会在告警被确认时发送 `state` 为 `2` 的通知。确认不会打开或关闭 Flashduty 告警，被忽略的通知返回成功。

## 告警等级

***

告警等级取自告警规则的 **Severity**：

| LibreNMS Severity | Flashduty 等级 |
| :---------------- | :----------- |
| `critical`        | Critical     |
| `warning`         | Warning      |
| `ok`              | Info         |
| 其他值或为空            | Critical     |

恢复通知携带同一条规则的 Severity，恢复事件保留该等级。

## 告警内容

***

* **标题**：`<规则名称> on <主机名>`；规则名称为空时用 `LibreNMS rule <rule_id>` 代替
* **描述**：LibreNMS 告警模板渲染出的正文 `msg`，默认模板包含标题、等级、时间和故障对象
* **标签**：`check`（规则名称）、`resource` 和 `host`（主机名）、`alert_id`、`rule_id`、`device_id`、`sys_name`、`os`、`location`、`severity`（规则原始等级）、`state`（`alert`、`worse`、`better`、`changed` 或 `recovered`）

值为空的字段不会写入标签。

## 排查问题

***

* **测试时 LibreNMS 报 `Transport delivery failed with 401`，返回内容含 `integration_key is required`**：`integration_key` 要填在 **Options** 中，不能写在 **API URL** 里
* **测试时 LibreNMS 报 `Transport delivery failed with 400`**：如果返回内容中出现原样的 `{{ $name|json_encode }}`，说明 LibreNMS 低于 25.7.0，不认识 `json_encode` 过滤器，请升级；否则检查模板中带 `|json_encode` 的字段是否额外加了引号，以及 **Send as form** 是否未勾选
* **告警没有发出**：26.4.0 及以上确认规则选择了包含该通道的 **Operation**，更早版本确认规则的 **Transports** 包含该通道；在设备的 **Alerts** 页或 **Event Log** 中查看发送结果
* **告警没有恢复**：确认规则的 **Recovery alerts** 已开启

模板变量的含义请参阅 LibreNMS 文档 [Templates](https://docs.librenms.org/Alerting/Templates/) 和 [API transport](https://docs.librenms.org/Alerting/Transports/Api/)。
