> ## 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.

# Ofelia 告警集成

> 通过 Ofelia 的 Webhook 将定时任务的失败和恢复事件同步到 Flashduty On-call。

通过 Ofelia 的 Webhook 将定时任务的执行结果同步到 Flashduty On-call。每个任务在每台 Ofelia 主机上对应一条 Flashduty 告警：任务执行失败时触发 Critical 告警，之后某次执行成功时自动恢复。

本页对应 [netresearch/ofelia](https://github.com/netresearch/ofelia) 的 Webhook 功能（已用 v1.0.1 验证）。上游 `mcuadros/ofelia` 没有 Webhook 功能，无法使用本集成。

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

  ***

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

  ### 使用专属集成

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

  ### 使用共享集成

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

## 在 Ofelia 中配置

***

Ofelia 通过 Docker API 工作，即使只运行 `job-local` 任务也是如此，所以运行 Ofelia 的容器必须挂载 `/var/run/docker.sock`；缺少它时，Ofelia 启动即退出。使用 `docker run` 时加 `-v /var/run/docker.sock:/var/run/docker.sock:ro`。

<Steps>
  <Step title="定义 Webhook">
    在 Ofelia 的配置文件中新增一个 Webhook，只写 `url` 和 `trigger`，不要写 `preset`。Ofelia 会使用内置的 `json-post` 预设，向该地址 POST 一个 JSON 请求。

    ```ini theme={null}
    [webhook "flashduty"]
    url = <Flashduty 推送地址>
    trigger = always
    ```

    <Warning>
      必须设置 `trigger = always`。Ofelia 的默认值是 `error`，只在任务失败时发送，Flashduty 收不到成功的执行结果，告警就不会恢复。
    </Warning>

    如果您在 `[global]` 中设置了 `webhook-allowed-hosts`，需要把 `api.flashcat.cloud` 加入列表。

    如果用 Docker 标签定义，标签必须写在带有 `ofelia.service: "true"` 的 Ofelia 服务容器上，其他容器上的 Webhook 标签会被忽略：

    ```yaml theme={null}
    services:
      ofelia:
        image: ghcr.io/netresearch/ofelia:1.0.1
        hostname: ofelia-prod-01
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock:ro
        labels:
          ofelia.enabled: "true"
          ofelia.service: "true"
          ofelia.webhook.flashduty.url: "<Flashduty 推送地址>"
          ofelia.webhook.flashduty.trigger: "always"
    ```
  </Step>

  <Step title="把 Webhook 挂到任务上">
    在需要监控的任务上用 `webhooks` 指定刚才定义的名称：

    ```ini theme={null}
    [job-exec "backup-database"]
    schedule = @daily
    container = postgres
    command = pg_dump -U postgres mydb > /backup/db.sql
    webhooks = flashduty
    ```

    Docker 标签写法为 `ofelia.job-exec.backup-database.webhooks: "flashduty"`。想让所有任务都发送，可以在 `[global]` 中设置 `webhook-webhooks = flashduty`（标签为 `ofelia.webhook-webhooks`）。
  </Step>

  <Step title="固定主机名">
    Flashduty 用主机名区分不同机器上的同名任务。Ofelia 运行在容器里时，主机名默认是容器 ID，重建容器后会变，已打开的告警就无法被新的成功执行恢复。请在 Compose 中设置 `hostname`（如上例），或在 `docker run` 中加 `--hostname`。
  </Step>

  <Step title="验证生命周期">
    让一个任务真正失败一次（例如临时把命令改成 `false`），确认 Flashduty 收到 Critical 告警；再把命令改回去，等下一次执行成功，确认原告警恢复。Ofelia 没有测试发送功能，上述真实执行是唯一的验证方式。
  </Step>
</Steps>

## Alert Key

***

Flashduty 用 `host.hostname` 与 `job.name` 组合出 Alert Key，两者之间用不可见分隔符连接后取 MD5。在我们的真实验证中，同一任务的失败与成功执行携带相同的主机名和任务名；而 `execution.id` 每次执行都不同，因此只作为排查参考，不参与 Alert Key。

* 同一台主机上的两个不同任务是两条告警；同名任务在两台主机上也是两条告警
* 任务的命令、调度表达式、耗时和错误内容的变化不会改变 Alert Key
* 同一个 Ofelia 里不同类型的任务（`job-exec`、`job-run` 等）如果重名，会被当成同一条告警，请保持任务名唯一
* `job.name` 缺失时 Flashduty 返回 400，避免把失败和恢复写进错误的告警

## 状态和告警等级

***

| Ofelia `execution.status` | Flashduty 处理 |
| :- | :- |
| `failed` | Critical 告警，描述中包含错误信息和 stderr 的前 2000 字节 |
| `successful` | 恢复同一任务的告警 |
| `skipped` | 忽略，返回 200，不新建也不恢复告警 |

任务因 `no-overlap` 被跳过时，上一次执行还没有结束，任务的健康状态没有变化，所以跳过的执行不会影响已打开的告警。

任务失败后重复失败，会更新同一条告警，不会新建。若同一任务长期不再执行（任务被删除或停用），告警不会自动恢复，需要手动关闭，或开启协作空间的[超时自动关闭](/zh/on-call/channel/create-edit)。

## 告警内容

***

* **标题**：`Ofelia job "<任务名>" failed`，恢复时为 `Ofelia job "<任务名>" succeeded`
* **描述**：`execution.error`，换行后追加 `execution.stderr`
* **标签**：`check`、`job_name`、`job_type`、`job_schedule`、`execution_status`、`duration`、`resource` / `host`（主机名）、`ofelia_version`、`source=ofelia`

任务命令和标准输出不会进入标签或描述，因为命令里可能带有凭据。

## 排查问题

***

* **Flashduty 没有收到任何请求**：确认任务上写了 `webhooks = flashduty`，查看 Ofelia 日志里的 `Webhook error`；Ofelia 对失败的 Webhook 默认重试 3 次，间隔 5 秒
* **只收到失败，没有恢复**：确认 Webhook 设置了 `trigger = always`，并确认主机名在两次执行之间没有变化
* **Flashduty 返回参数错误**：确认没有给该 Webhook 设置其他 `preset`，请求体必须是 `json-post` 预设的 JSON
* **Docker 标签不生效**：Webhook 标签只在带有 `ofelia.service: "true"` 的容器上处理；INI 与标签同名时以 INI 为准
* **提示 host not in allowed hosts list**：把 `api.flashcat.cloud` 加入 `[global] webhook-allowed-hosts`

更多配置请参阅 Ofelia 的 [Webhook Notifications](https://github.com/netresearch/ofelia/blob/main/docs/webhooks.md)。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.