AlertManager分析

AlertManager


Architecture


  • Alertmanager作為一個(gè)獨(dú)立的組件颁虐,負(fù)責(zé)接收并處理來自Prometheus Server(也可以是其它的客戶端程序)的告警信息。Alertmanager可以對(duì)這些告警信息進(jìn)行進(jìn)一步的處理仰剿,比如當(dāng)接收到大量重復(fù)告警時(shí)能夠消除重復(fù)的告警信息创淡,同時(shí)對(duì)告警信息進(jìn)行分組并且路由到正確的通知方,Prometheus內(nèi)置了對(duì)郵件南吮,Slack等多種通知方式的支持琳彩,同時(shí)還支持與Webhook的集成,以支持更多定制化的場(chǎng)景。同時(shí)AlertManager還提供了靜默和告警抑制機(jī)制來對(duì)告警通知行為進(jìn)行優(yōu)化露乏。

    • 客戶端通過POST請(qǐng)求向AlertManager推送告警信息碧浊。
    • 每條告警信息中的labels可用于唯一識(shí)別告警信息并用于去重。
  • AlertManager主要分為兩個(gè)部分瘟仿,路由(router)和接收器(receiver)箱锐。告警消息先被經(jīng)過路由樹,然后被分配到對(duì)應(yīng)的接收器中猾骡。路由樹是由預(yù)先設(shè)定的路由規(guī)則生成的瑞躺。其高可用架構(gòu)如上圖所示,具體流程如下:

    • Prometheus會(huì)通過調(diào)用AlertManager提供的告警接口將原始的告警消息發(fā)送到AlertManager兴想。
    • AlertManager的API除了接收告警幢哨,還接收靜默請(qǐng)求,將其分別保存到各自的provider里嫂便。
    • provider提供了一個(gè)訂閱(subscribe)接口捞镰,這樣Dispatcher組件便可以獲取告警數(shù)據(jù),并對(duì)數(shù)據(jù)進(jìn)行分組毙替,通過用戶預(yù)先設(shè)置的規(guī)則進(jìn)入告警抑制階段或靜默階段岸售。
    • 如果通過了上面的告警靜默階段,則進(jìn)入路由分發(fā)階段厂画,最終發(fā)送通知凸丸。

上報(bào)數(shù)據(jù)格式

[
  {
    "labels": {
      "alertname": "<requiredAlertName>",
      "<labelname>": "<labelvalue>",
      ...
    },
    "annotations": {
      "<labelname>": "<labelvalue>",
    },
    "startsAt": "<rfc3339>",
    "endsAt": "<rfc3339>",
    "generatorURL": "<generator_url>"
  },
  ...
]
  • 其中:
    • 告警信息的Fingerprint是通過labels來進(jìn)行計(jì)算的。
    • startAtendsAtprovider的告警合并會(huì)用到袱院。

Alert Provider

  • Prometheus或者告警發(fā)送系統(tǒng)可以通過API的方式發(fā)送給Alertmanager屎慢,收到告警后將告警分別存儲(chǔ)在Alert Provider中(當(dāng)前實(shí)現(xiàn)是存儲(chǔ)在內(nèi)存中,可以通過接口的方式自行實(shí)現(xiàn)其他存儲(chǔ)方式比如MySQL或者ES)忽洛。
  • 已解決的alerts會(huì)定期地從provider中清除腻惠,用戶可以定義相應(yīng)的回調(diào)函數(shù),在alerts被刪除時(shí)進(jìn)行相應(yīng)的回調(diào)處理欲虚。
  • Alert Provider收到告警信息后對(duì)相同的指標(biāo)數(shù)據(jù)進(jìn)行合并處理集灌。
