TerraformでGoogle Cloud Monitoringを活用してログ監視を実装してみた

こんにちは、SCSKの齋藤です。

今回は、Google Cloud Monitoring を活用してログ監視を実装してみました。Terraformを使用して、Cloud WorkflowsやDataformなどのログを監視し、SlackやPagerDutyに通知を送る仕組みを構築しました。

本記事では、その実装内容を紹介します。

この記事でわかること

  • TerraformでGoogle Cloud Monitoringのアラートポリシーを定義する方法
  • ログ監視の条件設定、通知先設定、環境ごとの設定の違い
  • 具体的な監視項目の設定例(Cloud Run, Composer)
  • 設定のポイントと工夫


実装の概要

Google Cloud MonitoringのアラートポリシーをTerraformで定義し、以下のようなログ監視を実装しました。

  • 特定のサービスの成功/失敗ログ監視
    • Cloud WorkflowsやCloud Run、Dataformなどの処理結果を監視し、成功や失敗を検知
  • データ処理パイプラインの状態監視
    • Composer(Airflow)のDAG実行結果を監視し、成功時に通知
  • 通知先としてSlackやPagerDutyを活用
    • 環境ごとに異なる通知先を設定し、本番環境ではPagerDutyを利用

 

実装のポイント

Terraformでのアラートポリシー定義

Terraformのgoogle_monitoring_alert_policyリソースを使って、ログ監視の条件や通知先を定義します。重要な属性は以下の通りです。

  • display_name: アラートポリシーの名前(Google Cloud Consoleに表示)
  • combiner: 複数の条件をどのように組み合わせるか
  • conditions: 監視する条件を定義するブロック
  • enabled: アラートポリシーを有効にするかどうか
  • alert_strategy: アラートがトリガーされた際の挙動を設定
  • notification_channels: 通知先チャネルのリスト
  • documentation: アラート発生時に表示するドキュメント

以下は、テンプレートとして再利用可能なアラートポリシーの例です。この例では、特定のリソースタイプのログから、特定のパターンに合致するログを検知します。

resource "google_monitoring_alert_policy" "example_alert_policy" {
  display_name = "Service - Example Alert"
  combiner     = "OR"
  conditions {
    display_name = "Example Condition"
    condition_matched_log {
      filter = <<EOT
        severity=INFO
        resource.type="example_resource_type"
        log_name="projects/example-project/logs/example-log"
        resource.labels.example_label =~ "example-pattern"
        EOT
      label_extractors = {
        key1 = "EXTRACT(jsonPayload.key1)"
        key2 = "EXTRACT(jsonPayload.key2)"
      }
    }
  }
  enabled = true
  alert_strategy {
    notification_prompts = ["OPENED"]
    notification_rate_limit {
      period = "300s" # 通知の頻度を制限
    }
    auto_close = "1800s" # 自動クローズの時間
  }
  notification_channels = [var.notification_channels["example_channel"]]
  documentation {
    content = <<EOT
    Key1: $${log.extracted_label.key1}
    Key2: $${log.extracted_label.key2}
    EOT
    mime_type = "text/markdown"
  }
}

コード解説:

  • filter: Cloud Monitoringのログフィルタを指定します。このフィルタによって、監視対象のログを絞り込みます。

    • severity=INFO: INFOレベル以上のログを対象とする。
    • resource.type="example_resource_type": 特定のリソースタイプ(例: gce_instance)のログを対象とする。
    • log_name="projects/example-project/logs/example-log": 特定のログ名(例: projects/my-project/logs/stdout)を対象とする。
    • resource.labels.example_label =~ "example-pattern": リソースのラベルに対して正規表現でマッチングを行う。
  • label_extractors: ログの内容から特定の情報を抽出します。抽出した情報は、通知内容に含めることができます。

    • key1 = "EXTRACT(jsonPayload.key1)"jsonPayloadkey1というフィールドの値を抽出する。
  • notification_rate_limit: アラート通知の頻度を制限します。過剰な通知を防ぐために重要です。

  • documentation: アラート発生時に表示されるドキュメントを記述します。抽出したログの情報を記載することで、問題の原因特定に役立ちます。

通知先の設定

通知先としてSlackやPagerDutyを利用しました。これはTerraformの変数として定義し、環境ごとの柔軟に切り替え可能にしています。

variable "notification_channels" {
  description = "通知チャネルのマッピング"
  type        = map(string)
}

