面向多告警源,如何構建統一告警管理體系?

本文介紹告警統一管理的最佳實踐,以幫助企業更好地處理異構監控系統所帶來的挑戰和問題。

背景信息

在雲原生時代,企業IT基礎設施的規模越來越大,越來越多的系統和服務被部署在雲環境中。爲了監控這些複雜的IT環境,企業通常會選擇使用異構監控系統,例如Prometheus、Grafana、Zabbix等,以獲取更全面的監控數據,以便更好地瞭解其IT基礎設施的運行狀況和性能表現。

然而,這種異構監控系統也帶來了一些問題,其中最顯着的是告警信息的分散。由於不同的監控系統可能會產生不同的告警信息,這些信息可能會分散在各個系統中,導致企業很難全面瞭解其IT系統的告警狀況。這使得響應告警變得更加困難,同時也增加了人工管理的複雜性和工作量。

爲了解決這些問題,企業需要一種更加統一和集中的告警管理方案,以確保告警信息能夠及時到達正確的人員,以便他們能夠快速採取必要的措施來應對潛在的問題。

告警管理的痛點

場景一:企業遷移上雲後,雲上產品的告警不統一

image.png

在一個典型的雲原生業務應用部署架構中,通常會使用到如下產品 ACK、ECS、RDS,應用通過Kubernetes部署在阿里雲的ECS上並訪問雲上的RDS。在這個架構中通常會用到如下監控產品來對系統進行監控。

  • 通過CloudMonitor對阿里雲基礎設施ECS和RDS進行監控,當資源出現異常時進行告警。
  • 通過Prometheus對Kubernetes以及部署在kubernetes上的Pod進行監控,當Kubernetes出現異常時進行告警。
  • 通過ARMS對部署在Kubernetes上的應用進行監控,包括應用直接的調用鏈。當應用異常時進行告警。
  • 通過SLS對應用產生的日誌進行監控,當日志出現異常時進行告警。

在這樣一個場景下由於用到了多個雲產品對整個系統進行監控會導致使用者需要在多個產品上重複配置聯繫人、通知方式、值班等運維配置。且不同系統之間的告警無法產生有機結合,當一個問題出現時不能快速關聯不同告警系統中的相關告警。

場景二:多雲、混合雲架構下,異構監控系統告警不統一

image.png

當企業的應用部署在多雲環境或混合雲環境下時,監控系統產生的告警可能會更加分散和複雜,給企業的運維工作帶來很大的挑戰。由於不同的雲平臺和私有云架構之間的差異,監控數據的採集和處理方式也可能不同,因此,不同監控系統產生的告警信息也可能表現出差異化,這會帶來一系列的問題。

首先,不同監控系統產生的告警信息分散在不同的地方,運維人員需要耗費更多的時間和精力去處理這些信息。其次,不同系統產生的告警信息難以統一進行管理和分析,使得問題的診斷和解決更加困難。此外,因爲不同系統的告警信息可能存在重複或衝突,管理和處理這些信息也會變得更加複雜。

場景三:自研監控系統、自定義事件告警接入

在應用開發運維過程中,隨着系統規模的擴大和複雜度的提高,各個角落中的膠水代碼逐漸增多。這些代碼雖然是連接不同模塊和系統的重要紐帶,但一旦出現問題,由於分散在不同的地方,很難立即發現和處理。這就使得企業難以保證系統的高可用性和穩定性。如何靈活的低成本的接入這部分代碼產生的告警也成爲企業應用運維的痛點之一。

統一告警管理

在構建統一告警管理平臺過程中,不同的監控系統對告警定義、處理流程都不一樣,往往會存在下面問題:

  • 不同系統產生的告警格式不同,接入成本高。
  • 不同系統間的告警接入後由于格式不統一,難以統一處理邏輯。
  • 不同告警系統對於告警等級的定義不同。
  • 不同告警系統對於告警自動恢復的處理方式不同。有的告警系統支持自動恢復,有的不支持。

ARMS告警管理 [ 1] 設計的集成、事件處理流、通知策略等功能專門針對告警統一管理的場景,解決了統一管理過程中遇到的諸多問題。

