Tutorial: depurar eventos de roteamento para o Cloud Run


Neste tutorial, ensinamos como solucionar erros de ambiente de execução encontrados ao usar o Eventarc para rotear eventos do Cloud Storage para um serviço do Cloud Run não autenticado usando os Registros de auditoria do Cloud.

Objetivos

Nesta seção, mostramos como concluir as seguintes tarefas:

  1. Crie um repositório padrão do Artifact Registry para armazenar a imagem do contêiner do Docker.
  2. Criar um bucket do Cloud Storage para ser a origem do evento.
  3. Crie, faça upload e implante uma imagem de contêiner no Cloud Run.
  4. Criar gatilhos do Eventarc
  5. Faça upload do arquivo para o bucket do Cloud Storage.
  6. Solucione problemas e corrija erros de ambiente de execução.

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Antes de começar

As restrições de segurança definidas pela sua organização podem impedir que você conclua as etapas a seguir. Para informações sobre solução de problemas, consulte Desenvolver aplicativos em um ambiente restrito do 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. Install the Google Cloud CLI.
  3. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Enable the Artifact Registry, Cloud Build, Cloud Logging, Cloud Run, Cloud Storage, Eventarc, and Pub/Sub APIs:

    gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com eventarc.googleapis.com logging.googleapis.com pubsub.googleapis.com run.googleapis.com storage.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

    gcloud init
  9. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  10. Make sure that billing is enabled for your Google Cloud project.

  11. Enable the Artifact Registry, Cloud Build, Cloud Logging, Cloud Run, Cloud Storage, Eventarc, and Pub/Sub APIs:

    gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com eventarc.googleapis.com logging.googleapis.com pubsub.googleapis.com run.googleapis.com storage.googleapis.com
  12. Se você for o criador do projeto, receberá o papel de proprietário básico (roles/owner). Por padrão, esse papel do gerenciamento de identidade e acesso (IAM) inclui as permissões necessárias para acesso total à maioria dos recursos do Google Cloud, e você pode pular esta etapa.

    Se você não é o criador do projeto, as permissões necessárias precisam ser concedidas ao principal apropriado. Por exemplo, um principal pode ser uma Conta do Google (para usuários finais) ou uma conta de serviço (para aplicativos e cargas de trabalho de computação). Para mais informações, consulte a página Papéis e permissões do destino do evento.

    Observe que, por padrão, as permissões do Cloud Build incluem permissões para upload e download de artefatos do Artifact Registry.

    Permissões necessárias

    Para conseguir as permissões necessárias para concluir o tutorial, peça ao administrador para conceder a você os seguintes papéis do IAM no seu projeto:

    Para mais informações sobre como conceder papéis, consulte Gerenciar acesso.

    Também é possível conseguir as permissões necessárias com papéis personalizados ou outros papéis predefinidos.

  13. Para o Cloud Storage, ative a geração de registros de auditoria para os tipos de acesso a dados ADMIN_READ, DATA_WRITE e DATA_READ.

    1. Leia a política de gerenciamento de identidade e acesso (IAM) associada ao seu projeto, pasta ou organização do Google Cloud e armazene-a em um arquivo temporário:
      gcloud projects get-iam-policy PROJECT_ID > /tmp/policy.yaml
    2. Em um editor de texto, abra /tmp/policy.yaml e adicione ou altere apenas a configuração do registro de auditoria na seção auditConfigs:

      auditConfigs:
      - auditLogConfigs:
        - logType: ADMIN_READ
        - logType: DATA_WRITE
        - logType: DATA_READ
        service: storage.googleapis.com
      bindings:
      - members:
      [...]
      etag: BwW_bHKTV5U=
      version: 1
    3. Grave a nova política de IAM:
      gcloud projects set-iam-policy PROJECT_ID /tmp/policy.yaml

      Se o comando anterior relatar um conflito com outra alteração, repita essas etapas, começando com a leitura da política de IAM. Para mais informações, acesse Configurar registros de auditoria de acesso a dados com a API.

  14. Conceda o papel eventarc.eventReceiver à conta de serviço do Compute Engine:

    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. Se você ativou a conta de serviço do Pub/Sub até 8 de abril de 2021, conceda o papel iam.serviceAccountTokenCreator à conta de serviço do Pub/Sub:

    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. Defina os padrões usados neste tutorial:
    export REGION=us-central1
    gcloud config set run/region ${REGION}
    gcloud config set run/platform managed
    gcloud config set eventarc/location ${REGION}
    

Criar um repositório padrão do Artifact Registry

Crie um repositório padrão do Artifact Registry para armazenar a imagem do contêiner:

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

