[Azure]Azure Monitor アラートのJSONスキーマのまとめ
Azure MonitorのアラートのJSONスキーマには複数のパターンがあるようで、初見で迷子になりかけたので理解を整理します。
なぜ理解する必要があるのか
Azure MonitorからアラートをWebhookでSlackやTeamsに連携するときに理解する必要があるからです。連携する時の流れは大まかに以下の通りになりますが、
- Azure Monitorのアラートルールに合致した時にWebhookでアラートのペイロードをAzure Logic Appsに送信する
- Azure Logic AppsがJSONをSlack/Teamsが受け付けられるようにパースして成型する
- Azure Logic AppsからSlack/TeamsのIncoming Webhookに成型したアラートを送信する
2の作業でAzure Monitorが飛ばすJSONのスキーマを理解する必要があります。
この記事では連携するための詳細な手順は説明しませんが、1~3の全体の流れは以下が参考になるかと思います。(そのうち記事にするかもしれません)
アラートスキーマの全体像
まずMSのドキュメントから、スキーマの全体像を図として整理すると以下のようになりました。
共通アラートスキーマと非共通アラートスキーマという概念があり、要するに元々バラバラだったスキーマが統合され、現在はどちらでも選べるという状態と理解しました。[1]
非共通アラートスキーマ
※現在も存続しているのは、おそらく過去に作成したアラートとの互換性の問題?
- メトリックアラート
- 使用例:エージェント経由で収集した仮想マシンのメトリクス(CPU使用率など)の監視
- ログアラート
- 使用例:Log Analytics Workspaceに転送したログの監視
- アクティビティログアラート
- 使用例:特定のアクティビティログの監視
共通アラートスキーマ
アラートごとに異なっていたスキーマを1つに統合したものが共通アラートスキーマです。
ただし完全に統合されたわけではなく、共通部分と非共通部分に分けて構成されています。
-
essentials
- 全てのアラートで共通する値(id、アラートルール名、発生時刻など)
-
alertContext
- 共通化できない、アラートの種別ごとに固有の値(メトリック値など)
それぞれのメリット/デメリット
アラートを送信する際のスキーマとしてどちらかを選択する必要があります。
※アクションルールでWebhook URIを指定する際に、選択します。
メリット/デメリット
共通アラートスキーマ | 非共通アラートスキーマ | |
---|---|---|
メリット | スキーマを1本化できる | 詳細な値までパースして成形できる |
デメリット | alertContextのプロパティをパースできない | スキーマの数だけ場合分けが必要 |
共通アラートスキーマを選択した場合、最大のメリットはすべてのアラートを1つのスキーマでパースできるようになる点にあります。
一方非共通アラートスキーマの場合、JSONからアラートスキーマを判別し適切なスキーマを選択する処理が必要になります。(または、アラートスキーマの数だけLogicAppsを用意する)
実際にアラートを表示させてみて比較
アラートをWebhookでSlackに連携するケースを例に、それぞれのスキーマでSlack上にアラートを表示させてみます。
- 送信するアラート
- ログアラート
- Slackに表示させたい情報
1.アラート発生時刻
2.アラートルール名
3.クエリ結果のリンク
共通アラートスキーマでパースした場合
- 与えたスキーマ
{
"type": "object",
"properties": {
"schemaId": {
"type": "string"
},
"data": {
"type": "object",
"properties": {
"essentials": {
"type": "object",
"properties": {
"alertId": {
"type": "string"
},
"alertRule": {
"type": "string"
},
"severity": {
"type": "string"
},
"signalType": {
"type": "string"
},
"monitorCondition": {
"type": "string"
},
"monitoringService": {
"type": "string"
},
"alertTargetIDs": {
"type": "array",
"items": {
"type": "string"
}
},
"originAlertId": {
"type": "string"
},
"firedDateTime": {
"type": "string"
},
"resolvedDateTime": {
"type": "string"
},
"description": {
"type": "string"
},
"essentialsVersion": {
"type": "string"
},
"alertContextVersion": {
"type": "string"
}
}
},
"alertContext": {
"type": "object",
"properties": {}
}
}
}
}
}
- 結果
3の情報を出力することができません
非共通アラートスキーマでパースした場合
- 与えたスキーマ
{
"type": "object",
"properties": {
"schemaId": {
"type": "string"
},
"data": {
"type": "object",
"properties": {
"SubscriptionId": {
"type": "string"
},
"AlertRuleName": {
"type": "string"
},
"SearchQuery": {
"type": "string"
},
"SearchIntervalStartTimeUtc": {
"type": "string"
},
"SearchIntervalEndtimeUtc": {
"type": "string"
},
"AlertThresholdOperator": {
"type": "string"
},
"AlertThresholdValue": {
"type": "integer"
},
"ResultCount": {
"type": "integer"
},
"SearchIntervalInSeconds": {
"type": "integer"
},
"LinkToSearchResults": {
"type": "string"
},
"LinkToFilteredSearchResultsUI": {
"type": "string"
},
"LinkToSearchResultsAPI": {
"type": "string"
},
"LinkToFilteredSearchResultsAPI": {
"type": "string"
},
"Description": {
"type": "string"
},
"Severity": {
"type": "string"
},
"SearchResult": {
"type": "object",
"properties": {
"tables": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"columns": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"type": {
"type": "string"
}
},
"required": [
"name",
"type"
]
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"required": [
"name",
"columns",
"rows"
]
}
},
"dataSources": {
"type": "array",
"items": {
"type": "object",
"properties": {
"resourceId": {
"type": "string"
},
"region": {
"type": "string"
},
"tables": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"resourceId",
"region",
"tables"
]
}
}
}
},
"WorkspaceId": {
"type": "string"
},
"ResourceId": {
"type": "string"
},
"AlertType": {
"type": "string"
}
}
}
}
}
- 結果
1~3の全てを出力させることができました
共通アラートスキーマの注意点
3.クエリ結果のリンクを共通アラートスキーマで表示できないのは、alertContextフィールドで定義された値だからです。
alertContextフィールドまでスキーマで定義すればパース自体はできますが、それは結局alertContextの数だけスキーマが必要になることを意味するので本末転倒になります。
とはいえessentialsフィールドの部分は共通化されていますので、alertContextフィールドを通知文に表示させることを諦めれば共通スキーマ一本でパースできることは間違いありません。
基本的に共通スキーマを選んでおけば問題なさそうでした。
結論
- 基本的に共通アラートスキーマを使えば問題なさそう
- 共通部分のessentialsと非共通部分のalertContextに分解して考える
- alertContextを通知文に出力させる場合は個別にスキーマの用意が必要
- 逆に、新規作成するアラートで非共通アラートスキーマを指定する必要も特にない印象
まとめ
通知を飛ばしたいだけでしたがそれなりに苦戦しました。
おまけ程度ですが、webhook.siteというテスト用のWebhook URLを一瞬で生成できる非常に便利なサービスがあるので、こちらでURLを生成して実際のJSONペイロードを確認するとデバッグがしやすくおすすめです。
Discussion