Skip to content
GitHub

AlertManager

alertmanager 是一个告警组件, 默认端口 9093

在 Prometheus 界面下载 Alertmanager

 # 检查配置文件
 $ ./amtool check-config alertmanager-config.yaml
 > Checking '../alertmanager/alertmanager-config.yml'  SUCCESS
 > Found:
 > - global config
 > - route
 > - 1 inhibit rules
 > - 1 receivers
 > - 1 templates
 > SUCCESS

 $ ./alertmanager-linux-amd64 --config.file=alertmanager-config.yaml

浏览器打开 http://localhost:9093 界面查看
重启 alermanager 服务 curl -X POST http://localhost:9093/-/reload

配置告警

global:
  resolve_timeout: 5m
  smtp_smarthost: "smtp.com:25" # 配置 smtp 服务地址, 邮箱类型和 smtp 服务器对应
  smtp_from: "facsert@outlook.com" # 发送人
  smtp_auth_username: "facsert@outlook.com" # 邮箱账户
  smtp_auth_password: "xxxxxx" # 邮箱密码
  smtp_require_tls: false

templates:
  - "/root/Desktop/alertmanager/email.tmpl" # 邮件模板

route:
  receiver: group # 默认收件人
  group_by: [...] # 分组方式 ['alertname', 'instance'] 不分组 [...], 字段值相同即为通一组, 告警可合并
  group_wait: 30s # 等待同组告警时间; 触发告警后, 等待同组告警以合并告警信息发送一次(默认 30s)
  group_interval: 5m # 已发送告警后, 同组又出现告警, 再次发送告警的等待时间(默认 5m)
  repeat_interval: 4h # 已发送告警, 告警未恢复, 再次发送同样的告警信息的间隔(默认 4h)

  # routes:                                      # 设置子路由, 按照路由规则发送, 匹配规则才会发送给接收人
  #   - match:
  #       team: operations
  #     group_by: [env,dc]
  #     receiver: 'ops'
  #   - receiver: ops                            # 路由和标签,根据match来指定发送目标,如果 rule的lable 包含 alertname, 使用 ops 来发送
  #     group_wait: 10s
  #     match:
  #       team: operations

receivers: # 定义接受人群组
  - name: group #
    email_configs:
      - to: "facsert@outlook.com" # 如果想发送多个人就以 ','做分割,写多个邮件人即可。
        send_resolved: true
        html: '{{ template "email.default.message" .}}'
        headers:
          from: "Prometheus 警报"
          subject: "Prometheus 告警邮件"
          to: "facsert"
    webhook_configs: # 发送告警信息给服务器
      url: "http://localhost:8080/api/v1/alerts"

inhibit_rules:
  - source_match:
      severity: "critical"
    target_match:
      severity: "warning"
    equal: ["alertname", "dev", "instance"]

group_by: 分组方式, 按 prometheus 告警规则中 labels 的自定义字段
group_wait: 触发组内第一个告警后, 先不发告警, 等待 group_wait 时间, 看是否有同组告警, 有则合并告警, 仅发送一次
group_interval: 组内已发送告警后, 同组出现新告警; 先不发, 等待 group_interval 时间, 看是否有同组新告警, 连同已发送信息, 并合并再次发送
repeat_interval: 已发送告警, 告警一直未复位; 等待 repeat_interval 时间, 再次发送同样的告警

使用 prometheus 监控 node1 node2 node3 机器

groups:
  - name: monitor # 规则组名, 唯一
    rules:
      - alert: Node Down
        expr: up{job=~".*Node.*"} == 0 # 告警规则, 表达式成立表示 node1 断连
        for: 1m # 表达式持续成立并持续 1 分钟 pending 时间, 未恢复则开始发送告警
        labels: # 自定义字段, 可用于告警分组, 定义或覆盖变量
          severity: critical
        annotations:
          summary: "{{ $labels.instance }} down" # 警报描述, 使用 {{ $label.instance }} 获取节点属性
          description: ""
          value: "{{ $value }}"

alertmanager 中 group_by 使用 team 字段分组, team 字段值一致为同一组
node1 节点表达式成立(expr), 进入 pending 状态; pending 持续 1 分钟(for 字段), 告警发送给 alertmanager, 并进入 firing 状态
aleertmanager 接到 node1 告警, 等待 30s(group_wait); 期间 node2 触发也告警; 同一组两个告警合并然后发送
告警发送后 node1 node2 告警未解除, node3 触发告警, 在 node3 触发告警 5m(group_interval) 后发送 node1 node2 node3 合并告警
node1 node2 node3 告警一直未恢复, 等待 4h(repeat_interval) 后再次发送 node1 node2 node3 合并告警

邮件模板

