created: 2024-03-25T06:16:53.307Z
GCP で発生したエラーログをすべて Slack 通知するアラートポリシー
つくりたての GCP プロジェクトとかで、雑でいいのですべてのエラーの発生を簡単に通知してくれる terraform リソースを実装した。 おそらくある程度成熟したプロジェクトだとすごい量のエラーログがでていると思われるので、当然ながらそういう規模に向いたものではない。
すべてのエラーの発生
すべてのエラーの発生
すべて
と書いてあるけど、本当はすべてではないし、エラーだけではない。
このような条件で CloudLogging をフィルタしている。
severity=(ERROR OR CRITICAL OR ALERT OR EMERGENCY)
NOT protoPayload.@type="type.googleapis.com/google.cloud.audit.AuditLog"
ログレベルはエラー以上
severity=(ERROR OR CRITICAL OR ALERT OR EMERGENCY)
監査ログは除く
GCP 側が出してくれている「クラウド上でこんな操作がされているよ」というログは省く。
NOT protoPayload.@type="type.googleapis.com/google.cloud.audit.AuditLog"
この条件を入れないと「BigQuery の UI で作業してる時に SQL のシンタックスエラーがありましたよ」みたいなのも通知に乗ってしまうので省いている。
通知してくれるエラーの例
- Cloud Function で例外が発生した
- データ不整合か何かで BigQuery のスケジュールクエリが失敗した
- Firebase がつくってくれた Schedular ジョブの削除漏れが PubSub であったよ
個人レベルのプロジェクトだとだいたいこれでバグをファイルしていけるので、モニタリングをかっちりとやるほどの工数はかけられないけど、という場合に便利。
実装
condition_matched_log
をつかっている。
resource "google_monitoring_alert_policy" "ProjectAllErrorCatcher" {
project = var.GCP_PROJECT_ID
enabled = true
combiner = "OR"
display_name = "Catch all error log"
notification_channels = [
google_monitoring_notification_channel.slack_alert.name,
]
conditions {
display_name = "Catch all error(or higher) log"
condition_matched_log {
filter = <<-EOT
severity=(ERROR OR CRITICAL OR ALERT OR EMERGENCY)
NOT protoPayload.@type="type.googleapis.com/google.cloud.audit.AuditLog"
EOT
label_extractors = {
insert_id = "EXTRACT(insertId)"
log_name = "EXTRACT(logName)"
resource_type = "EXTRACT(resource.type)"
text_payload = "EXTRACT(textPayload)"
}
}
}
# https://cloud.google.com/logging/docs/logs-based-metrics/labels?hl=ja#api
documentation {
mime_type = "text/markdown"
content = <<-EOS
# GCP Project All Error Catcher
エラーが発生しました。以下のクエリで状況を確認できます
\`\`\`
insertId="$${log.extracted_label.insert_id}"
logName="$${log.extracted_label.log_name}"
resource.type="$${log.extracted_label.resource_type}"
\`\`\`
## textPayload
\`\`\`
$$
{log.extracted_label.text_payload}
\`\`\`
* jsonPayload, protoPayload のログは別途確認が必要です
EOS
}
alert_strategy {
auto_close = "10800s"
notification_rate_limit {
period = "1800s"
}
}
}