Tutorial: depure eventos de encaminhamento para o Cloud Run


Este tutorial ensina como resolver problemas de erros de tempo de execução encontrados quando usa o Eventarc para encaminhar eventos do Cloud Storage para um serviço do Cloud Run não autenticado através dos registos de auditoria do Google Cloud.

Objetivos

Este tutorial mostra como concluir as seguintes tarefas:

  1. Crie um repositório padrão do Artifact Registry para armazenar a sua imagem de contentor.
  2. Crie um contentor do Cloud Storage para ser a origem de eventos.
  3. Crie, carregue e implemente uma imagem de contentor no Cloud Run.
  4. Criar acionadores do Eventarc.
  5. Carregue um ficheiro para o contentor do Cloud Storage.
  6. Resolva problemas e corrija os erros de tempo de execução.

Custos

Neste documento, usa os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custos com base na sua utilização projetada, use a calculadora de preços.

Os novos Google Cloud utilizadores podem ser elegíveis para uma avaliação gratuita.

Antes de começar

As restrições de segurança definidas pela sua organização podem impedir a conclusão dos seguintes passos. Para informações de resolução de problemas, consulte o artigo Desenvolva aplicações num ambiente Google Cloud restrito.

  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. Se estiver a usar um fornecedor de identidade (IdP) externo, tem primeiro de iniciar sessão na CLI gcloud com a sua identidade federada.

  4. Para inicializar a CLI gcloud, execute o seguinte comando:

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

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • 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.

  6. Verify that billing is enabled for your Google Cloud project.

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

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com eventarc.googleapis.com logging.googleapis.com pubsub.googleapis.com run.googleapis.com storage.googleapis.com
  8. Install the Google Cloud CLI.

  9. Se estiver a usar um fornecedor de identidade (IdP) externo, tem primeiro de iniciar sessão na CLI gcloud com a sua identidade federada.

  10. Para inicializar a CLI gcloud, execute o seguinte comando:

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

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • 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.

  12. Verify that billing is enabled for your Google Cloud project.

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

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com eventarc.googleapis.com logging.googleapis.com pubsub.googleapis.com run.googleapis.com storage.googleapis.com
  14. Se for o criador do projeto, é-lhe atribuída a função básica de proprietário (roles/owner). Por predefinição, esta função do Identity and Access Management (IAM) inclui as autorizações necessárias para acesso total à maioria dos Google Cloud recursos e pode ignorar este passo.

    Se não for o criador do projeto, as autorizações necessárias têm de ser concedidas no projeto ao principal adequado. Por exemplo, um principal pode ser uma Conta Google (para utilizadores finais) ou uma conta de serviço (para aplicações e cargas de trabalho de computação). Para mais informações, consulte a página Funções e autorizações do destino de eventos.

    Tenha em atenção que, por predefinição, as autorizações do Cloud Build incluem autorizações para carregar e transferir artefactos do Artifact Registry.

    Autorizações necessárias

    Para receber as autorizações de que precisa para concluir este tutorial, peça ao seu administrador que lhe conceda as seguintes funções da IAM no seu projeto:

    Para mais informações sobre a atribuição de funções, consulte o artigo Faça a gestão do acesso a projetos, pastas e organizações.

    Também pode conseguir as autorizações necessárias através de funções personalizadas ou outras funções predefinidas.

  15. Para o Cloud Storage, ative o registo de auditoria para os tipos de acesso aos dados ADMIN_READ, DATA_WRITE e DATA_READ.

    1. Leia a Política de gestão de identidade e de acesso (IAM) associada ao seu Google Cloud projeto, pasta ou organização e armazene-a num ficheiro temporário:
      gcloud projects get-iam-policy PROJECT_ID > /tmp/policy.yaml
    2. Num editor de texto, abra /tmp/policy.yaml e adicione ou altere apenas a configuração do registo de auditoria na secçã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. Escreva a sua nova Política IAM:
      gcloud projects set-iam-policy PROJECT_ID /tmp/policy.yaml

      Se o comando anterior comunicar um conflito com outra alteração, repita estes passos, começando pela leitura da política de IAM. Para mais informações, consulte o artigo Configure registos de auditoria de acesso aos dados com a API.

  16. Conceda a função 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'

  17. Se ativou a conta de serviço do Pub/Sub a 8 de abril de 2021 ou antes, conceda a função 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'

  18. Defina as predefinições usadas neste tutorial:
    export REGION=us-central1
    gcloud config set run/region ${REGION}
    gcloud config set run/platform managed
    gcloud config set eventarc/location ${REGION}
  19. Crie um repositório padrão do Artifact Registry

    Crie um repositório padrão do Artifact Registry para armazenar a imagem de contentor:

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

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

    Crie um contentor do Cloud Storage

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

    1. Crie um contentor em us-east1:

      export BUCKET1="troubleshoot-bucket1-PROJECT_ID"
      gcloud storage buckets create gs://${BUCKET1} --location=us-east1
    2. Crie um contentor em us-west1:

      export BUCKET2="troubleshoot-bucket2-PROJECT_ID"
      gcloud storage buckets create gs://${BUCKET2} --location=us-west1

    Depois de criar a origem do evento, implemente o serviço de receção de eventos no Cloud Run.

    Implemente o recetor de eventos

    Implemente um serviço do Cloud Run que receba e registe eventos.

    1. Obtenha o exemplo de código clonando o repositório do 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. Reveja o código deste tutorial, que consiste no seguinte:

      • Um controlador de eventos que recebe o evento recebido como um CloudEvent no pedido 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 controlador 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 consoante o idioma:

        Go

        
        # Use the official Go image to create a binary.
        # This is based on Debian and sets the GOPATH to /go.
        # https://hub.docker.com/_/golang
        FROM golang:1.24-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.16_8-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/sdk:8.0-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/aspnet:8.0-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 de contentor com o Cloud Build e carregue a 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. Implemente a imagem do contentor no Cloud Run:

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

      Quando a implementação é bem-sucedida, a linha de comandos apresenta o URL do serviço.

    Crie um acionador

    Depois de implementar um serviço do Cloud Run, configure um acionador para ouvir eventos do Cloud Storage através de registos de auditoria.

    1. Crie um acionador do Eventarc para ouvir eventos do Cloud Storage encaminhados através dos registos de auditoria do Google 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
      

      Esta ação cria um acionador denominado troubleshoot-trigger.

    2. Para confirmar que troubleshoot-trigger foi criado, execute o seguinte comando:

      gcloud eventarc triggers list
      

      O resultado deve ser semelhante ao seguinte:

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

    Gere e veja um evento

    Confirme que implementou o serviço com êxito e que pode receber eventos do Cloud Storage.

    1. Crie e carregue um ficheiro para o contentor de armazenamento BUCKET1:

       echo "Hello World" > random.txt
       gcloud storage cp random.txt gs://${BUCKET1}/random.txt
      
    2. Monitorize os registos para verificar se o serviço recebeu um evento. Para ver a entrada do registo, conclua os seguintes passos:

      1. Filtre as entradas do registo e devolva o resultado no formato JSON:

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

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

    Tenha em atenção que, inicialmente, não é devolvida nenhuma entrada de registo. Isto indica que existe um problema na configuração que tem de investigar.

    Investigue o problema

    Siga o processo de investigação para saber por que motivo o serviço não está a receber eventos.

    Tempo de inicialização

    Embora o acionador seja criado imediatamente, pode demorar até dois minutos para que um acionador propague e filtre eventos. Execute o seguinte comando para confirmar que um acionador está ativo:

    gcloud eventarc triggers list
    

    O resultado indica o estado do acionador. No exemplo seguinte, troubleshoot-trigger vai 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
    

    Assim que o acionador estiver ativo, carregue novamente um ficheiro para o contentor de armazenamento. Os eventos são escritos nos registos do serviço do Cloud Run. Se o serviço não receber eventos, pode estar relacionado com o tamanho dos eventos.

    Registos de auditoria

    Neste tutorial, os eventos do Cloud Storage são encaminhados através dos registos de auditoria do Cloud e enviados para o Cloud Run. Confirme que os registos de auditoria estão ativados para o Cloud Storage.

    1. Na Google Cloud consola, aceda à página Registos de auditoria.

      Aceder aos registos de auditoria

    2. Selecione a caixa de verificação Google Cloud Storage.
    3. Certifique-se de que os tipos de registos Admin Read, Data Read e Data Write estão selecionados.

    Depois de ativar os registos de auditoria do Cloud, carregue novamente o ficheiro para o contentor de armazenamento e verifique os registos. Se o serviço continuar a não receber eventos, isto pode estar relacionado com a localização do acionador.

    Localização do acionador

    Podem existir vários recursos em localizações diferentes e tem de filtrar os eventos de origens que se encontram na mesma região que o destino do Cloud Run. Para mais informações, consulte as localizações suportadas pelo Eventarc e compreenda as localizações do Eventarc.

    Neste tutorial, implementou o serviço do Cloud Run em us-central1. Como definiu eventarc/location como us-central1, também criou um acionador na mesma localização.

    No entanto, criou dois contentores do Cloud Storage nas localizações us-east1 e us-west1. Para receber eventos dessas localizações, tem de criar acionadores do Eventarc nessas localizações.

    Crie um acionador do Eventarc localizado em us-east1:

    1. Confirme a localização do acionador existente:

      gcloud eventarc triggers describe troubleshoot-trigger
      
    2. Defina a localização e a região para us-east1:

      gcloud config set eventarc/location us-east1
      gcloud config set run/region us-east1
      
    3. Implemente novamente o recetor de eventos criando e implementando a imagem do contentor no Cloud Run.

    4. Crie um novo acionador 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 acionador foi criado:

      gcloud eventarc triggers list
      

      Um acionador pode demorar até dois minutos a inicializar antes de começar a encaminhar eventos.

    6. Para confirmar que o acionador está agora implementado corretamente, gere e veja um evento.

    Outros problemas que pode encontrar

    Pode encontrar outros problemas ao usar o Eventarc.

    Tamanho do evento

    Os eventos que envia não podem exceder os limites de tamanho dos eventos.

    Um acionador que enviou eventos anteriormente deixou de funcionar

    1. Verifique se a origem está a gerar eventos. Verifique os registos de auditoria da nuvem e certifique-se de que o serviço monitorizado está a emitir registos. Se os registos forem gravados, mas os eventos não forem enviados, contacte o apoio técnico.

    2. Verifique se existe um tópico do Pub/Sub com o mesmo nome do acionador. O Eventarc usa o Pub/Sub como camada de transporte e usa um tópico Pub/Sub existente ou cria automaticamente um tópico e gere-o por si.

      1. Para ver uma lista de acionadores, consulte gcloud eventarc triggers list.
      2. Para listar os tópicos do Pub/Sub, execute o seguinte comando:

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

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

      Se o tópico do Pub/Sub estiver em falta, crie novamente o acionador para um fornecedor, um tipo de evento e um destino do Cloud Run específicos.

    3. Confirme que o acionador foi configurado para o serviço.

      1. Na Google Cloud consola, aceda à página Serviços.

        Aceder a Serviços

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

      3. Clique no separador Acionadores.

        O acionador do Eventarc associado ao serviço deve ser indicado.

    4. Valide o estado do tópico e da subscrição do Pub/Sub através dos tipos de métricas do Pub/Sub.

      • Pode monitorizar mensagens não entregues encaminhadas através da métrica subscription/dead_letter_message_count. Esta métrica mostra o número de mensagens não entregues que o Pub/Sub encaminha a partir de uma subscrição.

        Se as mensagens não forem publicadas no tópico, verifique os registos de auditoria da nuvem e certifique-se de que o serviço monitorizado está a emitir registos. Se os registos forem gravados, mas os eventos não forem enviados, contacte o apoio técnico.

      • Pode monitorizar as subscrições push através da métrica subscription/push_request_count e agrupando a métrica por response_code e subcription_id.

        Se forem comunicados erros de envio, verifique os registos do serviço do Cloud Run. Se o ponto final de receção devolver um código de estado não OK, indica que o código do Cloud Run não está a funcionar como esperado e tem de contactar o apoio técnico.

      Para mais informações, consulte o artigo Crie políticas de alertas de limite métrico.

    Limpar

    Se criou um novo projeto para este tutorial, elimine o projeto. Se usou um projeto existente e quer mantê-lo sem as alterações adicionadas neste tutorial, elimine os recursos criados para o tutorial.

    Elimine o projeto

    A forma mais fácil de eliminar a faturação é eliminar o projeto que criou para o tutorial.

    Para eliminar 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.

    Elimine recursos de tutoriais

    1. Elimine o serviço do Cloud Run que implementou neste tutorial:

      gcloud run services delete SERVICE_NAME

      Onde SERVICE_NAME é o nome do serviço escolhido.

      Também pode eliminar serviços do Cloud Run a partir da Google Cloud consola.

    2. Remova todas as configurações predefinidas da CLI gcloud que adicionou durante a configuração do tutorial.

      Por exemplo:

      gcloud config unset run/region

      ou

      gcloud config unset project

    3. Elimine outros Google Cloud recursos criados neste tutorial:

      • Elimine o acionador do Eventarc:
        gcloud eventarc triggers delete TRIGGER_NAME
        
        Substitua TRIGGER_NAME pelo nome do seu acionador.

    O que se segue?