📧

ログベース指標に基いた通知に、ログの一部を含めたい。textPayloadとかを。

2024/05/17に公開

クラウドエースの亀梨です。
監視通報メールを受け取ったとき、具体的な情報が掲載されていてほしいですよね。
Cloud Monitoring のログベース指標では、ログ出力というイベントに起因する通知を構成することができます。
そこで「ラベル」機能を設定することによって、その送信される通知に、元となったログの全部または一部を含めることができます。

TL;DR 〜 この記事の要約

  • ログベースの指標を作成する際、「ラベル」を付与するよう指定することができる。
  • 「ラベル」には、LogEntry の一部を抽出した値がセットされる。
  • このラベル条件に欲しい情報を指定すれば、通知に欲しい情報を出すことができる。

構築手順

事前準備1: ログデータの蓄積

「ログベースの指標」UI がラベルを作成するとき、候補となるフィールドは、既存のログメッセージから取得されるようです。
そのため、あらかじめログデータを用意しておかないと、作成時に出て来ずにハマります。

今回は、テキストログと、構造化ログ ( JSON 形式 )の両方を試したいので、以下の2つのログを gcloud コマンドで Logging API に送っておきます。

$ gcloud logging write --payload-type=text my-test-log 'this is plain text'
$ gcloud logging write --payload-type=json my-test-log '{ "message": "this is message", "weather": "rainbow" }'

このコマンドでは、(デフォルトのプロジェクト)の LogName "my-test-log" に対して、テキスト/構造化形式で、メッセージを投入しています。

結果、以下のようなログエントリーが記録されました。この情報は、Cloud Logging の画面で確認できます。

2つのログ
テキストログの詳細
text log
構造化ログの詳細
json log

テキスト形式ログには、フィールド「 textPayload 」、JSON 形式ログには、フィールド「 jsonPayload.weather 」があることを覚えておいてください。

事前準備2: logging クエリ式の作成

次項でログベースの指標を作成するにあたって、対象のログを間違いなく抽出できるクエリ(フィルタ)が必要になります。
このクエリは、Cloud Logging の UI で対話的に作って試すことができます。

  1. Cloud Logging のトップ画面に移動し、「クエリをクリア」ボタンを押して、既に設定されているフィルタ条件を消去してください。場合によっては、時間帯の指定も忘れずに再設定しましょう。
  2. 「リソース」ドロップダウンから、対象となる Google プロダクトを選択しましょう。ただし、今回の例ではプロダクトに関連しないサンプルログを扱うので、ここでは何も指定しません。
  3. 「ログ名」ドロップダウンで「my-test-log」を選択して適用します。
  4. 前項で投入した、2種類のログだけが、抽出されて表示されています。(されていない場合は、時間帯が合っているか再確認してください。)
  5. ここで、「クエリを表示」ボタンを押すと、いままさに画面に表示されているログを抽出するためのクエリ式が以下のように表示されます。
logName="projects/{YOUR_PROJECT_NAME}/logs/my-test-log"

もし、より詳細な絞りこみ条件が必要であれば、Logging クエリ言語で、条件を書き加えることができます。

ログベース指標の作成

Cloud Logging トップ画面 > メニュー > ログベースの指標 を表示し、項目「ユーザー定義の指標」 > 「指標を作成」ボタンから作成を開始します。

  • 「指標タイプ」は Counter
  • 「指標の名前」は任意の名前
  • 「単位」は空欄
  • 「ログのスコープの選択」は「プロジェクトのログ」
  • 「フィルタの作成」フィールドには、前項で作成した logName= ... のフィルタ式を貼り付け

のように進めてください。
最後に次項で「ラベル」を指定します。重要なので、まだ作成を確定せず、ちょっと待ってください。

ログベース指標に「ラベル」を埋め込む

ここで言うラベルとは、抽出条件とその名前のセットのことです。ラベルを設定すると、ラベルに基いてログの頻度を分析できるようになります。

  • 「ラベルを追加」ボタンを押します。
  • ラベル名を指定します。日本語は使えません。
  • ラベル タイプ: STRING を選択してください。