ARMS告警管理如何接入不同格式的告警?

傳統告警通常包括如下一些內容,這種結構化的告警通常只適用於單一告警源。當多個告警源的數據彙總到一起後通常會導致數據結構的衝突。因此ARMS使用了半結構化的數據來存儲告警。

阿里雲監控告警數據格式:

image.png

Zabbix告警數據格式:

image

Nagios告警數據格式:

image.png

半結構化的告警數據結構

[
  {
   "labels": {
    "alertname": "<requiredAlertNames>",
    "<labelnames>": "<labelvalues>",
    ...
   }, 
   "annotations": {
   "<labelnames>": "<labelvalues>",
   }, 
   "startsAt": "<rfc3339>",
   "endsAt": "<rfc3339>",
   "generatorURL": "<generator_url>"
  },
  ...
]
  • labels(標籤):告警元數據,一組標籤唯一標識一個事件,所有標籤均相同的事件爲同一個事件,重複上報會進行合併,例如:alertname: 告警名稱。
  • annotations(註釋):註釋是告警事件的附加描述,註釋不屬於元數據。例如:message: 告警內容。不同時間點發生的同一個事件他們的標籤是相同的,但是註釋可以是不同的。比如告警內容的註釋可能不同,例如:“主機i-12b3ac3*** CPU使用率持續三分鐘大於75%,當前值82%”。
  • startsAt(告警開始時間):告警事件開始時間。
  • endsAt(告警結束時間):告警事件結束時間。
  • generatorUrl(事件URL地址):告警事件URL地址。

如上述代碼所示,ARMS參考開源Prometheus告警定義 [ 2] ,使用一個半結構化的數據結構來描述告警。通過高度可擴展的鍵值對來描述告警,這樣就可以非常靈活的對告警內容進行擴展從而接入不同的數據源產生的告警。

任意JSON格式的自定義告警接入能力

ARMS告警提供了任意一種JSON格式接入的能力(自定義集成 [ 3] )。只要告警數據結構滿足JSON格式就能接入。如下圖所示,自定義告警接入需要先將告警內的JSON數據上傳到ARMS告警中心後,通過頁面編輯字段映射的方式將告警內容中的關鍵信息映射到ARMS告警數據結構中。

image.png

ARMS定義瞭如alertname等關鍵字段,對於更多的擴展字段,用戶可以在集成中通過新增擴展字段的方式進行配置。所有的擴展字段都可以運用到後面的告警處理邏輯中。以下圖爲例將原始告警報文中的hostname字段映射到擴展的hostname字段,hostip字段映射到擴展的hostip字段。

image.png

常用監控工具告警快捷接入能力

ARMS默認提供了雲上雲下多種監控系統的告警接入能力,可以參考集成概述 [ 4] 進行快速接入。

image

ARMS告警管理如何統一告警等級?

ARMS中將告警分爲P1、P2、P3、P4四個等級。通過配置映射表,將多個不同類型的等級歸一到P1-P4四個等級。如下圖所示,將L1、Critical、嚴重告警這三種不同描述的告警等級都映射爲P1告警,這樣就可以統一不同系統中對於告警等級的不同定義。

image

ARMS告警管理對於不同格式的告警如何統一處理邏輯?

由於ARMS告警採用了半結構化的數據結構,可以通過標籤來統一告警的處理邏輯。通常我們需要至少2個標籤來統一告警的處理邏輯。一個標籤用來決定這個告警應該通知給哪些人,比如業務標籤(service,biz)。另一個標籤用來決定這個告警應用通過什麼樣的方式進行通知和升級。如下表所示,通常使用告警等級(severity)來定義告警處理的SLA。

image

ARMS設計了通知策略和升級策略兩種策略來滿足不同等級的告警的處理要求,您可以參考通知策略最佳實踐 [ 5] 來進行配置。

標籤設計原則

