【Google Cloud】New Relicへのログ転送をCLIで構築・動作確認してみた

記事タイトルとURLをコピーする

はじめに

こんにちは、マネージドサービス部の福田です。
普段はAWSをメインに触っていますがGoogle Cloud上のログをNew Relicに送る機会がありましたので 設定の流れを備忘録として本ブログを書きます。

New Relicへログを送るために必要な設定はコンソール画面をポチポチ操作して設定するのも良いですが、今回は楽するために再現性を高めるために gcloud コマンド(CLI)中心 で構築しています。 また、New Relicへログを送る方法としては gcloud コマンドによる方法と、API を直接叩く方法の 2パターン をご紹介します。

構成の概要

今回のアーキテクチャは以下の通りです。

  1. Cloud Logging で条件に合うログ(severity >= ERROR)をフィルタリング
  2. Cloud Pub/Sub へ転送
  3. Pub/Sub の Push サブスクリプション機能で、New Relic Logs API へ送信

事前準備

作業にあたり、以下の準備が必要です。

  • Google Cloud プロジェクトと gcloud コマンドが使える環境
  • New Relic アカウント
  • New Relic Ingest URL(ログ転送用のエンドポイント URL )

New Relic の UI から Integrations & Agents > Google Cloud Platform Logs と進み、ログ転送用のエンドポイント URL を取得します。

要はNew Relic公式ドキュメントに沿って設定を進めていきます。

docs.newrelic.com

CLI でのリソース構築

まずは Cloud Shell へ移動します。

それでは早速構築していきます。
以下のスクリプトを Cloud Shell に貼り付ければ、Pub/Sub トピックの作成からログシンクの設定まで完了します。
※環境変数の PROJECT_IDNEW_RELIC_URL などは、ご自身の環境に合わせてください。

本スクリプトは単一プロジェクト用になります

# ===== 変数の設定 =====

# GCPプロジェクトID (ご自身のプロジェクトIDに変更してください)
export PROJECT_ID="your-project-id"

# New Relicから取得したIngest URL
# 末尾に &format=gcp が付いていることを確認してください
# API-Key=以降はご自身のキーに置き換わります
export NEW_RELIC_URL="New Relicから取得したIngest URL"

# 作成するリソースのID(任意の名前に変更可能です)
export TOPIC_ID="new-relic-export-topic"
export SUBSCRIPTION_ID="new-relic-export-sub"
export SINK_NAME="all-errors-to-new-relic-sink"

# gcloudのデフォルトプロジェクトを設定
gcloud config set project $PROJECT_ID


# ===== Pub/Subトピックとサブスクリプションの作成 =====

# 1. ログ転送用Pub/Subトピックを作成
gcloud pubsub topics create $TOPIC_ID

# 2. New RelicへPushするサブスクリプションを作成
# ここでPush先としてNew RelicのURLを指定します
gcloud pubsub subscriptions create $SUBSCRIPTION_ID \
  --topic $TOPIC_ID \
  --push-endpoint=$NEW_RELIC_URL \
  --ack-deadline=60


# ===== ログルーターシンクの作成と権限設定 =====

# 3. 転送対象のログを定義するフィルタ
# 【ここがポイント】
# 特定のリソースには限定せず「ERROR以上」すべてを対象にします
export LOG_FILTER='severity >= ERROR'

# 4. ログシンクを作成
gcloud logging sinks create $SINK_NAME \
  pubsub.googleapis.com/projects/$PROJECT_ID/topics/$TOPIC_ID \
  --log-filter="$LOG_FILTER"

# 5. シンク用のサービスアカウントIDを取得
# ログルーターがPub/Subに書き込むためのIDです
export SINK_SERVICE_ACCOUNT=$(gcloud logging sinks describe $SINK_NAME --format='value(writerIdentity)')

# 6. サービスアカウントにPub/Subへの書き込み権限を付与
gcloud pubsub topics add-iam-policy-binding $TOPIC_ID \
  --member=$SINK_SERVICE_ACCOUNT \
  --role='roles/pubsub.publisher'

動作確認:2つのパターンでテストする

構築ができたら動作確認です。今回は用途に合わせて2種類のテスト方法を紹介します。

パターン1:手軽に疎通確認 (gcloud コマンド)

「とにかく New Relic までログが届くか確認したい」という場合はこちらがおすすめです。
テスト時のポイントとして、gcloud コマンドでログを送る際は、疑似的に実在するリソース(Cloud SQL等)のログとして送る必要 があるようです(指定しないと上手くNew Relicへログが転送されませんでした)。

理由は、New Relic 側のエンティティ認識の仕様 にあると想像しています。 ※リソースタイプをglobalと指定をするとNew Relicへログが転送されませんでした。

  • 紐付けの問題: New Relic はログを特定の「エンティティ(DBやサーバー)」に紐付けようとします。globalSample のような抽象的なリソースタイプで送信すると、紐付け先が特定できず、ログが破棄される可能性があり
  • 必須ラベルの問題: 多くのリソースタイプには database_idzone といった必須ラベルがあり、これらが欠けているとログ自体が正しく処理されない可能性があり
# Cloud SQL を模した疎通確認コマンド
gcloud logging write "new-relic-test-log" \
  '{"message": "Test error log for New Relic integration check", "component": "connectivity-test", "status": "critical"}' \
  --payload-type=json \
  --severity=ERROR \
  --monitored-resource-type="cloudsql_database" \
  --monitored-resource-labels="project_id=$PROJECT_ID,database_id=$PROJECT_ID:test-db,region=asia-northeast1"

パターン2:本番に近いログで詳細テスト (API / curl)