次に「フィールド名」をクリックすると、以下のようにフィールド名を選択するドロップダウンが表示されます。(※されないこともあります。次項で説明します)

フィールドの選択

この中から、ラベルに割り当てたいフィールドを選択して指定してください。
フィールド全体でなく、フィールドの一部分だけを切り出したい場合は、次の「正規表現」入力欄に指定することで実現できます。

ドロップダウンが空表示だった場合

もし、���ィールド選択ドロップダウンが表示されなかった場合は、手動で以下のようにフィールド名を指定してください。

  • テキストログの場合
textPayload
  • 構造化ログの場合
jsonPayload.weather

ラベル設定後の画面

ラベル一覧

このようにラベルが設定できたら、「指標を作成」してください。
ラベルの定義は、指標を作成したあとから再度、編集することもできます。

もし「ラベルのフィールドが正しくない」というエラーで保存できない場合は、抽出対象のログがまだ記録されていないか、クエリ式が正しくない可能性が高いです。見直してください。

アラートポリシーの作成

「ログベース指標画面」で、さきほど作成した指標が表示されていると思います。
表の右端、縦3点のメニューを開いてください。

指標メニュー

「指標に基づいて通知を作成する」項目を選ぶことで、アラートポリシーの作成に進みます。

この記事では、以下の観点でアラートポリシーを作ります。別の要件については説明しません。

  • ログ1件につき、1件の通知が欲しい
  • ログが記録されたら、すぐ通知して欲しい

「アラート条件」> New Condition

  • Select a metric: metric.type="logging.googleapis.com/user/my-test-log" が指定済みです。
  • ローリングウィンドウ: 最短の「1分」にします。
  • ローリングウィンドウ関数: delta にします。
  • Across time series > 時系列集計: none にします。
  • Across time series > 時系列のグループ化の基準: 空欄 にします。

New Condition > トリガーの設定

  • Condition Types: Threshold を選択。
  • Alert Trigger: 任意の時系列の違反 を選択。
  • しきい値の位置: しきい値より上 を選択。
  • しきい値: 0
  • Advanced Options > この期間に条件が満たされた場合にトリガーします: 0秒
  • 条件名: 任意の名前を指定。

通知と名前

  • 通知チャンネル: ご利用のチャンネルを指定してください。この例ではメールを使います。
  • 他の項目: 任意に指定してください。

動作テスト

アラートポリシーが作成できたら、「事前準備1: ログデータの蓄積」で投入した gcloud logging write コマンドを再度実行して、トリガーが正常動作するかを確認しましょう。

結果、届いた通知メールの、以下ピンク色で示した箇所に、元々のログの一部が抽出されているのがわかります。

テキストログに対応した通報メール
text mail
構造化ログに対応した通報メール
json mail

ログベースの指標で抽出したログメッセージの中身を通知に反映させることができました。

補足: 「ラベル」を作成するということの、本来の意義

この記事の主題は「ログの内容を通知メールに出す」ことなので、意図的に説明を省いていました。
「ラベル」を設定することで、元々1つにまとまっていた時系列指標を、ラベルの分の時系列指標に分割して扱うことが可能になります。

この画像では、Metrics Explorer で対象のログベース指標を表示したところです。
クエリ ツールバーの「by」項目で「weather」を指定し、付与されたラベルの値ごとの頻度を見ることができます。

label selector

「by」に「weather」を指定した場合のマウスホバーで表示される凡例です。「weather」に指定した値がそのまま反映されていることがわかります。

weather label

同様に「text」を指定した場合の凡例です。今回は一種類のみなので、凡例も一種類のみになっています。

text label

この記事で説明しなかったこと

ログベース指標のドキュメントには、通知の本文欄で変数が使えるし、それによってログの中身を表示できますよ!と書いてあるのですが、何回か試しても (null) な表示になってしまい、うまく行きませんでした。
textPayload 全体、および jsonPayload.(子要素) のラベルによる切り出しは問題なくできたため、こちらを紹介しています。
通知本文で変数参照する方式は、またの機会に検証できればと思います。

Discussion