// Alerts gives access to a set of alerts. All methods are goroutine-safe.
type Alerts interface {
    // Subscribe returns an iterator over active alerts that have not been
    // resolved and successfully notified about.
    // They are not guaranteed to be in chronological order.
    Subscribe() AlertIterator
    // GetPending returns an iterator over all alerts that have
    // pending notifications.
    GetPending() AlertIterator
    // Get returns the alert for a given fingerprint.
    Get(model.Fingerprint) (*types.Alert, error)
    // Put adds the given alert to the set.
    Put(...*types.Alert) error
}

Silence Provider


Dispatcher

  • Dispatcher sorts incoming alerts into aggregation groups and assigns the correct notifiers to each.
  • AlertManager內(nèi)部的Dispatcher通過訂閱的方式獲得告警信息更新(獲得Alerts的迭代器,通過for循環(huán)不斷的獲得發(fā)送到信道中的Alerts, 通過route的match函數(shù)獲得匹配的route對(duì)象(比如基于標(biāo)簽的正則表達(dá)复哆,傳遞到不同的郵件或者slack信道路由),并且每隔一段時(shí)間將執(zhí)行一次清理操作(當(dāng)aggregate group中的告警數(shù)量為空的時(shí)候)欣喧,刪除之前的記錄。收到的Alert通過標(biāo)簽匹配的方式被送到不同的聚合組中等待Pipeline流程進(jìn)行處理寂恬。

Aggregate group

  • aggrGroup aggregates alert fingerprints into groups to which a common set of routing options applies.
    It emits notifications in the specified intervals.
  • 聚合組aggregate group用來管理具有相同屬性信息的告警续誉,通過將相同類型的告警進(jìn)行分組可以統(tǒng)一的管理,因?yàn)橛袝r(shí)候告警處理是大量同時(shí)出現(xiàn)的(比如一個(gè)數(shù)據(jù)中心的失效將導(dǎo)致成百上千的告警產(chǎn)生初肉,通過分組可以聚合相同標(biāo)簽到一個(gè)郵件或者接收者中)酷鸦。分組創(chuàng)建將依賴于處理route路由和告警的labels標(biāo)簽,不同的告警labels將產(chǎn)生不同的聚合組,所有接收到的告警將首先計(jì)算一個(gè)聚合組的Fingerprint如果找到則直接插入到該組臼隔,否則創(chuàng)建一個(gè)新的聚合組嘹裂,每次新創(chuàng)建的聚合組都會(huì)啟動(dòng)一個(gè)goroutine來執(zhí)行實(shí)際的pipeline work.

Inhibitor

  • An Inhibitor determines whether a given label set is muted based on the currently active alerts and a set of inhibition rules. It implements the Muter interface.
  • Inhibitor用于管理相同的告警配置, 比如下面的配置定義了當(dāng)告警名稱alertname一致的時(shí)候摔握,如果嚴(yán)重告警存在的時(shí)候寄狼,途同級(jí)別告警將被過濾掉。
  • 查詢流程上將獲得的alert的label進(jìn)行檢查氨淌,匹配檢查的內(nèi)容滿足target匹配但是source不匹配的標(biāo)記為Inhibited.

Silencer

  • Silencer用來取消告警泊愧,比如直接配置告警在某一段時(shí)間內(nèi)不觸發(fā)任何消息,可以基于正則表達(dá)式的匹配盛正,該配置可以通過alertmanager的WebUI或者API接口配置删咱。
  • 當(dāng)流程傳遞到Silence步驟時(shí)候,Silence模塊將循環(huán)檢查每一個(gè)告警是否滿足匹配豪筝,比如設(shè)置某一個(gè)告警標(biāo)簽出現(xiàn)后取消告警痰滋。當(dāng)查詢結(jié)束后返回一個(gè)sils(Silence的結(jié)構(gòu)體,用來指定某一類告警的Silence在一段時(shí)間內(nèi)的處理對(duì)象续崖。)一個(gè)告警可能會(huì)被多個(gè)Silence同時(shí)管理敲街。
  • 同時(shí)要實(shí)現(xiàn)集群管理,彼此之間的Silence狀態(tài)也要共享(告警發(fā)送給多個(gè)AM)严望,因此系統(tǒng)設(shè)計(jì)的時(shí)候加入了SilenceProvider來進(jìn)行集群之間的Silence管理,彼此之間通過protoBuf來進(jìn)行數(shù)據(jù)狀態(tài)的同步多艇。同時(shí)集群在接收到告警后也要進(jìn)行通知,告知其他的節(jié)點(diǎn)關(guān)于告警的處理狀態(tài)像吻,防止多個(gè)通知同時(shí)被發(fā)送墩蔓。