{{ define "email.default.message" }}
{{- if gt (len .Alerts.Firing) 0 -}}
<h2> 异常告警 </h2>
<table border="1" bgcolor="#e8e8e8">
  <thead bgcolor="#EF665B">
      <tr bgcolor="#EF665B">
      <td align="center" valign="middle"> 告警主机 </td>
      <td align="center" valign="middle"> 告警级别 </td>
      <td align="center" valign="middle"> 告警状态 </td>
      <td align="center" valign="middle"> 告警类型 </td>
      <td align="center" valign="middle"> 告警概述 </td>
      <td align="center" valign="middle"> 告警取值 </td>
      <td align="center" valign="middle"> 告警时间 </td>
      <td align="center" valign="middle"> 告警详情 </td>
      </tr>
  </thead>
  <tbody>
    {{ range $i, $alert :=.Alerts }}
    <tr>
      <td align="left" valign="middle">{{ $alert.Labels.instance }}</td>
      <td align="left" valign="middle">{{ $alert.Labels.severity }}</td>
      <td align="left" valign="middle">{{   .Status }}</td>
      <td align="left" valign="middle">{{ $alert.Labels.alertname }}</td>
      <td align="left" valign="middle">{{ $alert.Annotations.summary }}</td>
      <td align="left" valign="middle">{{ $alert.Annotations.value }}</td>
      <td align="left" valign="middle">{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}</td>
      <td align="left" valign="middle">{{ $alert.Annotations.description }}</td>
    </tr>
    {{ end }}
  </tbody>
</table>
{{ end -}}

{{- if gt (len .Alerts.Resolved) 0 -}}
<h2> 异常恢复 </h2>
<table border="1" bgcolor="#e8e8e8">
  <thead bgcolor="#98FB98">
      <tr bgcolor="#98FB98">
      <td align="center" valign="middle"> 告警主机 </td>
      <td align="center" valign="middle"> 告警状态 </td>
      <td align="center" valign="middle"> 告警类型 </td>
      <td align="center" valign="middle"> 告警概述 </td>
      <td align="center" valign="middle"> 告警时间 </td>
      <td align="center" valign="middle"> 恢复时间 </td>
      </tr>
  </thead>
  <tbody>
    {{ range $i, $alert :=.Alerts }}
    <tr>
      <td align="left" valign="middle">{{ $alert.Labels.instance }}</td>
      <td align="left" valign="middle">{{   .Status }}</td>
      <td align="left" valign="middle">{{ $alert.Labels.alertname }}</td>
      <td align="left" valign="middle">{{ $alert.Annotations.summary }}</td>
      <td align="left" valign="middle">{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}</td>
      <td align="left" valign="middle">{{ ($alert.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}</td>
    </tr>
    {{ end }}
  </tbody>
</table>
{{ end -}}
{{ end -}}

<!-- {{ range $i, $alert :=.Alerts }}: 遍历所有告警, 使用 `$alert` 获取单个告警对象, 使用 . 获取规则配置中 alert 字段下内容
如: $alert.Labels.instance => alert.labels.instance   -->

prometheus.yml 指定 alertmanager 服务, 规则文件, 添加监控节点

# 添加 alertmanager 服务
alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - localhost:9093

# 指定规则文件
rule_files:
  - "rules.yml"

scrape_configs:
  # prometheus.yml 注册节点
  - job_name: "Node"
    static_configs:
      - targets: ["192.168.1.100:9100"]
        # 可选项, 通过 labels 添加自定义节点信息, 默认有 instance 属性对应 targets
        labels:
          host: "192.168.1.100"
          tag: "python"

rules.yml 设定告警规则

# rules.yml 定义断连规则
groups:
  - name: monitor
    rules:
      - alert: Node Down
        expr: up{job=~".*Node.*"} == 0 # 告警规则, 表达式成立表示 node1 断连
        for: 5m # 表达式持续成立并持续 1 分钟 pending 时间, 未恢复则开始发送告警
        labels: # 自定义字段, 用于分组
          severity: critical
        annotations:
          summary: "{{ $labels.host }} disconnect for 5m"
          description: ""
          value: "{{ $value }}"

alertmanager.yml 设定告警服务配置文件

route:
  group_by: ["alertname"]
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 1h
  receiver: "devops"
receivers:
  - name: "devops"
    # 将告警消息发送给指定服务
    webhook_configs:
      - url: "http://192.168.1.150:8030/api/v1/alerts"
inhibit_rules:
  - source_match:
      severity: "critical"
    target_match:
      severity: "warning"
    equal: ["alertname", "dev", "instance"]

拉起后端配置接口 POST http://192.168.1.150:8030/api/v1/alerts 接收告警

{
  "receiver": "devops",
  "status": "firing",
  "alerts": [
    {
      "status": "firing",
      "labels": {
        "alertname": "Node Down",
        "host": "192.168.1.100",
        "instance": "192.168.1.100:9100",
        "job": "Node",
        "severity": "critical",
        "tag": "python"
      },
      "annotations": {
        "description": "",
        "summary": "192.168.1.100 disconnect for 5m",
        "value": "0"
      },
      "startsAt": "2024-10-11T03:43:02.163Z",
      "endsAt": "0001-01-01T00:00:00Z",
      "generatorURL": "http://canpheds02659:9090/graph?g0.expr=up%7Bjob%3D~%22.%2ANode.%2A%22%7D+%3D%3D+0&g0.tab=1",
      "fingerprint": "7e27892c867dd27f"
    }
  ],
  "groupLabels": {
    "alertname": "Node Down"
  },
  "commonLabels": {
    "alertname": "Node Down",
    "host": "192.168.1.100",
    "instance": "192.168.1.100:9100",
    "job": "Node",
    "severity": "critical",
    "tag": "python"
  },
  "commonAnnotations": {
    "description": "",
    "summary": "192.168.1.100:10101 disconnect for 5m",
    "value": "0"
  },
  "externalURL": "http://canpheds02659:9093",
  "version": "4",
  "groupKey": "{}:{alertname=\"Node Down\"}",
  "truncatedAlerts": 0
}