Substitua REPOSITORY por um nome exclusivo para o repositório.

Criar um bucket do Cloud Storage

Crie um bucket do Cloud Storage em cada uma das duas regiões como a origem do evento para o serviço do Cloud Run:

  1. Crie um bucket em us-east1:

    export BUCKET1="troubleshoot-bucket1-PROJECT_ID"
    gsutil mb -l us-east1 gs://${BUCKET1}
    
  2. Crie um bucket em us-west1:

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

Depois que a origem do evento for criada, implante o serviço de receptor de eventos no Cloud Run.

Implantar o receptor de eventos

Implante um serviço do Cloud Run que recebe e registra eventos.

  1. Clone o repositório do GitHub para recuperar o exemplo de código:

    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. Revise o código deste tutorial, que consiste no seguinte:

    • Um manipulador de eventos que recebe o evento de entrada como um CloudEvent na solicitação HTTP POST:

      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)
      
      
    • Um servidor que usa o manipulador de eventos:

      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)))
    • Um Dockerfile que define o ambiente operacional do serviço. O conteúdo do Dockerfile varia por linguagem.

      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. Crie a imagem do contêiner com o Cloud Build e faça upload da imagem para o 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. Implante a imagem do contêiner no Cloud Run:

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

    Quando a implantação for bem-sucedida, a linha de comando exibirá o URL de serviço.

Criar um gatilho

Depois de implantar um serviço do Cloud Run, configure um gatilho para detectar eventos do Cloud Storage por meio de registros de auditoria.

  1. Crie um gatilho do Eventarc para detectar eventos do Cloud Storage que são roteados usando os Registros de auditoria do Cloud:

    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
    

    Isso gera um gatilho chamado troubleshoot-trigger.

  2. Para confirmar se troubleshoot-trigger foi criado, execute:

    gcloud eventarc triggers list
    

    A saída será semelhante a esta:

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

Gerar e visualizar um evento

Confirme se você implantou o serviço e pode receber eventos do Cloud Storage.

  1. Crie e faça upload de um arquivo no bucket de armazenamento BUCKET1:

     echo "Hello World" > random.txt
     gsutil cp random.txt gs://${BUCKET1}/random.txt
    
  2. Monitore os registros para verificar se o serviço recebeu um evento. Para conferir a entrada de registro, siga estas etapas:

    1. Filtre as entradas de registro e retorne a saída no formato JSON:

      gcloud logging read "resource.labels.service_name=troubleshoot-service \
          AND textPayload:random.txt" \
          --format=json
    2. Procure uma entrada de registro semelhante a esta:

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

Inicialmente, nenhuma entrada de registro é retornada. Isso indica que há um problema na configuração que você precisa investigar.

Investigar o problema

Investigue por que o serviço não está recebendo eventos.

Tempo de inicialização

O gatilho é criado imediatamente, mas pode levar até dois minutos para que ele seja propagado e filtre eventos. Execute o seguinte comando para confirmar se um gatilho está ativo:

gcloud eventarc triggers list

A saída indica o status do gatilho. No exemplo a seguir, troubleshoot-trigger estará ativo às 14:16:56:

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

Quando o gatilho estiver ativo, faça upload de um arquivo novamente para o bucket de armazenamento. Os eventos são gravados nos registros de serviço do Cloud Run. Se o serviço não receber eventos, ele poderá estar relacionado ao tamanho dos eventos.

Registros de auditoria

Neste tutorial, os eventos do Cloud Storage são roteados usando os registros de auditoria do Cloud e enviados para o Cloud Run. Confirme se os registros de auditoria estão ativados para o Cloud Storage.

  1. No console do Google Cloud, acesse a página Registros de auditoria.

    Ir para Registros de auditoria

  2. Marque a caixa de seleção Google Cloud Storage.
  3. Verifique se os tipos de registro Leitura de administrador, Leitura de dados e Gravação de dados estão selecionados.

Depois de ativar os Registros de auditoria do Cloud, faça o upload do arquivo novamente para o bucket de armazenamento e verifique os registros. Se o serviço ainda não receber eventos, o motivo pode estar relacionado ao local do gatilho.

Local do gatilho

Pode haver vários recursos em locais diferentes, e você precisa filtrar eventos de origens que estão na mesma região que o destino do Cloud Run. Para mais informações, consulte locais compatíveis com o Eventarc e saiba mais sobre os locais do Eventarc.

Neste tutorial, você implantou o serviço do Cloud Run em us-central1. Como você definiu eventarc/location como us-central1, também criou um gatilho no mesmo local.