「アプリが出力するような JSON 構造でテストしたい」「特定のリソース(GCEなど)としてログを送りたい」場合は、API を直接叩くこちらの方法を使います。

# 詳細なログシミュレーション
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://logging.googleapis.com/v2/entries:write \
  -d '{
  "entries": [
    {
      "logName": "projects/'$PROJECT_ID'/logs/test-application-log",
      "resource": {
        "type": "gce_instance",
        "labels": {
          "project_id": "'$PROJECT_ID'",
          "instance_id": "1234567890123456789",
          "zone": "asia-northeast1-a"
        }
      },
      "severity": "ERROR",
      "jsonPayload": {
        "message": "Critical Error: Database connection timeout",
        "component": "backend-api",
        "error_code": 500
      }
    }
  ]
}'

それぞれのテストの違いを解説

この2つのテスト方法は、以下のような違いがあります。

比較項目 パターン1: gcloud コマンド パターン2: API (curl)
主な目的 疎通確認用
New Relicへの経路が機能するかをサクッと確認する。
詳細検証用
New Relic 側でのログの見え方(パース処理など)や、特定リソース条件でのフィルタ確認を行う。
リソース指定 既存リソース(Cloud SQL等)を定義
※ New Relic がエンティティを認識しやすいよう、具体的なリソースIDを指定して送る。
自由に定義可能
JSON 内で gce_instance 等を定義し、必須ラベルもダミー値で埋めやすい。
メリット コマンドが短く、認証トークンなどの準備も不要でとにかく簡単 本番ログと同じような構造を作れるため、New Relic Parsing Rule のテスト等にも使える

結果確認

New Relic の Logs 画面を確認すると、どちらのログも無事に到着していることが確認できるはずです。

// パターン1のログ例(Cloud SQLとして認識される)
{
  "component": "connectivity-test",
  "insertId": "xxxxxxx",
  "logging.googleapis.com/timestamp": "2025-12-21T09:22:53.136831001Z",
  "logName": "xxxxxxx",
  "message": "Test error log for New Relic integration check",
  "newrelic.source": "api.logs",
  "plugin.type": "gcp",
  "publishTime": "2025-12-21T09:22:57.047Z",
  "receiveTimestamp": "2025-12-21T09:22:53.136831001Z",
  "resource.labels.database_id": "xxxxxxx",
  "resource.labels.project_id": "xxxxxxx",
  "resource.labels.region": "asia-northeast1-a",
  "resource.type": "cloudsql_database",
  "severity": "ERROR",
  "status": "critical",
  "subscription": "xxxxxxx",
  "timestamp": 1766308973136
}

// パターン2のログ例(GCEとして認識される)
{
  "component": "backend-api",
  "error_code": 500,
  "insertId": "xxxxxxx",
  "logging.googleapis.com/timestamp": "2025-12-21T09:15:27.791944048Z",
  "logName": "xxxxxxx",
  "message": "Critical Error: Database connection timeout",
  "newrelic.source": "api.logs",
  "plugin.type": "gcp",
  "publishTime": "2025-12-21T09:15:33.207Z",
  "receiveTimestamp": "2025-12-21T09:15:27.791944048Z",
  "resource.labels.instance_id": "1234567890123456789",
  "resource.labels.project_id": "xxxxxxx",
  "resource.labels.zone": "asia-northeast1-a",
  "resource.type": "gce_instance",
  "severity": "ERROR",
  "subscription": "xxxxxxx",
  "timestamp": 1766308527791
}

お片付け(リソース削除)

検証が終わってリソースが不要になった場合は、以下のコマンドで一括削除できます。

# ===== 変数の設定(作成時と同じもの)=====
export PROJECT_ID="your-project-id"
export TOPIC_ID="new-relic-export-topic"
export SUBSCRIPTION_ID="new-relic-export-sub"
export SINK_NAME="all-errors-to-new-relic-sink"
gcloud config set project $PROJECT_ID

# ===== 削除実行 =====
echo "▶ Deleting Log Sink..."
gcloud logging sinks delete $SINK_NAME --quiet

echo "▶ Deleting Pub/Sub Subscription..."
gcloud pubsub subscriptions delete $SUBSCRIPTION_ID --quiet

echo "▶ Deleting Pub/Sub Topic..."
gcloud pubsub topics delete $TOPIC_ID --quiet

echo "削除完了しました"

まとめ

今回は Google Cloud のログを New Relic に転送する設定を CLI 中心で行ってみました。
普段 AWS を触っている身として、Google Cloud は発見が多かったです。

特に「ログシンク」の機能は魅力的だと感じました。AWS でいうところの「サブスクリプションフィルター」に近い機能ですが、組織全体に対して一括で設定できる点 が非常に便利です。

AWS ではロググループごとに設定が必要になることが多いですが、Google Cloud ではシンクで組織配下の全リソースのログを対象にフィルタリングできるため、管理コストの面で大きなメリットを感じました。
(今回のスクリプトはプロジェクト単体用ですが、コマンドにオプションを追加すれば組織レベルの集約シンクも同様に作成可能です。もちろん、設定を誤ると意図しないログまで大量に転送してしまうリスクはありそうですが…)

ちなみにログシンクはフォルダまたは組織ごとに最大200まで設定が可能だそうです。

docs.cloud.google.com

これからもGoogle Cloudを触っていきたいと思うので、ちょくちょくブログを書きながら学んでいきたいと思います。
本ブログがどなたかの参考になれば幸いです。

・福田 圭(記事一覧)

・マネージドサービス部 所属
・X(Twitter):@soundsoon25

2023 New Relic Partner Trailblazer。New Relic Trailblazer of the Year 2025受賞。New Relic User Group運営。