チュートリアル: Cloud Run へのイベント転送をデバッグする


このチュートリアルでは、Cloud Storage から Cloud Audit Logs を使用する未認証の Cloud Run サービスへ、Eventarc を使用してイベントを転送するときに発生するランタイム エラーのトラブルシューティング方法について説明します。

目標

このチュートリアルでは、次のタスクを行う方法を説明します。

  1. コンテナ イメージを保存する Artifact Registry 標準リポジトリを作成する。
  2. イベントソースとなる Cloud Storage バケットを作成する。
  3. コンテナ イメージをビルドしてアップロードし、Cloud Run にデプロイする。
  4. Eventarc トリガーを作成する。
  5. ファイルを Cloud Storage バケットにアップロードする。
  6. ランタイム エラーのトラブルシューティングと修正を行う。

費用

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

始める前に

組織で定義されているセキュリティの制約により、次の手順を完了できない場合があります。トラブルシューティング情報については、制約のある Google Cloud 環境でアプリケーションを開発するをご覧ください。

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Google Cloud CLI をインストールします。
  3. gcloud CLI を初期化するには:

    gcloud init
  4. Google Cloud プロジェクトを作成または選択します

    • Google Cloud プロジェクトを作成します。

      gcloud projects create PROJECT_ID

      PROJECT_ID は、作成する Google Cloud プロジェクトの名前に置き換えます。

    • 作成した Google Cloud プロジェクトを選択します。

      gcloud config set project PROJECT_ID

      PROJECT_ID は、実際の Google Cloud プロジェクト名に置き換えます。

  5. Google Cloud プロジェクトで課金が有効になっていることを確認します

  6. Artifact Registry, Cloud Build, Cloud Logging, Cloud Run, Cloud Storage, Eventarc, and Pub/Sub API を有効にします。

    gcloud services enable artifactregistry.googleapis.comcloudbuild.googleapis.comeventarc.googleapis.comlogging.googleapis.compubsub.googleapis.comrun.googleapis.comstorage.googleapis.com
  7. Google Cloud CLI をインストールします。
  8. gcloud CLI を初期化するには:

    gcloud init
  9. Google Cloud プロジェクトを作成または選択します

    • Google Cloud プロジェクトを作成します。

      gcloud projects create PROJECT_ID

      PROJECT_ID は、作成する Google Cloud プロジェクトの名前に置き換えます。

    • 作成した Google Cloud プロジェクトを選択します。

      gcloud config set project PROJECT_ID

      PROJECT_ID は、実際の Google Cloud プロジェクト名に置き換えます。

  10. Google Cloud プロジェクトで課金が有効になっていることを確認します

  11. Artifact Registry, Cloud Build, Cloud Logging, Cloud Run, Cloud Storage, Eventarc, and Pub/Sub API を有効にします。

    gcloud services enable artifactregistry.googleapis.comcloudbuild.googleapis.comeventarc.googleapis.comlogging.googleapis.compubsub.googleapis.comrun.googleapis.comstorage.googleapis.com
  12. プロジェクト作成者には、オーナーロールroles/owner)が付与されます。デフォルトでは、この Identity and Access Management(IAM)ロールには、ほとんどの Google Cloud リソースへの完全アクセス権に必要な権限が含まれており、この手順は省略できます。

    プロジェクト作成者でない場合は、プロジェクトで適切なプリンシパルに必要な権限を付与する必要があります。プリンシパルは Google アカウント(エンドユーザーの場合)やサービス アカウント(アプリケーションとコンピューティング ワークロードの場合)になることもあります。詳細については、イベントの宛先のロールと権限のページをご覧ください。

    デフォルトでは、Cloud Build の権限には、Artifact Registry アーティファクトをアップロードおよびダウンロードするための権限が含まれています

    必要な権限

    このチュートリアルを完了するために必要な権限を取得するには、プロジェクトに対する次の IAM ロールを付与するよう管理者に依頼してください。

    ロールの付与の詳細については、アクセス権の管理をご覧ください。

    必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

  13. Cloud Storage の場合は、ADMIN_READDATA_WRITEDATA_READ のデータアクセス タイプの監査ロギングを有効にします。

    1. Google Cloud プロジェクト、フォルダ、または組織に関連付けられた Identity and Access Management(IAM)ポリシーを読み取り、一時ファイルに保存します。
      gcloud projects get-iam-policy PROJECT_ID > /tmp/policy.yaml
    2. テキスト エディタで /tmp/policy.yaml を開き、auditConfigs セクションで監査ログの構成のみを追加または変更します。

      auditConfigs:
      - auditLogConfigs:
        - logType: ADMIN_READ
        - logType: DATA_WRITE
        - logType: DATA_READ
        service: storage.googleapis.com
      bindings:
      - members:
      [...]
      etag: BwW_bHKTV5U=
      version: 1
    3. 新しい IAM ポリシーを作成します。
      gcloud projects set-iam-policy PROJECT_ID /tmp/policy.yaml

      上記のコマンドで別の変更との競合が報告された場合は、IAM ポリシーの読み取りからやり直してください。詳細については、API でデータアクセス監査ログを構成するをご覧ください。

  14. Compute Engine サービス アカウントに eventarc.eventReceiver ロールを付与します。

    export PROJECT_NUMBER="$(gcloud projects describe $(gcloud config get-value project) --format='value(projectNumber)')"
    
    gcloud projects add-iam-policy-binding $(gcloud config get-value project) \
        --member=serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com \
        --role='roles/eventarc.eventReceiver'
    

  15. 2021 年 4 月 8 日以前に Pub/Sub サービス アカウントを有効にした場合は、Pub/Sub サービス アカウントに iam.serviceAccountTokenCreator ロールを付与します。

    gcloud projects add-iam-policy-binding $(gcloud config get-value project) \
        --member="serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"\
        --role='roles/iam.serviceAccountTokenCreator'
    

  16. このチュートリアルで使用するデフォルトを設定します。
    export REGION=us-central1
    gcloud config set run/region ${REGION}
    gcloud config set run/platform managed
    gcloud config set eventarc/location ${REGION}
    