Notify Provider


Router


Receiver Stage

Wait

  • 等待間隔用來設(shè)置發(fā)送告警的等待時(shí)間,對(duì)于集群操作中萧豆,需要根據(jù)不同的peer設(shè)置不同的超時(shí)時(shí)間,如果僅僅一個(gè)Server本身昏名,等待間隔設(shè)置為0涮雷;

Dedup

  • Dedup Stage用于管理告警的去重,傳遞的參數(shù)中包含了一個(gè)NotificationLog, 用來保存告警的發(fā)送記錄轻局。當(dāng)有多個(gè)機(jī)器組成集群的時(shí)候洪鸭,NotificationLog會(huì)通過協(xié)議去進(jìn)行通信,傳遞彼此的記錄信息仑扑,加入集群中的A如果發(fā)送了告警览爵,該記錄會(huì)傳遞給B機(jī)器,并進(jìn)行merge操作镇饮,這樣B機(jī)器在發(fā)送告警的時(shí)候如果查詢已經(jīng)發(fā)送蜓竹,則不再進(jìn)行告警發(fā)送。

Retry

  • Retry Stage利用backoff策略來管理告警的重發(fā),對(duì)于沒有發(fā)送成功的告警將不斷重試俱济,直到超時(shí)嘶是。

Set Notify

  • Set Notifies Stage用來設(shè)置發(fā)送告警的信息到nfLog,該模塊僅僅用于被該Alert Manager發(fā)送的告警的記錄(Retry組件傳遞的alertsDedup組件中發(fā)送出去的告警信息)蛛碌。

  • Integration定義一個(gè)集成路由組件聂喇,包含用戶的配置信息和名稱以及發(fā)送告警的實(shí)現(xiàn)。自定義的notify路由需要滿足該Notifier接口蔚携,實(shí)現(xiàn)Notify方法希太。


Examples

groups:

- name: httpd
  rules:
  - alert: httpd_down
    expr: probe_success{instance="http://httpd:80",job="httpd"} == 0
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "httpd is down"

  • Prometheus Server will wait for 1m and if the expression meets the condition for 1m, now Prometheus Server has to fire alert and forward to AlertManager. Until now, Prometheus knows how to connect to AlertManager and when to fire and forward alerts to AlertManager.
route:
  repeat_interval: 2h
  receiver: email-1
  routes:
    - match:
        alertname: httpd_down
      receiver: email-1

    - match:
        alertname: nginx_down
      receiver: email-2
  • These routes and receivers are defined in the AlertManager configuration file by the parent element called route. The parent route element has child routes which an alert follows in order to reach to its receiver based upon the match label as we will see in a bit.