當我們在設計用於告警處理的業務標籤時需要滿足如下原則:

  • 互斥原則:指避免對同一個資源使用兩個或以上的標籤鍵。例如:如果已經使用了標籤鍵service來標識業務,就不要再使用biz或業務等類似的標籤鍵。
  • 集體詳盡原則:指所有資源都必須綁定已規劃的標籤鍵及其對應的標籤值。例如:某公司有3個業務,標籤鍵是service,則應至少有3個標籤值分別代表這3個業務。
  • 有限值原則:指爲資源只保留核心標籤值,刪除多餘的標籤值。例如:某公司共有5個業務,那麼應該有且僅有這5個業務的標籤,方便管理。

除了業務標籤也可以定義其他的標籤來進行告警的管理,比如使用環境標籤來區分開發和測試環境的告警。這些標籤應該滿足上述設計原則,這樣可以簡化告警管理配置的複雜度。

通過事件處理流給告警打標籤(富化告警)

當我們設計好標籤後如何對不同告警源的告警打標呢。在ARMS告警管理中設計了低代碼方式的事件處理流 [ 6] ,通過拖拉拽的配置方式可以實現給告警打標籤的能力(富化告警)。

場景一:匹配特定條件後給告警打標籤

某xx業務使用了自研監控系統,通過自定義集成將自研的告警接入到ARMS告警管理中後,需要對這部分告警統一打上業務標籤xx。事件處理流的配置如下:

a. 登錄ARMS控制檯 [ 7] ,在左側導航欄選擇告警管理,然後單擊新建處理流。

b. 在彈出的面板創建事件處理流,編輯觸發條件匹配自定義集成的名稱爲“xx自研監控系統”。

image.png

c. 添加設置業務標籤動作,將"xx"設置爲業務(service)標籤值。

image

場景二:切割字符串,提取標籤

某自研告警系統中所有的主機都使用固定格式進行命名,命名格式爲env−env−{env}-{biz}-app−app−{app}-{group}-${index} ,需要提取其中的biz字段做爲業務標籤。配置正確的觸發條件後,使用分割內容操作,將hostname根據字符'-'進行分割,分割後的內容依次填充到env、service、 app、group字段。

image

場景三:通過查詢Excel表格富化告警

某應用監控平臺,在發生告警時僅通知了應用ID,需要根據Excel表格關聯到應用名稱、應用責任人等信息。

image.png

a. 創建Excel數據源,並上傳app_cmdb.xlsx文件。

image.png

b. 配置事件處理流,添加字段豐富操作,選擇數據源爲第一步創建的數據源。編輯匹配字段爲appId,將Excel表中其他字段分別填充到appName、owner、ownerPhone擴展字段中。

image.png**
**

場景四:通過Serverless(FunctionCompute)調用外部服務富化告警

同上述場景三,當告警中缺失的數據需要從CMDB等外部系統獲取時,可以通過API類型的數據源來進行告警富化。

image

a. 創建函數計算應用 [ 8] ,開發一個HTTP服務,接收入參爲appId,返回出參爲appName、owner、ownerPhone等參數。如下截圖僅爲示例代碼。

image

b. 創建API類型的數據源,URL地址爲第一步中開發的函數。

image

c. 配置事件處理流,添加字段豐富操作,選擇數據源爲上一步創建的數據源。編輯匹配字段爲appId,將Excel表中其他字段分別填充到appName、owner、ownerPhone擴展字段中。

ARMS告警管理如何配置告警自動恢復?

不同的監控系統對告警自動恢復的處理邏輯大不相同。如Prometheus告警不會發送特定格式的恢復告警,僅通過告警時間來標識告警是否結束。阿里云云監控 [ 9] 中告警是否恢復的狀態合併到了告警等級中,如下所示。

  • 參數:triggerLevel
  • 數據類型:String
  • 本次觸發報警的級別。取值:

<!---->

    • CRITICAL:嚴重
    • WARN:警告
    • INFO:信息
    • OK:正常

不同場景下的告警在處理是否恢復的邏輯可能也會有所區別。如閾值類型的告警,當監控值不滿足閾值條件時期望立即恢復告警。但是對於事件類型的重要告警,告警發生只在一瞬間,並沒有恢復的過程。需要運維人員人工確認事件產生的影響已經消除後才能恢復告警。

