掌握Web应用的监控与告警

前面有介绍利用Blackbox监控Web应用的健康状况:使用blackbox监控Web应用,最近组里又来了一个需求:当告警发生时,将告警信息通过企业微信发送给开发的相关负责人,方便尽快排除故障。实际使用Alertmanager来完成这项工作,下面介绍具体的实现方法。

详细配置

  • 告警通道配置
    监控最重要的是在故障发生时,能将告警信息发送出来,让正确的人第一时间获悉故障的详情,只有这样才能尽快排除故障。企业微信很多公司都有使用,而且Alertmanager支持将企业微信作为告警通道。

按照企业微信的官方文档来配置告警通道,如果觉得麻烦,可以在浏览器上搜索“alertmanager 企业微信”关键字,就有很多配置例子展示。我们需要得到下面五个键值对:

wechat_api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
wechat_api_corp_id: '12345678'
agent_id: 12345678
api_secret: 12345678
to_tag: 4

这五个键值对需要在Alertmanager中配置,后面四个键的值根据实际情况填写。

企业微信有三种ID来选择消息的接收对象:用户ID、部门ID和标签ID。因为第三种方式支持同时包含用户和部门,使用起来比较灵活,这里选择第三种方式,


标签ID

点击“标签详情”,可以看到标签ID,在配置Alertmanager时会用到。


标签ID显示

docker-compose.yaml

version: '3.3'
services:
  blackbox_exporter:
    image: prom/blackbox-exporter:v0.19.0
    ports:
      - "9115:9115"
    restart: always
    volumes:
      - "./config:/config"
    command: "--config.file=/config/blackbox.yaml"

config/blackbox.yaml

modules:
  http_get:
    prober: http
    timeout: 5s
    http:
      valid_http_versions: ["HTTP/1.1", "HTTP/2.0"]
      valid_status_codes: [200]
      no_follow_redirects: false
      tls_config:
        insecure_skip_verify: true
  • Alertmanager配置
    这里是关键,因为告警通知的发送控制都由Alertmanager来控制。配置文件如下,

docker-compose.yaml

alertmanager:
  image: bitnami/alertmanager:0
  restart: "always"
  ports:
    - 9093:9093
  container_name: "alertmanager"
  volumes:
      - "./config:/etc/alertmanager"

config/config.yml

global:
  resolve_timeout: 5m
  wechat_api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
  wechat_api_corp_id: '1234567'
templates:
  - '/etc/alertmanager/*.tmpl'
route:
  receiver: wechat
  group_wait: 1s
  group_interval: 1s
  repeat_interval: 2s
  group_by: [adm]
  routes:
    - matchers:
          - adm="search"
      receiver: searchEngine
      group_wait: 10s

    - matchers:
          - adm="portalweb"
      receiver: portalWeb
      group_wait: 10s

receivers:
- name: wechat
  wechat_configs:
  - to_tag: infra
    message: '{{ template "wechat.message" . }}'
    agent_id: 1000002
    message_type: markdown
    api_secret: verylongstring

- name: searchEngine
  wechat_configs:
  - to_tag: searchdep
    message: '{{ template "wechat.message" . }}'
    agent_id: 1000002
    message_type: markdown
    api_secret: verylongstring

- name: portalWeb
  wechat_configs:
  - to_tag: portalwebdep
    message: '{{ template "wechat.message" . }}'
    agent_id: 1000002
    message_type: markdown
    api_secret: verylongstring

有几个参数需要介绍下,

group_wait:Alertmanager 在接收到一条新的告警(第一次出现的告警)时,将这条告警发送给 receiver 之前需要等待的时间

group_interval:对于一条已经出现过的告警,alertmanager 每隔 group_interval 时间检查一次告警

repeat_interval: 对于一条已经出现过的告警,每隔 repeat_interval 会重新发送给 receiver。

有篇文档整理得很好,这里直接列出来,

Alertmanager 在收到一条新的告警之后,会等待 group_wait 时间,对这条新的告警做一些分组、更新、静默的操作。当第一条告警经过 group_wait 时间之后,Alertmanager 会每隔 group_interval 时间检查一次这条告警,判断是否需要对这条告警进行一些操作,当 Alertmanager 经过 n 次 group_interval 的检查后,ngroup_interval 恰好大于 repeat_interval 的时候,Alertmanager 才会将这条告警再次发送给对应的 receiver。*

