🧙‍♂️

[Azure]Azure Monitor アラートのJSONスキーマのまとめ

2023/03/30に公開

Azure MonitorのアラートのJSONスキーマには複数のパターンがあるようで、初見で迷子になりかけたので理解を整理します。

なぜ理解する必要があるのか

Azure MonitorからアラートをWebhookでSlackやTeamsに連携するときに理解する必要があるからです。連携する時の流れは大まかに以下の通りになりますが、

  1. Azure Monitorのアラートルールに合致した時にWebhookでアラートのペイロードをAzure Logic Appsに送信する
  2. Azure Logic AppsがJSONをSlack/Teamsが受け付けられるようにパースして成型する
  3. Azure Logic AppsからSlack/TeamsのIncoming Webhookに成型したアラートを送信する

2の作業でAzure Monitorが飛ばすJSONのスキーマを理解する必要があります。
この記事では連携するための詳細な手順は説明しませんが、1~3の全体の流れは以下が参考になるかと思います。(そのうち記事にするかもしれません)
https://www.challenge-cf.jp/post/microsoft-365-teamsのwebhookとazure-monitorの連携
https://learn.microsoft.com/ja-jp/azure/azure-monitor/alerts/alerts-logic-apps?tabs=send-email

アラートスキーマの全体像

まずMSのドキュメントから、スキーマの全体像を図として整理すると以下のようになりました。
共通アラートスキーマ非共通アラートスキーマという概念があり、要するに元々バラバラだったスキーマが統合され、現在はどちらでも選べるという状態と理解しました。[1]

非共通アラートスキーマ

https://learn.microsoft.com/ja-jp/azure/azure-monitor/alerts/alerts-non-common-schema-definitions
アラートの種別ごとに個別定義されたスキーマで、以下の3種類があります。
※現在も存続しているのは、おそらく過去に作成したアラートとの互換性の問題?

  • メトリックアラート
    • 使用例:エージェント経由で収集した仮想マシンのメトリクス(CPU使用率など)の監視
  • ログアラート
    • 使用例:Log Analytics Workspaceに転送したログの監視
  • アクティビティログアラート
    • 使用例:特定のアクティビティログの監視

共通アラートスキーマ

https://learn.microsoft.com/ja-jp/azure/azure-monitor/alerts/alerts-common-schema

アラートごとに異なっていたスキーマを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ペイロードを確認するとデバッグがしやすくおすすめです。

脚注
  1. 共通アラートスキーマのリリース記事を参照。
    https://learn.microsoft.com/ja-jp/archive/blogs/mssvrpmj/alerts-in-azure-are-now-all-the-more-consistent ↩︎

Discussion