ポイント:

  • type = map(string): 文字列型のキーと文字列型の値を持つマップとして定義します。
  • default: デフォルトの値を設定します。実際の環境に合わせて適切な値を設定してください。 これらのIDは、Google Cloud Consoleから取得できます。

環境ごとの柔軟な設定 

環境(開発、ステージング、本番)ごとに異なる設定を適用するため、var.envを使用しました。
本番環境ではPagerDuty通知を追加しています。

notification_channels = concat(
  [var.notification_channels["example_channel"]],
  var.env == "prod" ? [var.notification_channels["pagerduty_channel"]] : []
)

コード解説:

  • concat: 複数のリストを結合する関数です。
  • var.env == "prod" ? [var.notification_channels["pagerduty_channel"]] : []var.envprod(本番環境)の場合、PagerDutyの通知チャネルをリストに追加します。それ以外の場合は、空のリスト([])を追加します。

 

実装した監視項目の例

Cloud Runジョブのエラーログ監視

特定のジョブのエラーを検知し、通知を行う設定

resource "google_monitoring_alert_policy" "job_error_alert" {
  display_name = "Job - Error Detected"
  combiner     = "OR"
  conditions {
    display_name = "Job Error"
    condition_matched_log {
      filter = <<EOT
        severity>=ERROR
        resource.type="job_resource_type"
        resource.labels.job_name =~ "example-job-pattern"
      EOT
      label_extractors = {
        error_message = "EXTRACT(jsonPayload.error_message)"
      }
    }
  }
  enabled = true
  notification_channels = [var.notification_channels["error_channel"]]
  documentation {
    content   = <<EOT
      Job Name: $${resource.labels.job_name}
      Error Message: $${log.extracted_label.error_message}
    EOT
    mime_type = "text/markdown"
  }
}

Composer DAGの成功通知

AirflowのDAG実行結果を監視し、成功時に通知を行う設定

resource "google_monitoring_alert_policy" "dag_success_alert" {
  display_name = "Composer - DAG Success"
  combiner     = "OR"
  conditions {
    display_name = "DAG Success"
    condition_matched_log {
      filter = <<EOT
        resource.type="cloud_composer_environment"
        resource.labels.environment_name="example-composer-env"
        textPayload:("DagRun Finished" AND "state=success")
      EOT
    }
  }
  enabled = true
  notification_channels = [var.notification_channels["info_channel"]]
  documentation {
    content   = <<EOT
DAG実行が成功しました。
    EOT
    mime_type = "text/markdown"
  }
}

ポイント:

  • Cloud Runジョブのエラーログ監視では、severity>=ERRORでエラーレベルのログを絞り込み、resource.type="cloud_run_job"でCloud Runジョブのログに限定しています。
  • Composer DAGの成功通知では、textPayload:("DagRun Finished" AND "state=success")でログメッセージの内容を確認し、DAGの成功を判断しています。

 

実装の工夫

  1. 再利用性の高いテンプレート設計
    環境変数や通知チャンネルを変数化することで、異なるプロジェクトや環境でも簡単に適用可能な構成に
  2. 詳細なログ情報の抽出
    `label_extractors`を活用し、ログから必要な情報を抽出して通知内容に反映
  3. 通知の頻度制限
    `notification_rate_limit`を設定し、通知が過剰にならないように制御

 

参考ドキュメント

以下の公式ドキュメントを参考にしました。TerraformやGoogle Cloud Monitoringの設定に役立つ情報が記載されています。

Terraform関連

Google Cloud Monitoring関連

 

まとめ

Terraformを使用することで、Google Cloud Monitoringのログ監視を効率的に構築できます。テンプレート化により、他のプロジェクトや環境にも容易に適用でき、運用コストを削減できます。

今後は、さらに監視項目を増やし、Custom MetricsやLog-based Metricsを活用して、システム全体の可観測性を向上させていきたいと考えています。

この記事が、皆様のログ監視実装の一助となれば幸いです。

著者について

SCSK株式会社
ソリューション事業グループ
基盤ソリューション事業本部

齋藤雄太をフォローする

クラウドに強いによるエンジニアブログです。

SCSKクラウドサービス(Google Cloud)は、Google Cloudの多彩なAIや各種サービスを活用したワンストップソリューションを提供します。SCSKのノウハウや体制を有効活用し、業務課題の解決に必要な全体検討と組み合わせで、最適な業務実装まで支援します。

Google Cloud
シェアする
タイトルとURLをコピーしました