文中这三个参数配置的值很小,主要为测试目的,生产环境根据需要配置。

还有一点需要注意,Alertmanager子路由(即routes里面)中配置的参数会覆盖根路由(即route里面)中配置的参数,所以按照文件“config/config.yml”中的配置,如果一条告警发送到了“searchEngine”,就不可能再发送给默认的接收者“wechat”,除非子路由没有匹配。

告警模板文件:config/wechat.tmpl

{{ define "wechat.message" }}
{{- if gt (len .Alerts.Firing) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 -}}
# 报警项: {{ $alert.Labels.alertname }}
{{- end }}
> `**===告警详情===**` 
> 告警级别: {{ $alert.Labels.severity }}
> 告警详情: <font color="comment">{{ index $alert.Annotations "description" }}{{ $alert.Annotations.message }}</font>
> 故障时间: <font color="warning">{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}</font>
> 故障实例: <font color="info">{{ $alert.Labels.instance }}</font>
{{- end }}
{{- end }}
{{- if gt (len .Alerts.Resolved) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 -}}
# 恢复项: {{ $alert.Labels.alertname }}
{{- end }}
> `===恢复详情===` 
> 告警级别: {{ $alert.Labels.severity }}
> 告警详情: <font color="comment">{{ index $alert.Annotations "description" }}{{ $alert.Annotations.message }}</font>
> 故障时间: <font color="warning">{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}</font>
> 恢复时间: <font color="warning">{{ ($alert.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}</font>
> 故障实例: <font color="info">{{ $alert.Labels.instance }}</font>
{{- end }}
{{- end }}
{{- end }}

其中语句“{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}”是将时间转换成北京时间,否则默认显示的是UTC时间,不利于故障发生时间的查看。

配置完Alertmanager,再看Prometheus的配置。

  • Prometheus配置
    Prometheus需要增加告警规则文件,所有待监控的metrics都保存在Prometheus中,但它并不知道metrics的值处于什么状态的情况下,自己要发告警给Alertmanager,所以要通过增加告警规则文件告知Prometheus,各个配置文件如下,

docker-compose.yaml

version: '3.3'
services:
  prometheus:
    image: prom/prometheus
    restart: always
    ports:
      - "9090:9090"
    volumes:
      - "./config:/config"
    command: --config.file=/config/prometheus.yaml

Prometheus的配置文件,config/prometheus.yaml

# my global config
global:
  scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration
alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - 192.168.52.128:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
   - /config/alerts.rules 

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  - job_name: 'web-monitor'
    scrape_interval: 1m
    metrics_path: /probe
    params:
      module: [http_get]
    static_configs:
      - targets:
        - https://www.baidu.com
        - https://cn.bing.com
        labels:
          adm: "search"
      - targets:
        - https://www.163.com
        - https://www.ifeng.com
        labels:
          adm: "portalweb"
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: 192.168.52.128:9115  # The blackbox exporter's real hostname:port.

Prometheus的告警规则文件,config/alerts.rules

groups:
    - name: Web监控
      rules:
      - alert: Web API不能访问
        expr: probe_success == 0
        for: 10s
        labels:
          severity: 非常严重
        annotations:
          summary: "{{$labels.instance}}:链接不能访问"
          description: "{{$labels.instance}}:链接超过10s无法连接"

到这里,所有的配置已经完成,看下效果
效果展示
在Prometheus上查看probe_success metric的值,看到此时链接“https://www.163.com”访问异常(当然不是真的有问题,可以使用一些手段模拟),

prometheus查看

查看Alertmanager Web界面,也收到了Prometheus发送过来的告警信息,
Alertmanager告警详情

企业微信告警信息如下,
企业微信告警

总结

依赖企业微信和Alertmanager便实现根据告警详情指定告警接收人的配置。如果对文中的参数有不熟悉,欢迎在评论区指出,笔者将尽自己最大努力解释。

希望这篇文章能帮到正在努力的你!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容