http://localhost:9090/api/v1/alertmanagers
{
  "status": "success",
  "data": {
    "activeAlertmanagers": [
      {
        "url": "http://127.0.0.1:9093/api/v1/alerts"
      }
    ],
    "droppedAlertmanagers": []
  }
}
curl -X GET http://10.255.101.73:9090/api/v1/alerts
{
  "status": "success",
  "data": {
    "alerts": [
      {
        "labels": {
          "alertname": "內(nèi)存使用率過高",
          "instance": "127.0.0.1:9100",
          "job": "node",
          "severity": "warning"
        },
        "annotations": {
          "description": "127.0.0.1:9100 of job node內(nèi)存使用率超過80%,當(dāng)前使用率[59.74335527485338].",
          "summary": "Instance 127.0.0.1:9100 內(nèi)存使用率過高"
        },
        "state": "firing",
        "activeAt": "2019-08-23T11:27:34.027571952Z",
        "value": 59.74335527485338
      }
    ]
  }
}
http://10.255.101.73:9093/api/v2/alerts
[
  {
    "annotations": {
      "description": "10.255.101.74:8051 of job default go_goroutines > 100,當(dāng)前go_goroutines: [137].",
      "summary": "Instance 10.255.101.74:8051 go_goroutines > 100"
    },
    "endsAt": "2019-08-31T06:19:27.344Z",
    "fingerprint": "0d38358ac4713623",
    "receivers": [
      {
        "name": "default-receiver"
      }
    ],
    "startsAt": "2019-08-23T11:28:27.344Z",
    "status": {
      "inhibitedBy": [],
      "silencedBy": [],
      "state": "active"
    },
    "updatedAt": "2019-08-31T14:16:27.348+08:00",
    "generatorURL": "http://ceph-1:9090/graph?g0.expr=go_goroutines+%3E+100&g0.tab=1",
    "labels": {
      "alertname": "go_goroutines大于100",
      "instance": "10.255.101.74:8051",
      "job": "default",
      "severity": "warning"
    }
  }
]
http://10.255.101.73:9093/api/v1/alerts
{
  "status": "success",
  "data": [
    {
      "labels": {
        "alertname": "go_goroutines大于100",
        "instance": "10.255.101.74:8051",
        "job": "default",
        "severity": "warning"
      },
      "annotations": {
        "description": "10.255.101.74:8051 of job default go_goroutines > 100,當(dāng)前go_goroutines: [135].",
        "summary": "Instance 10.255.101.74:8051 go_goroutines > 100"
      },
      "startsAt": "2019-08-23T11:28:27.344378042Z",
      "endsAt": "2019-08-31T06:21:27.344378042Z",
      "generatorURL": "http://ceph-1:9090/graph?g0.expr=go_goroutines+%3E+100&g0.tab=1",
      "status": {
        "state": "active",
        "silencedBy": [],
        "inhibitedBy": []
      },
      "receivers": [
        "default-receiver"
      ],
      "fingerprint": "0d38358ac4713623"
    }
  ]
}

References

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市酝蜒,隨后出現(xiàn)的幾起案子誊辉,更是在濱河造成了極大的恐慌,老刑警劉巖秕硝,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芥映,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡远豺,警方通過查閱死者的電腦和手機(jī)奈偏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來躯护,“玉大人惊来,你說我怎么就攤上這事」字停” “怎么了裁蚁?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長继准。 經(jīng)常有香客問我枉证,道長,這世上最難降的妖魔是什么移必? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任室谚,我火速辦了婚禮,結(jié)果婚禮上崔泵,老公的妹妹穿的比我還像新娘秒赤。我一直安慰自己,他們只是感情好憎瘸,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布入篮。 她就那樣靜靜地躺著,像睡著了一般幌甘。 火紅的嫁衣襯著肌膚如雪潮售。 梳的紋絲不亂的頭發(fā)上痊项,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音饲做,去河邊找鬼线婚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛盆均,可吹牛的內(nèi)容都是我干的塞弊。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼泪姨,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼游沿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起肮砾,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤诀黍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后仗处,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體眯勾,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年婆誓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吃环。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡洋幻,死狀恐怖郁轻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情文留,我是刑警寧澤好唯,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏泣洞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一替蛉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拄氯,春花似錦、人聲如沸它浅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姐霍。三九已至鄙麦,卻和暖如春典唇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背胯府。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來泰國打工介衔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人骂因。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓炎咖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親寒波。 傳聞我的和親對(duì)象是個(gè)殘疾皇子乘盼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容