Artifact Registry 標準リポジトリを作成する

コンテナ イメージを保存する Artifact Registry 標準リポジトリを作成します。

gcloud artifacts repositories create REPOSITORY \
    --repository-format=docker \
    --location=$REGION

REPOSITORY は、リポジトリの一意の名前に置き換えます。

Cloud Storage バケットを作成する

Cloud Run サービスのイベントソースとして、2 つのリージョンに Cloud Storage バケットを作成します。

  1. us-east1 にバケットを作成します。

    export BUCKET1="troubleshoot-bucket1-PROJECT_ID"
    gsutil mb -l us-east1 gs://${BUCKET1}
    
  2. us-west1 にバケットを作成します。

    export BUCKET2="troubleshoot-bucket2-PROJECT_ID"
    gsutil mb -l us-west1 gs://${BUCKET2}
    

イベントソースの作成後、イベント レシーバ サービスを Cloud Run にデプロイします。

イベント レシーバーをデプロイする

イベントを受信してロギングする Cloud Run サービスをデプロイします。

  1. GitHub リポジトリのクローンを作成して、コードサンプルを取得します。

    Go

    git clone https://github.com/GoogleCloudPlatform/golang-samples.git
    cd golang-samples/eventarc/audit_storage
    

    Java

    git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git
    cd java-docs-samples/eventarc/audit-storage
    

    .NET

    git clone https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git
    cd dotnet-docs-samples/eventarc/audit-storage
    

    Node.js

    git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
    cd nodejs-docs-samples/eventarc/audit-storage
    

    Python

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
    cd python-docs-samples/eventarc/audit-storage
    
  2. このチュートリアルのコードが、次の内容を含んでいることを確認します。

    • HTTP POST リクエスト内で受信イベントを CloudEvent として受け取るイベント ハンドラ:

      Go

      
      // Processes CloudEvents containing Cloud Audit Logs for Cloud Storage
      package main
      
      import (
      	"fmt"
      	"log"
      	"net/http"
      	"os"
      
      	cloudevent "github.com/cloudevents/sdk-go/v2"
      )
      
      // HelloEventsStorage receives and processes a Cloud Audit Log event with Cloud Storage data.
      func HelloEventsStorage(w http.ResponseWriter, r *http.Request) {
      	if r.Method != http.MethodPost {
      		http.Error(w, "Expected HTTP POST request with CloudEvent payload", http.StatusMethodNotAllowed)
      		return
      	}
      
      	event, err := cloudevent.NewEventFromHTTPRequest(r)
      	if err != nil {
      		log.Printf("cloudevent.NewEventFromHTTPRequest: %v", err)
      		http.Error(w, "Failed to create CloudEvent from request.", http.StatusBadRequest)
      		return
      	}
      	s := fmt.Sprintf("Detected change in Cloud Storage bucket: %s", event.Subject())
      	fmt.Fprintln(w, s)
      }
      

      Java

      import io.cloudevents.CloudEvent;
      import io.cloudevents.rw.CloudEventRWException;
      import io.cloudevents.spring.http.CloudEventHttpUtils;
      import org.springframework.http.HttpHeaders;
      import org.springframework.http.HttpStatus;
      import org.springframework.http.ResponseEntity;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RequestHeader;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestMethod;
      import org.springframework.web.bind.annotation.RestController;
      
      @RestController
      public class EventController {
      
        @RequestMapping(value = "/", method = RequestMethod.POST, consumes = "application/json")
        public ResponseEntity<String> receiveMessage(
            @RequestBody String body, @RequestHeader HttpHeaders headers) {
          CloudEvent event;
          try {
            event =
                CloudEventHttpUtils.fromHttp(headers)
                    .withData(headers.getContentType().toString(), body.getBytes())
                    .build();
          } catch (CloudEventRWException e) {
            return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
          }
      
          String ceSubject = event.getSubject();
          String msg = "Detected change in Cloud Storage bucket: " + ceSubject;
          System.out.println(msg);
          return new ResponseEntity<>(msg, HttpStatus.OK);
        }
      }

      .NET

      
      using Microsoft.AspNetCore.Builder;
      using Microsoft.AspNetCore.Hosting;
      using Microsoft.AspNetCore.Http;
      using Microsoft.Extensions.DependencyInjection;
      using Microsoft.Extensions.Hosting;
      using Microsoft.Extensions.Logging;
      
      public class Startup
      {
          public void ConfigureServices(IServiceCollection services)
          {
          }
      
          public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
          {
              if (env.IsDevelopment())
              {
                  app.UseDeveloperExceptionPage();
              }
      
              logger.LogInformation("Service is starting...");
      
              app.UseRouting();
      
              app.UseEndpoints(endpoints =>
              {
                  endpoints.MapPost("/", async context =>
                  {
                      logger.LogInformation("Handling HTTP POST");
      
                      var ceSubject = context.Request.Headers["ce-subject"];
                      logger.LogInformation($"ce-subject: {ceSubject}");
      
                      if (string.IsNullOrEmpty(ceSubject))
                      {
                          context.Response.StatusCode = 400;
                          await context.Response.WriteAsync("Bad Request: expected header Ce-Subject");
                          return;
                      }
      
                      await context.Response.WriteAsync($"GCS CloudEvent type: {ceSubject}");
                  });
              });
          }
      }
      

      Node.js

      const express = require('express');
      const app = express();
      
      app.use(express.json());
      app.post('/', (req, res) => {
        if (!req.header('ce-subject')) {
          return res
            .status(400)
            .send('Bad Request: missing required header: ce-subject');
        }
      
        console.log(
          `Detected change in Cloud Storage bucket: ${req.header('ce-subject')}`
        );
        return res
          .status(200)
          .send(
            `Detected change in Cloud Storage bucket: ${req.header('ce-subject')}`
          );
      });
      
      module.exports = app;

      Python

      @app.route("/", methods=["POST"])
      def index():
          # Create a CloudEvent object from the incoming request
          event = from_http(request.headers, request.data)
          # Gets the GCS bucket name from the CloudEvent
          # Example: "storage.googleapis.com/projects/_/buckets/my-bucket"
          bucket = event.get("subject")
      
          print(f"Detected change in Cloud Storage bucket: {bucket}")
          return (f"Detected change in Cloud Storage bucket: {bucket}", 200)
      
      
    • イベント ハンドラを使用するサーバー:

      Go

      
      func main() {
      	http.HandleFunc("/", HelloEventsStorage)
      	// Determine port for HTTP service.
      	port := os.Getenv("PORT")
      	if port == "" {
      		port = "8080"
      	}
      	// Start HTTP server.
      	log.Printf("Listening on port %s", port)
      	if err := http.ListenAndServe(":"+port, nil); err != nil {
      		log.Fatal(err)
      	}
      }
      

      Java

      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      
      @SpringBootApplication
      public class Application {
        public static void main(String[] args) {
          SpringApplication.run(Application.class, args);
        }
      }

      .NET

          public static void Main(string[] args)
          {
              CreateHostBuilder(args).Build().Run();
          }
          public static IHostBuilder CreateHostBuilder(string[] args)
          {
              var port = Environment.GetEnvironmentVariable("PORT") ?? "8080";
              var url = $"http://0.0.0.0:{port}";
      
              return Host.CreateDefaultBuilder(args)
                  .ConfigureWebHostDefaults(webBuilder =>
                  {
                      webBuilder.UseStartup<Startup>().UseUrls(url);
                  });
          }
      

      Node.js

      const app = require('./app.js');
      const PORT = parseInt(process.env.PORT) || 8080;
      
      app.listen(PORT, () =>
        console.log(`nodejs-events-storage listening on port ${PORT}`)
      );

      Python

      import os
      
      from cloudevents.http import from_http
      
      from flask import Flask, request
      
      app = Flask(__name__)
      if __name__ == "__main__":
          app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
    • サービスの運用環境を定義する Dockerfile。Dockerfile の内容は言語によって異なります。

      Go

      
      # Use the offical golang image to create a binary.
      # This is based on Debian and sets the GOPATH to /go.
      # https://hub.docker.com/_/golang
      FROM golang:1.21-bookworm as builder
      
      # Create and change to the app directory.
      WORKDIR /app
      
      # Retrieve application dependencies.
      # This allows the container build to reuse cached dependencies.
      # Expecting to copy go.mod and if present go.sum.
      COPY go.* ./
      RUN go mod download
      
      # Copy local code to the container image.
      COPY . ./
      
      # Build the binary.
      RUN go build -v -o server
      
      # Use the official Debian slim image for a lean production container.
      # https://hub.docker.com/_/debian
      # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
      FROM debian:bookworm-slim
      RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
          ca-certificates && \
          rm -rf /var/lib/apt/lists/*
      
      # Copy the binary to the production image from the builder stage.
      COPY --from=builder /app/server /server
      
      # Run the web service on container startup.
      CMD ["/server"]
      

      Java

      
      # Use the official maven image to create a build artifact.
      # https://hub.docker.com/_/maven
      FROM maven:3-eclipse-temurin-17-alpine as builder
      
      # Copy local code to the container image.
      WORKDIR /app
      COPY pom.xml .
      COPY src ./src
      
      # Build a release artifact.
      RUN mvn package -DskipTests
      
      # Use Eclipse Temurin for base image.
      # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
      FROM eclipse-temurin:17.0.11_9-jre-alpine
      
      # Copy the jar to the production image from the builder stage.
      COPY --from=builder /app/target/audit-storage-*.jar /audit-storage.jar
      
      # Run the web service on container startup.
      CMD ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/audit-storage.jar"]
      

      .NET

      
      # Use Microsoft's official build .NET image.
      # https://hub.docker.com/_/microsoft-dotnet-core-sdk/
      FROM mcr.microsoft.com/dotnet/core/sdk:3.1-alpine AS build
      WORKDIR /app
      
      # Install production dependencies.
      # Copy csproj and restore as distinct layers.
      COPY *.csproj ./
      RUN dotnet restore
      
      # Copy local code to the container image.
      COPY . ./
      WORKDIR /app
      
      # Build a release artifact.
      RUN dotnet publish -c Release -o out
      
      
      # Use Microsoft's official runtime .NET image.
      # https://hub.docker.com/_/microsoft-dotnet-core-aspnet/
      FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine AS runtime
      WORKDIR /app
      COPY --from=build /app/out ./
      
      # Run the web service on container startup.
      ENTRYPOINT ["dotnet", "AuditStorage.dll"]

      Node.js

      
      # Use the official lightweight Node.js image.
      # https://hub.docker.com/_/node
      FROM node:20-slim
      # Create and change to the app directory.
      WORKDIR /usr/src/app
      
      # Copy application dependency manifests to the container image.
      # A wildcard is used to ensure both package.json AND package-lock.json are copied.
      # Copying this separately prevents re-running npm install on every code change.
      COPY package*.json ./
      
      # Install dependencies.
      # if you need a deterministic and repeatable build create a 
      # package-lock.json file and use npm ci:
      # RUN npm ci --omit=dev
      # if you need to include development dependencies during development
      # of your application, use:
      # RUN npm install --dev
      
      RUN npm install --omit=dev
      
      # Copy local code to the container image.
      COPY . .
      
      # Run the web service on container startup.
      CMD [ "npm", "start" ]
      

      Python

      
      # Use the official Python image.
      # https://hub.docker.com/_/python
      FROM python:3.11-slim
      
      # Allow statements and log messages to immediately appear in the Cloud Run logs
      ENV PYTHONUNBUFFERED True
      
      # Copy application dependency manifests to the container image.
      # Copying this separately prevents re-running pip install on every code change.
      COPY requirements.txt ./
      
      # Install production dependencies.
      RUN pip install -r requirements.txt
      
      # Copy local code to the container image.
      ENV APP_HOME /app
      WORKDIR $APP_HOME
      COPY . ./
      
      # Run the web service on container startup. 
      # Use gunicorn webserver with one worker process and 8 threads.
      # For environments with multiple CPU cores, increase the number of workers
      # to be equal to the cores available.
      CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

  3. Cloud Build でコンテナ イメージをビルドし、イメージを Artifact Registry にアップロードします。

    export PROJECT_ID=$(gcloud config get-value project)
    export SERVICE_NAME=troubleshoot-service
    gcloud builds submit --tag $REGION-docker.pkg.dev/${PROJECT_ID}/REPOSITORY/${SERVICE_NAME}:v1
  4. コンテナ イメージを Cloud Run にデプロイします。

    gcloud run deploy ${SERVICE_NAME} \
        --image $REGION-docker.pkg.dev/${PROJECT_ID}/REPOSITORY/${SERVICE_NAME}:v1 \
        --allow-unauthenticated

    デプロイに成功すると、コマンドラインにサービスの URL が表示されます。

トリガーを作成する

Cloud Run サービスをデプロイした後は、監査ログを使用して Cloud Storage からのイベントをリッスンするトリガーを設定します。

  1. Cloud Audit Logs を使用して転送された Cloud Storage イベントをリッスンする Eventarc トリガーを作成します。

    gcloud eventarc triggers create troubleshoot-trigger \
        --destination-run-service=troubleshoot-service \
        --event-filters="type=google.cloud.audit.log.v1.written" \
        --event-filters="serviceName=storage.googleapis.com" \
        --event-filters="methodName=storage.objects.create" \
        --service-account=${PROJECT_NUMBER}-compute@developer.gserviceaccount.com
    

    これにより、troubleshoot-trigger というトリガーが作成されます。

  2. troubleshoot-trigger が作成されたことを確認するには、次のコマンドを実行します。

    gcloud eventarc triggers list
    

    出力例を以下に示します。

    NAME: troubleshoot-trigger
    TYPE: google.cloud.audit.log.v1.written
    DESTINATION: Cloud Run service: troubleshoot-service
    ACTIVE: By 20:03:37
    LOCATION: us-central1
    

イベントを生成して表示する

サービスが正常にデプロイされ、Cloud Storage からイベントを受信できることを確認します。

  1. ファイルを作成して、BUCKET1 ストレージ バケットにアップロードします。

     echo "Hello World" > random.txt
     gsutil cp random.txt gs://${BUCKET1}/random.txt
    
  2. ログをモニタリングして、サービスがイベントを受信するかどうかを確認します。ログエントリを表示するには、次の手順を行います。

    1. ログエントリをフィルタして、JSON 形式で出力を返します。

      gcloud logging read "resource.labels.service_name=troubleshoot-service \
          AND textPayload:random.txt" \
          --format=json
    2. 次のようなログエントリを探します。

      "textPayload": "Detected change in Cloud Storage bucket: ..."
      

最初はログエントリが返されません。これは、セットアップに問題があり、調査する必要があることを意味します。

問題を調査する

サービスがイベントを受信しない原因を調査するプロセスを行います。

初期化時間

トリガーはすぐに作成されますが、トリガーが伝播されてイベントがフィルタされるまでに最大で 2 分かかることがあります。次のコマンドを実行して、トリガーが有効であることを確認します。

gcloud eventarc triggers list

出力は、トリガーのステータスを示します。次の例では、troubleshoot-trigger が 14:16:56 までに有効になります。

NAME                  TYPE                               DESTINATION_RUN_SERVICE  ACTIVE
troubleshoot-trigger  google.cloud.audit.log.v1.written  troubleshoot-service     By 14:16:56

トリガーが有効になったら、ファイルをストレージ バケットに再度アップロードします。イベントは Cloud Run サービスログに書き込まれます。サービスがイベントを受信しない場合は、イベントサイズに関連している可能性があります。

監査ログ

このチュートリアルでは、Cloud Audit Logs を使用して Cloud Storage イベントが転送され、Cloud Run に送信されます。Cloud Storage の監査ログが有効になっていることを確認します。

  1. Google Cloud コンソールで、[監査ログ] ページに移動します。

    監査ログに移動

  2. [Google Cloud Storage] チェックボックスをオンにします。
  3. [管理読み取り]、[データ読み取り]、[データ書き込み] のログタイプが選択されていることを確認します。

Cloud Audit Logs を有効にしたら、ファイルをストレージ バケットに再度アップロードして、ログを確認します。サービスがまだイベントを受信していない場合は、トリガーのロケーションに関連している可能性があります。

トリガーのロケーション

ロケーションが異なる複数のリソースが存在している可能性があります。Cloud Run ターゲットと同じリージョン内のソースからのイベントをフィルタする必要があります。詳細については、Eventarc でサポートされているロケーションEventarc のロケーションについてをご覧ください。

このチュートリアルでは、Cloud Run サービスを us-central1 にデプロイしました。eventarc/locationus-central1 に設定したため、同じロケーションにトリガーも作成しました。

しかし、2 つの Cloud Storage バケットは、us-east1us-west1 のロケーションに作成しました。これらのロケーションからイベントを受信するには、各ロケーションで Eventarc トリガーを作成する必要があります。

us-east1 に Eventarc トリガーを作成します。

  1. 既存のトリガーのロケーションを確認します。

    gcloud eventarc triggers describe troubleshoot-trigger
    
  2. ロケーションとリージョンを us-east1 に設定します。

    gcloud config set eventarc/location us-east1
    gcloud config set run/region us-east1
    
  3. コンテナ イメージをビルドして Cloud Run にデプロイし、再度イベント レシーバをデプロイします。

  4. us-east1 に新しいトリガーを作成します。

    gcloud eventarc triggers create troubleshoot-trigger-new \
      --destination-run-service=troubleshoot-service \
      --event-filters="type=google.cloud.audit.log.v1.written" \
      --event-filters="serviceName=storage.googleapis.com" \
      --event-filters="methodName=storage.objects.create" \
      --service-account=${PROJECT_NUMBER}-compute@developer.gserviceaccount.com
    
  5. トリガーが作成されたことを確認します。

    gcloud eventarc triggers list
    

    トリガーが初期化され、イベントの転送が開始するまでに 2 分ほどかかることがあります。

  6. トリガーが正しくデプロイされたことを確認するには、イベントを生成し表示します。

発生する可能性がある他の問題

Eventarc の使用時に、他の問題が発生することがあります。

イベントサイズ

送信するイベントは、イベントサイズの上限を超えないようにする必要があります。

以前にイベントを配信したトリガーが停止している

  1. ソースがイベントを生成していることを確認します。Cloud Audit Logs で、モニタリング対象サービスがログを出力していることを確認します。ログが記録されていてもイベントが配信されない場合は、サポートにお問い合わせください。

  2. 同じトリガー名の Pub/Sub トピックが存在することを確認します。 Eventarc は、Pub/Sub をトランスポート層として使用します。既存の Pub/Sub トピックを使用するか、トピックを自動的に作成して管理します。

    1. トリガーを一覧表示するには、gcloud eventarc triggers list をご覧ください。
    2. Pub/Sub トピックを一覧表示するには、次のコマンドを実行します。

      gcloud pubsub topics list
      
    3. Pub/Sub トピック名に、作成されたトリガーの名前が含まれていることを確認します。例:

      name: projects/PROJECT_ID/topics/eventarc-us-east1-troubleshoot-trigger-new-123

    Pub/Sub トピックがない場合は、特定のプロバイダ、イベントタイプ、Cloud Run の宛先のトリガーを再度作成します。

  3. サービスにトリガーが構成されていることを確認します。

    1. Google Cloud コンソールの [サービス] ページに移動します。

      [サービス] に移動

    2. サービスの名前をクリックして、[サービスの詳細] ページを開きます。

    3. [トリガー] タブをクリックします。

      サービスに関連付けられた Eventarc トリガーが表示されます。

  4. Pub/Sub 指標タイプを使用して、Pub/Sub トピックとサブスクリプションの健全性を確認します。

    • subscription/dead_letter_message_count 指標を使用して、転送済みの配信不能メッセージをモニタリングできます。この指標は、Pub/Sub がサブスクリプションから転送する配信不能メッセージの数を示します。

      トピックにメッセージが公開されていない場合は、Cloud Audit Logs で、モニタリング対象サービスがログを出力していることを確認します。ログが記録されていてもイベントが配信されない場合は、サポートにお問い合わせください。

    • subscription/push_request_count 指標を使用してプッシュ サブスクリプションをモニタリングし、指標を response_codesubcription_id でグループ化できます。

      push エラーが報告された場合は、Cloud Run サービスログを確認します。受信エンドポイントが OK 以外のステータス コードを返した場合、Cloud Run コードが期待どおりに機能していません。この場合、サポートにお問い合わせいただく必要があります。

    詳細については、指標しきい値のアラート ポリシーを作成するをご覧ください。

クリーンアップ

このチュートリアル用に新規プロジェクトを作成した場合は、そのプロジェクトを削除します。既存のプロジェクトを使用していて、このチュートリアルで行った変更を追加せずに残す場合は、チュートリアル用に作成したリソースを削除します

プロジェクトを削除する

課金をなくす最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。

プロジェクトを削除するには:

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

チュートリアル リソースの削除

  1. このチュートリアルでデプロイした Cloud Run サービスを削除します。

    gcloud run services delete SERVICE_NAME

    SERVICE_NAME は、選択したサービス名です。

    Cloud Run サービスは Google Cloud コンソールから削除することもできます。

  2. チュートリアルの設定時に追加した gcloud CLI のデフォルト構成を削除します。

    例:

    gcloud config unset run/region

    または

    gcloud config unset project

  3. このチュートリアルで作成した他の Google Cloud リソースを削除します。

    • Eventarc トリガーを削除します。
      gcloud eventarc triggers delete TRIGGER_NAME
      
      TRIGGER_NAME をトリガーの名前に置き換えます。

次のステップ