راه اندازی Prometheus Aalert Manager

برای مدیریت اخطار ها در Prometheus از AlertManager استفاده می شود به طوری که اخطار ها را از سمت پرومتئوس می گیرد و کاربر نهایی را از طریق E-mail ، اسلک یا دیگر ابزارها مطلع می سازد. اخطار دهی منجر به این می شود همین که خطایی رخ داد، کاربر از آن مطلع شود.

برای راه اندازی alertmanager به prometheus rule و کانفیگ خود alertmanager نیاز داریم. ابتدا با prometheus rule شرایط ایجاد خطا را مشخص می کنیم که نمونه کانفیگ آن در زیر آورده شده است:

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: mpaas
  labels:
    role: alert-rules
spec:
  groups:
    - name: mpaas
      rules:
      - alert: example
        annotations:
          annotation1: example1
          annotation2: example2
        expr: sum(container_cpu_usage_seconds_total{namespace=&quotcdn-prod&quot})>0
        for: 5m
        labels:
          label1: example1
          label2: example2

در تنظیمات بالا قسمت های مهم به صورت زیر پیکربندی می شوند:

  • annotations

برای این که هنگام ارسال هشدار توضیحاتی برای مشخص شدن مشکل وجود داشته باشد از این قسمت استفاده می شود و بهتر است محل وقوع خطا و شدت خطا و ... آورده شود.

  • expr

کویری پرومتئوسی که برای تشخیص خطا به کار می رود.

  • for

مدت زمانی که خطا وجود داشته باشد تا هشدار به وجود بیاید.

  • labels

برای جدا کردن الرت ها از همدیگر زمان ارسال هشدار استفاده می شود برای مثال هشدار با label1: example1 به کاربر ۱ ارسال گردد.


بعد از تمام شدن کانفیگ prometheus rule با استفاده از

kubectl apply -n namespace prometheus-rule.yaml

ریسورس آن ایجاد می شود.


حالا باید برای ارسال هشدار به کاربر alertmanager را پیکریندی کنیم:

config:
  global:
    resolve_timeout: 1m
  route:
    receiver: 'default-team'
    group_wait: 30s
    group_interval: 30s
    repeat_interval: 1d
    group_by: [alertname]
    routes:
    - receiver: 'team1'
      group_wait: 10s
      group_interval: 5m
      repeat_interval: 4h
      group_by: [alertname]
      matchers:
      - label1=~&quotexample1|example2&quot
      active_time_intervals:
        - offhours
        - holidays
      mute_time_intervals:
        - offhours
        - holidays
      continue: true

  receivers:
  - name: 'team1'
    webhook_configs:
    - url: http://example.com
      send_resolved: true

  - name: 'email'
    email_configs:
    - to: 'to@gmail.com'
      from: 'from@gmail.com'
      smarthost: smtp.gmail.com:587
      auth_username: 'from@gmail.com'
      auth_identity: 'from@gmail.com'
      auth_password: 'pass'

در کانفیگ بالا route مشخص می کند که هشدار ها با label های مختلف به کدام کاربر ارسال شوند هر کانفیگی که زیر مجموعه route و بالای routes باشد به عنوان تنظیمات پیش فرض انتخاب می شود و در قسمت routes می توان آن ها را overwrite کرد.

  • group_wait

مدت زمانی که الرت منیجر بعد از ایجاد هشدار صبر می کند و سپس هشدار را وارد گروه مشخص شده می کند.

  • group_interval

اگر هشدار قبلا در گروه وجود داشته مدت زمانی که الرت منیجر بعد از ایجاد هشدار صبر می کند و سپس هشدار را وارد گروه مشخض شده می کند.

  • repeat_interval

اگر هشدار برطرف نشده باشد بعد از این مدت زمان دوباره پیام را ارسال می شود.

  • matchers

در زمان تعریف prometheus rule لیبل هایی برای alert ها می شخص می شوند با استفاده از این لیبل ها می توان تعیین کرد به receiver مورد نظر کدام هشدار ارسال شود.

  • active_time_intervals