No entanto, você criou dois buckets do Cloud Storage nos locais us-east1 e us-west1. Para receber eventos desses locais, é preciso criar gatilhos do Eventarc nesses locais.

Crie um gatilho do Eventarc localizado em us-east1:

  1. Confirme o local do gatilho atual:

    gcloud eventarc triggers describe troubleshoot-trigger
    
  2. Defina o local e a região como us-east1:

    gcloud config set eventarc/location us-east1
    gcloud config set run/region us-east1
    
  3. Implante o receptor de eventos novamente criando e implantando a imagem do contêiner no Cloud Run.

  4. Crie um novo gatilho localizado em 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. Verifique se o gatilho foi criado:

    gcloud eventarc triggers list
    

    Um gatilho pode levar até dois minutos para ser inicializado antes de começar a rotear eventos.

  6. Para confirmar se o gatilho está implantado corretamente, gere e visualize um evento.

Outros problemas que você pode encontrar

Talvez você encontre outros problemas ao usar o Eventarc.

Tamanho do evento

Os eventos enviados não podem exceder os limites de tamanho do evento.

Um gatilho que enviou eventos anteriormente parou de funcionar

  1. Verifique se a origem está gerando eventos. Verifique os registros de auditoria do Cloud e se o serviço monitorado está emitindo registros. Se os registros forem gravados, mas os eventos não forem entregues, entre em contato com o suporte.

  2. Verifique se há um tópico do Pub/Sub com o mesmo nome de gatilho. O Eventarc usa o Pub/Sub como a camada de transporte e vai usar um tópico do Pub/Sub atual ou criar automaticamente um tópico e gerenciá-lo para você.

    1. Para listar os gatilhos, consulte gcloud eventarc triggers list.
    2. Para listar os tópicos do Pub/Sub, execute:

      gcloud pubsub topics list
      
    3. Verifique se o nome do tópico do Pub/Sub inclui o nome do gatilho criado. Por exemplo:

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

    Se o tópico do Pub/Sub estiver ausente, crie o gatilho novamente para um provedor, tipo de evento e destino do Cloud Run específicos.

  3. Verifique se o gatilho foi configurado para o serviço.

    1. No console do Google Cloud, abra a página serviços.

      Acessar Serviços

    2. Clique no nome do serviço para abrir a página Detalhes do serviço.

    3. Clique na guia Gatilhos.

      O gatilho do Eventarc associado ao serviço precisa ser listado.

  4. Verifique a integridade do tópico e da assinatura do Pub/Sub usando os tipos de métricas do Pub/Sub.

    • É possível monitorar mensagens encaminhadas que não podem ser entregues usando a métrica subscription/dead_letter_message_count. Essa métrica mostra o número de mensagens não entregues que o Pub/Sub encaminha de uma assinatura.

      Se as mensagens não forem publicadas no tópico, verifique os Registros de auditoria do Cloud e verifique se o serviço monitorado está emitindo registros. Se os registros forem gravados, mas os eventos não forem entregues, entre em contato com o suporte.

    • É possível monitorar assinaturas de push usando a métrica subscription/push_request_count e agrupando-a por response_code e subcription_id.

      Se forem relatados erros de push, verifique os registros de serviço do Cloud Run. Se o endpoint de recebimento retornar um código de status não OK, isso indica que o código do Cloud Run não está funcionando como esperado e você precisa entrar em contato com o suporte.

    Para mais informações, consulte Criar políticas de alertas de limite de métrica.

Limpar

Se você criou um novo projeto para este tutorial, exclua o projeto. Se você usou um projeto já existente e quer mantê-lo sem as alterações incluídas com este tutorial, exclua os recursos criados para o tutorial.

Exclua o projeto

O jeito mais fácil de evitar cobranças é excluindo o projeto que você criou para o tutorial.

Para excluir o projeto:

  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.

delete-tutorial-resources

  1. Exclua o serviço do Cloud Run que você implantou neste tutorial:

    gcloud run services delete SERVICE_NAME

    SERVICE_NAME é o nome escolhido do serviço.

    Também é possível excluir os serviços do Cloud Run no Console do Google Cloud.

  2. Remova as configurações padrão do gcloud CLI que você adicionou durante a configuração do tutorial.

    Por exemplo:

    gcloud config unset run/region

    ou

    gcloud config unset project

  3. Exclua outros recursos do Google Cloud criados neste tutorial:

    • Exclua o gatilho do Eventarc:
      gcloud eventarc triggers delete TRIGGER_NAME
      
      . Substitua TRIGGER_NAME pelo nome do acionador.

A seguir