TL;DR
- アプリケーションからStackdriverに吐き出したエラーログをアラート(メールやSlack)に含めたかった
- しかし、GCPの仕様上、ログを起点としたアラートにログ本文を埋め込むことができなかった
- 仕方がないので、妥協してエラーの種類が分かる情報をメトリクスのラベルとして埋め込むことにした
- (しかし、これはラベルの本来の使い方では無さそうなので不安は残る)
背景
GCP Functionsを使ったアプリケーションを開発していました。
これをリリースし、運用するにあたって、アプリケーションが吐き出すエラーログを検知して、アラートを飛ばしたいという要求が出てきました。
エラーログの中でも、通知が必要なものを絞り混むために、 [[ALERT_ERROR]]
のようなテキストが埋め込まれたログのみ通知することにしました。
さらに、運用フローをできるだけ機械的に回せるようにするため、続いてエラーの種類を識別するテキストを埋め込んでいました。
これにエラーの詳細情報、各種変数などが加わったものがログになっています。
例: [[ALERT_ERROR]] SOMETHING_HAPPENED Some bad things happened. foo:[1000] bar:[xxxxx]
さて、我々はアラートのメール(Slackでも何でも良いのですが、ひとまずメールにしておきましょう)を見て、どんなエラーが起きたのかを知りたかったので、ログの本文を入れようとしたのですが…。
なぜだか分かりませんが、GCPにはこれを実現する手段が用意されていませんでした。
妥協案
アラートに含められるドキュメントテンプレートの変数を探したり、ログベースの指標を見たりしたのですが、どうもログ本文を埋め込める方法ありません。
が、ログベースの指標(メトリクス)ラベルを使うと、何とかログ本文から、エラーの種類が識別できる情報は含めることができることが分かりました。
[[ALERT_ERROR]] SOMETHING_HAPPENED Some bad things happened. foo:[1000] bar:[xxxxx]
このログで言えば、 SOMETHING_HAPPENED
の部分ですね。
設定方法
1. ログベースの指標の作成
公式ドキュメントに従い、ユーザー定義指標を作成します。
この場合、 [[ALERT_ERROR]]
と付くものを検知したいので、フィルタに [[ALERT_ERROR]]
を入力します。
2. ログベースの指標のラベルにエラー種類を示すテキストを追加
- 指標の設定で、ラベルの「アイテムの追加」をクリック
- 名前を適当に決定(alert_typeとしています)
- フィールド名にログの本文を示すtextPayloadを選択
- 抽出の正規表現に
\[\[ALERT_ERROR\]\]\s+([a-zA-Z_]+)
を入力-
[[ALERT_ERROR]] SOMETHING_HAPPENED Some bad things happened. foo:[1000] bar:[xxxxx]
のSOMETHING_HAPPENED
を取り出す正規表現
-
補足
ログベース指標のドキュメントによると、ラベルにはかなりの制約があります。
- 長さが 100 文字以下である。
- 正規表現 [a-zA-Z][a-zA-Z0-9_]* と一致する。
- 文字列「log」以外も含まれる。
という条件を満たす必要があります。また、
注: ラベルを作成するのは、指標データを分類または要約するために値を識別する必要がある場合のみです。データ フィールドに単に名前を付けるためにラベルを使用しないでください。
あるいは
注意: insertId フィールドや timestamp フィールドなど、個々のログエントリに固有のラベル値を抽出しないでください。このようなラベル値の場合、ポイントを 1 つしか含まない時系列がログエントリと同じ数だけ作成されてしまいます。
という注意事項があります。
自動生成されるIDなどは、通知に出したい場合でもラベル値を利用するのは避けた方が良さそうです。
3. アラートポリシーを作成
- 作成したログベースの指標の三点リーダから「指標に基づいて通知を作成する」をクリック
- 適切に条件を設定
- Documentationに変数を使って指標のラベルを記述(
${metric.label.[ラベル名]}
)
- 「SAVE」をクリック
以上で、設定は完了です。
アラートの発生条件を満たせば、通知メールの「Policy documentation」欄に、
アラート種別: SOMETHING_HAPPEND
のように表示されているはずです。
最後に
元々やりたかったことは、単にエラーログ本文を通知に載せる、ということです。
これが不可能なので、せめてエラーの種類が分かる情報だけでも載せる、という苦肉の策を取っています。
もっと素直にログ本文を載せる方法をご存知の方がいれば、教えていただけると幸いです。
もし無いようでしたら、Googleさん、何とかしてくると幸いです。
(ログを起点にするアラートにログを載せたいって至って普通のことだと思うんだけどなぁ)