場景一:針對不會恢復的告警,配置自動恢復時長,告警按照時間自動恢復

針對事件類型的告警,通常需要人工確認事件的影響範圍後再處理告警。這時告警自動恢復可能會導致需要被處理的事件沒有被人工處理。針對這種情況需要在接收到告警後不進行自動恢復或者至少在一個長週期內不自動恢復,給處理人員一定的時間來確認該告警的影響。

image

ARMS自定義集成配置告警自動恢復時間截圖:

image

場景二:配置恢復告警字段,接收到恢復事件後恢復告警

在ARMS的告警集成中,可以通過配置告警恢復字段,當告警內容中某個字段的值滿足條件時,視爲恢復告警。根據該告警的其他字段的內容尋找對應的告警進行恢復。告警主動恢復的示意圖如下所示:

image

ARMS控制檯配置方式截圖:

image

告警恢復需要滿足如下2點,才能正確的恢復對應的告警。

  • 如果沒有定義去重字段,那麼告警和恢復告警的標籤需要完全一致才能正確恢復告警。
  • 如果定義了去重字段,那麼告警和恢復告警的去重字段需要完全一致才能正確恢復告警。

說明:當配置了某個字段如(status)做完告警恢復字段時,請不要將這個字段添加到告警的映射規則中。通常會導致告警與恢復告警字段不匹配,從而恢復失敗。

補充信息

FunctionCompute示例代碼:

# -*- coding: utf-8 -*-

import logging
import json

def handler(environ, start_response):
    context = environ['fc.context']
    request_uri = environ['fc.request_uri']
    body_str = get_request_body(environ)
    id = json.loads(body_str).get('appId')
    # 這一行爲僞代碼,示例通過查詢cmdb獲取應用詳細信息, 獲取到的app格式如下
    # {"appId":"b38cdf95-2526-4d7a-9ea9-ffe7b32*****", "appName": "iot-iam", "owner":"王五", "ownerPhone": "130xxxx1236"}
    app = cmdb.getApp(id)
    ret = json.dumps(app)
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    return [ret.encode('utf-8')]

def get_request_body(environ):
    try:
        request_body_size = int(environ.get('CONTENT_LENGTH', 0))
    except (ValueError):
        request_body_size = 0
    request_body = environ['wsgi.input'].read(request_body_size)
    return request_body

相關鏈接:

[1] ARMS告警管理

https://help.aliyun.com/document_detail/214753.htm?spm=a2c4g.2362717.0.0.1890245ddgeRkP#concept-2075853

[2] Prometheus告警定義

https://prometheus.io/docs/alerting/latest/clients/#sending-alerts

[3] 自定義集成

https://help.aliyun.com/document_detail/251850.htm?spm=a2c4g.2362717.0.0.18906bf4Pry1jD#task-2021669

[4] 集成概述

https://help.aliyun.com/document_detail/260831.htm?spm=a2c4g.2362717.0.0.1890d928BoEXFr#concept-2078267

[5] 通知策略最佳實踐

https://help.aliyun.com/document_detail/456953.htm?spm=a2c4g.2362717.0.0.1890951awN1Sbk#task-2249792

[6] 事件處理流

https://help.aliyun.com/document_detail/311905.htm?spm=a2c4g.2362717.0.0.18901c8dwhrptl#task-2114624

[7] ARMS控制檯

https://account.aliyun.com/login/login.htm?oauth_callback=https%3A%2F%2Farms.console.aliyun.com%2F#/home

[8] 函數計算應用

https://help.aliyun.com/document_detail/51783.htm?spm=a2c4g.2362717.0.0.189070368lSswF#multiTask782

[9] 阿里云云監控

https://help.aliyun.com/document_detail/60714.htm?spm=a2c4g.2362717.0.0.18904bf99bofq7#task-2151109

目前應用實時監控服務ARMS 提供全功能15天試用,開發者可以全面體驗告警能力。點擊此處,即可獲取。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章