زمان هایی که ارسال هشدار فعال است را مشخص می کند.

  • mute_time_intervals

زمان هایی که ارسال هشدار غیر فعال است را مشخص می کند.

  • continue

تعیین می کند اگر هشدار با receiver اول مطابق شده و هشدار ارسال شد ایا receiver بعدی نیز چک شود.


حال باید receivers تنظیم شوند برای این ها انواع مختلفی وجود دارد که در اینجا دو حالت email و webhook مورد بررسی قرار گرفته است. به عنوان مثال برای کانفیگ Gmail باید اکانت مورد نظر به صورت لاگین دو مرحله ای باشد و از قسمت security > signing whit google مقدار password را کپی کرده و در auth_password قرار دهید. برای راه اندازی سرویس ارسال پیامک با استفاده از webhook باید یک fast api راه اندازی شده و درخواست را از alertmanager گرفته و به سمت سرویس ارسال پیامک ارسال کند و در درخواستی که به سمت fast api ارسال می گردد شماره تلفن به صورت query parameter به صورت زیر داده شود:

url: http://example.com/?phone=09*********

همچین فایل python مورد نیاز برای ارسال درخواست به صورت زیر نوشته می شود:

from ctypes import Union
from lib2to3.pgen2 import grammar
from lib2to3.pgen2.token import NEWLINE
from typing import Optional, Type
from fastapi import FastAPI, Query
from pydantic import BaseModel
import requests
from urllib.parse import unquote
import urllib.parse
import json

class Book(BaseModel):
    version: str
    #...

app = FastAPI()
@app.post(&quot/&quot)
def req(phone: str,annotations: Annotations):
    return_list=[]
    return_list.append(f&quotalertname : {annotations.alerts[0].get('labels').get('alertname')}&quot)
    #...
    temp = &quot&quot
    nl= '\n'
    temp = f&quot{nl.join(return_list)}&quot
    uri = urllib.parse.quote(temp)
    url = &quothttps://example?username=user&password=pass&from=from&to=&quot + phone + &quot&text=&quot + uri
    payload={}
    headers = {
      'example': 'example'
    }
    response = requests.request(&quotGET&quot, url, headers=headers, data=payload)

در کد بالا درخواست از سمت alertmanager ارسال می گردد و مقادیر مورد نیاز response body از آن با استفاده از Base model استخراج می شود به عنوان نمونه:

version: str
...

نمونه response body:

{
  &quotversion&quot: &quot4&quot,
  &quotgroupKey&quot: <string>,              // key identifying the group of alerts (e.g. to deduplicate)
  &quottruncatedAlerts&quot: <int>,          // how many alerts have been truncated due to &quotmax_alerts&quot
  &quotstatus&quot: &quot<resolved|firing>&quot,
  &quotreceiver&quot: <string>,
  &quotgroupLabels&quot: <object>,
  &quotcommonLabels&quot: <object>,
  &quotcommonAnnotations&quot: <object>,
  &quotexternalURL&quot: <string>,           // backlink to the Alertmanager.
  &quotalerts&quot: [
    {
      &quotstatus&quot: &quot<resolved|firing>&quot,
      &quotlabels&quot: <object>,
      &quotannotations&quot: <object>,
      &quotstartsAt&quot: &quot<rfc3339>&quot,
      &quotendsAt&quot: &quot<rfc3339>&quot,
      &quotgeneratorURL&quot: <string>,      // identifies the entity that caused the alert
      &quotfingerprint&quot: <string>        // fingerprint to identify the alert
    },
    ...
  ]
}


باید در هنگام راه اندازی fast apj مقدار response body الرت منیجر مشاهده شده و بر اساس آن Base mode تعریف شود.

در قسمت return_list مقادیر مورد استخراج شده و به لیست خروجی که به صورت query parameter هست اضافه می شوند

و در اخر براساس سرویس پیامک موجود url ساخته شده و مقادیر user و pass و ... در آن قرار می گیرد و با استفاده از‌ آن یک درخواست get به سمت سرویس پیامکی ارسال می شود