掌握Web應(yīng)用的監(jiān)控與告警

前面有介紹利用Blackbox監(jiān)控Web應(yīng)用的健康狀況:使用blackbox監(jiān)控Web應(yīng)用,最近組里又來(lái)了一個(gè)需求:當(dāng)告警發(fā)生時(shí),將告警信息通過(guò)企業(yè)微信發(fā)送給開(kāi)發(fā)的相關(guān)負(fù)責(zé)人,方便盡快排除故障。實(shí)際使用Alertmanager來(lái)完成這項(xiàng)工作,下面介紹具體的實(shí)現(xiàn)方法。

詳細(xì)配置

  • 告警通道配置
    監(jiān)控最重要的是在故障發(fā)生時(shí),能將告警信息發(fā)送出來(lái),讓正確的人第一時(shí)間獲悉故障的詳情,只有這樣才能盡快排除故障。企業(yè)微信很多公司都有使用,而且Alertmanager支持將企業(yè)微信作為告警通道。

按照企業(yè)微信的官方文檔來(lái)配置告警通道,如果覺(jué)得麻煩,可以在瀏覽器上搜索“alertmanager 企業(yè)微信”關(guān)鍵字,就有很多配置例子展示。我們需要得到下面五個(gè)鍵值對(duì):

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

這五個(gè)鍵值對(duì)需要在Alertmanager中配置,后面四個(gè)鍵的值根據(jù)實(shí)際情況填寫。

企業(yè)微信有三種ID來(lái)選擇消息的接收對(duì)象:用戶ID、部門ID和標(biāo)簽ID。因?yàn)榈谌N方式支持同時(shí)包含用戶和部門,使用起來(lái)比較靈活,這里選擇第三種方式,


標(biāo)簽ID

點(diǎn)擊“標(biāo)簽詳情”,可以看到標(biāo)簽ID,在配置Alertmanager時(shí)會(huì)用到。


標(biāo)簽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配置
    這里是關(guān)鍵,因?yàn)楦婢ㄖ陌l(fā)送控制都由Alertmanager來(lái)控制。配置文件如下,

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

有幾個(gè)參數(shù)需要介紹下,

group_wait:Alertmanager 在接收到一條新的告警(第一次出現(xiàn)的告警)時(shí),將這條告警發(fā)送給 receiver 之前需要等待的時(shí)間

group_interval:對(duì)于一條已經(jīng)出現(xiàn)過(guò)的告警,alertmanager 每隔 group_interval 時(shí)間檢查一次告警

repeat_interval: 對(duì)于一條已經(jīng)出現(xiàn)過(guò)的告警,每隔 repeat_interval 會(huì)重新發(fā)送給 receiver。

有篇文檔整理得很好,這里直接列出來(lái),

Alertmanager 在收到一條新的告警之后,會(huì)等待 group_wait 時(shí)間,對(duì)這條新的告警做一些分組、更新、靜默的操作。當(dāng)?shù)谝粭l告警經(jīng)過(guò) group_wait 時(shí)間之后,Alertmanager 會(huì)每隔 group_interval 時(shí)間檢查一次這條告警,判斷是否需要對(duì)這條告警進(jìn)行一些操作,當(dāng) Alertmanager 經(jīng)過(guò) n 次 group_interval 的檢查后,ngroup_interval 恰好大于 repeat_interval 的時(shí)候,Alertmanager 才會(huì)將這條告警再次發(fā)送給對(duì)應(yīng)的 receiver。*

文中這三個(gè)參數(shù)配置的值很小,主要為測(cè)試目的,生產(chǎn)環(huán)境根據(jù)需要配置。

還有一點(diǎn)需要注意,Alertmanager子路由(即routes里面)中配置的參數(shù)會(huì)覆蓋根路由(即route里面)中配置的參數(shù),所以按照文件“config/config.yml”中的配置,如果一條告警發(fā)送到了“searchEngine”,就不可能再發(fā)送給默認(rèn)的接收者“wechat”,除非子路由沒(méi)有匹配。

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

{{ define "wechat.message" }}
{{- if gt (len .Alerts.Firing) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 -}}
# 報(bào)警項(xiàng): {{ $alert.Labels.alertname }}
{{- end }}
> `**===告警詳情===**` 
> 告警級(jí)別: {{ $alert.Labels.severity }}
> 告警詳情: <font color="comment">{{ index $alert.Annotations "description" }}{{ $alert.Annotations.message }}</font>
> 故障時(shí)間: <font color="warning">{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}</font>
> 故障實(shí)例: <font color="info">{{ $alert.Labels.instance }}</font>
{{- end }}
{{- end }}
{{- if gt (len .Alerts.Resolved) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 -}}
# 恢復(fù)項(xiàng): {{ $alert.Labels.alertname }}
{{- end }}
> `===恢復(fù)詳情===` 
> 告警級(jí)別: {{ $alert.Labels.severity }}
> 告警詳情: <font color="comment">{{ index $alert.Annotations "description" }}{{ $alert.Annotations.message }}</font>
> 故障時(shí)間: <font color="warning">{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}</font>
> 恢復(fù)時(shí)間: <font color="warning">{{ ($alert.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}</font>
> 故障實(shí)例: <font color="info">{{ $alert.Labels.instance }}</font>
{{- end }}
{{- end }}
{{- end }}

其中語(yǔ)句“{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}”是將時(shí)間轉(zhuǎn)換成北京時(shí)間,否則默認(rèn)顯示的是UTC時(shí)間,不利于故障發(fā)生時(shí)間的查看。

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

  • Prometheus配置
    Prometheus需要增加告警規(guī)則文件,所有待監(jiān)控的metrics都保存在Prometheus中,但它并不知道m(xù)etrics的值處于什么狀態(tài)的情況下,自己要發(fā)告警給Alertmanager,所以要通過(guò)增加告警規(guī)則文件告知Prometheus,各個(gè)配置文件如下,

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的告警規(guī)則文件,config/alerts.rules

groups:
    - name: Web監(jiān)控
      rules:
      - alert: Web API不能訪問(wèn)
        expr: probe_success == 0
        for: 10s
        labels:
          severity: 非常嚴(yán)重
        annotations:
          summary: "{{$labels.instance}}:鏈接不能訪問(wèn)"
          description: "{{$labels.instance}}:鏈接超過(guò)10s無(wú)法連接"

到這里,所有的配置已經(jīng)完成,看下效果
效果展示
在Prometheus上查看probe_success metric的值,看到此時(shí)鏈接“https://www.163.com”訪問(wèn)異常(當(dāng)然不是真的有問(wèn)題,可以使用一些手段模擬),

prometheus查看

查看Alertmanager Web界面,也收到了Prometheus發(fā)送過(guò)來(lái)的告警信息,
Alertmanager告警詳情

企業(yè)微信告警信息如下,
企業(yè)微信告警

總結(jié)

依賴企業(yè)微信和Alertmanager便實(shí)現(xiàn)根據(jù)告警詳情指定告警接收人的配置。如果對(duì)文中的參數(shù)有不熟悉,歡迎在評(píng)論區(qū)指出,筆者將盡自己最大努力解釋。

希望這篇文章能幫到正在努力的你!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容