Écrire des métriques OTLP à l'aide d'un side-car OpenTelemetry


Ce tutoriel explique comment écrire, déployer et appeler un service Cloud Run qui transmet des métriques OLTP personnalisées à Google Cloud Managed Service pour Prometheus à l'aide du side-car OpenTelemetry.

Si vous disposez d'un service Cloud Run qui signale les métriques Prometheus, utilisez plutôt le side-car Prometheus pour Cloud Run.

Objectifs

  • Écrire, créer et déployer un service sur Cloud Run avec le side-car OpenTelemetry
  • Générer des métriques personnalisées et les transmettre à Google Cloud Managed Service pour Prometheus.

Coûts

Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Avant de commencer

  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. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

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

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

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

  6. Enable the Cloud Run, Cloud Monitoring, Artifact Registry, and Cloud Build APIs.

    Enable the APIs

  7. Installez et initialisez gcloud CLI.
  8. Mettez à jour Google Cloud CLI : gcloud components update

Rôles requis

Pour obtenir les autorisations nécessaires pour suivre le tutoriel, demandez à votre administrateur de vous accorder les rôles IAM suivants sur votre projet :

Pour en savoir plus sur l'attribution de rôles, consultez la page Gérer l'accès aux projets, aux dossiers et aux organisations.

Vous pouvez également obtenir les autorisations requises via des rôles personnalisés ou d'autres rôles prédéfinis.

Notez également que l'identité du service Cloud Run doit disposer du rôle Rédacteur de métriques Monitoring (roles/monitoring.metricWriter). Le compte de service Compute Engine par défaut peut disposer de ce rôle par défaut, mais vous devrez peut-être l'ajouter si vous avez modifié les autorisations de ce compte ou si vous utilisez un autre compte de service.

Configurer les paramètres par défaut de gcloud

Pour configurer gcloud avec les valeurs par défaut pour votre service Cloud Run, procédez comme suit :

  1. Définissez le projet par défaut :

    gcloud config set project PROJECT_ID

    Remplacez PROJECT_ID par le nom du projet que vous avez créé pour ce tutoriel.

  2. Configurez gcloud pour la région choisie :

    gcloud config set run/region REGION

    Remplacez REGION par la région Cloud Run compatible de votre choix.

Emplacements Cloud Run

Cloud Run est régional, ce qui signifie que l'infrastructure qui exécute vos services Cloud Run est située dans une région spécifique et gérée par Google pour être disponible de manière redondante dans toutes les zones de cette région.

Lors de la sélection de la région dans laquelle exécuter vos services Cloud Run, vous devez tout d'abord considérer vos exigences en matière de latence, de disponibilité et de durabilité. Vous pouvez généralement sélectionner la région la plus proche de vos utilisateurs, mais vous devez tenir compte de l'emplacement des autres produits Google Cloud utilisés par votre service Cloud Run. L'utilisation conjointe de produits Google Cloud dans plusieurs emplacements peut avoir une incidence sur la latence et le coût de votre service.

Cloud Run est disponible dans les régions suivantes :

Soumis aux tarifs de niveau 1

Soumis aux tarifs de niveau 2

Si vous avez déjà créé un service Cloud Run, vous pouvez afficher la région dans le tableau de bord Cloud Run de la console Google Cloud.

Créer un dépôt d'images Artifact Registry

Créez un dépôt Docker Artifact Registry pour héberger l'exemple d'image de service :

gcloud artifacts repositories create run-otel \
    --repository-format=docker \
    --location=REGION \
    --project=PROJECT_ID

Remplacez les éléments suivants :

  • PROJECT_ID par le nom du projet que vous avez créé pour ce tutoriel ;
  • REGION par la région Cloud Run compatible de votre choix.

Récupérer l'exemple de code

Pour récupérer l’exemple de code à utiliser, procédez comme suit :

  1. Clonez le dépôt de l'exemple d'application sur votre machine locale :

    Accéder

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

    Vous pouvez également télécharger l'exemple en tant que fichier ZIP et l'extraire.

  2. Accédez au répertoire contenant l'exemple de code Cloud Run :

    Accéder

    cd golang-samples/run/custom-metrics/

Comprendre le code

Le code de ce tutoriel comprend les éléments suivants :

  • Un serveur qui gère les requêtes entrantes et génère une métrique nommée sidecar_sample_counter.
package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"os"

	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
	"go.opentelemetry.io/otel/metric"
	sdkmetric "go.opentelemetry.io/otel/sdk/metric"
	"go.opentelemetry.io/otel/sdk/resource"
	semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
)

var counter metric.Int64Counter

func main() {
	ctx := context.Background()
	shutdown := setupCounter(ctx)
	defer shutdown(ctx)

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
		log.Printf("defaulting to port %s", port)
	}

	http.HandleFunc("/", handler)
	log.Fatal(http.ListenAndServe(":"+port, nil))
}

func handler(w http.ResponseWriter, r *http.Request) {
	counter.Add(context.Background(), 100)
	fmt.Fprintln(w, "Incremented sidecar_sample_counter metric!")
}

func setupCounter(ctx context.Context) func(context.Context) error {
	serviceName := os.Getenv("K_SERVICE")
	if serviceName == "" {
		serviceName = "sample-cloud-run-app"
	}
	r, err := resource.Merge(
		resource.Default(),
		resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceName(serviceName),
		),
	)
	if err != nil {
		log.Fatalf("Error creating resource: %v", err)
	}

	exporter, err := otlpmetricgrpc.New(ctx,
		otlpmetricgrpc.WithInsecure(),
	)
	if err != nil {
		log.Fatalf("Error creating exporter: %s", err)
	}
	provider := sdkmetric.NewMeterProvider(
		sdkmetric.WithReader(sdkmetric.NewPeriodicReader(exporter)),
		sdkmetric.WithResource(r),
	)

	meter := provider.Meter("example.com/metrics")
	counter, err = meter.Int64Counter("sidecar-sample-counter")
	if err != nil {
		log.Fatalf("Error creating counter: %s", err)
	}
	return provider.Shutdown
}
  • Un fichier Dockerfile qui définit l'environnement d'exploitation du service.
FROM golang:1.21 as builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o sample-app

FROM alpine:3
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/sample-app /sample-app
CMD ["/sample-app"]

L'exemple inclut également des fichiers stockés dans le sous-répertoire collector permettant de créer un collecteur OpenTelemetry personnalisé :

  • Fichier de configuration pour le collecteur OpenTelemetry.

    receivers:
      otlp:
        protocols:
          grpc:
          http:
    
    processors:
      batch:
        # batch metrics before sending to reduce API usage
        send_batch_max_size: 200
        send_batch_size: 200
        timeout: 5s
    
      memory_limiter:
        # drop metrics if memory usage gets too high
        check_interval: 1s
        limit_percentage: 65
        spike_limit_percentage: 20
    
      # automatically detect Cloud Run resource metadata                                                                                                                                               
      resourcedetection:
        detectors: [env, gcp]
        timeout: 2s
        override: false
    
      resource:
        attributes:
          # add instance_id as a resource attribute                                                                                                                                                    
        - key: service.instance.id
          from_attribute: faas.id
          action: upsert
          # parse service name from K_SERVICE Cloud Run variable                                                                                                                                       
        - key: service.name
          value: ${env:K_SERVICE}
          action: insert
    
    exporters:
      googlemanagedprometheus: # Note: this is intentionally left blank   
    
    extensions:
      health_check:
    
    service:
      extensions: [health_check]
      pipelines:
        metrics:
          receivers: [otlp]
          processors: [batch, memory_limiter, resourcedetection, resource]
          exporters: [googlemanagedprometheus]
  • Un fichier Dockerfile qui regroupe la configuration fournie dans une image de collecteur en amont.

    FROM otel/opentelemetry-collector-contrib:0.101.0
    
    COPY collector-config.yaml /etc/otelcol-contrib/config.yaml

Transmettre le code

La transmission du code se déroule en trois étapes : création d'une image de conteneur avec Cloud Build, importation de l'image de conteneur dans Artifact Registry, puis déploiement de cette image dans Cloud Run.

Pour transmettre votre code, procédez comme suit :

  1. Créez votre exemple de conteneur de service et publiez-le dans Artifact Registry :

    gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/run-otel/sample-metrics-app

    En cas de réussite, vous devriez voir un message SUCCESS contenant l'ID, l'heure de création et le nom de l'image. Celle-ci est stockée dans Artifact Registry et peut être réutilisée au besoin.

  2. Créez votre conteneur collecteur et publiez-le dans Artifact Registry :

    gcloud builds submit collector --tag REGION-docker.pkg.dev/PROJECT_ID/run-otel/otel-collector-metrics

    En cas de réussite, vous devriez voir un message SUCCESS contenant l'ID, l'heure de création et le nom de l'image. Celle-ci est stockée dans Artifact Registry et peut être réutilisée au besoin.

  3. Déployez votre application :

    YAML

    1. Créez un fichier nommé service.yaml contenant les éléments suivants :

      apiVersion: serving.knative.dev/v1
      kind: Service
      metadata:
        name: SERVICE-NAME
        annotations:
          run.googleapis.com/launch-stage: BETA
      spec:
        template:
          metadata:
            annotations:
              run.googleapis.com/container-dependencies: "{app:[collector]}"
          spec:
            containers:
            - image: REGION-docker.pkg.dev/PROJECT_ID/run-otel/sample-metrics-app
              name: app
              ports:
              - containerPort: CONTAINER_PORT
              env:
              - name: "OTEL_EXPORTER_OTLP_ENDPOINT"
                value: "http://localhost:4317"
            - image: REGION-docker.pkg.dev/PROJECT_ID/run-otel/otel-collector-metrics
              name: collector
              startupProbe:
                httpGet:
                  path: /
                  port: 13133
      
    2. Remplacez les éléments suivants :
  4. Créez le service à l'aide de la commande suivante :

    gcloud run services replace service.yaml

    Cette commande renvoie une URL de service. Utilisez cette URL pour tester l'exemple d'application dans la section Tester le service.

Tester le service

À l'aide de l'URL obtenue de la commande gcloud run dans la section Transmettre le code, connectez-vous au service pour générer des exemples de métriques (vous pouvez exécuter cette commande à plusieurs reprises pour générer des données plus intéressantes) :

curl -H \
"Authorization: Bearer $(gcloud auth print-identity-token)" \
SERVICE_URL

Remplacez SERVICE_URL par l'URL de votre service.

Accédez ensuite à l'explorateur de métriques dans la section Cloud Monitoring de la console Google Cloud, puis sélectionnez la métrique sidecar_sample_counter.

Métrique personnalisée affichée dans l'interface utilisateur de l'explorateur de métriques

Vous pouvez également interroger les métriques à l'aide de PromQL. Par exemple, la requête ci-dessous filtrera les métriques selon l'ID d'instance Cloud Run :

sidecar_sample_counter{instance="INSTANCE_ID"}

Remplacez INSTANCE_ID par l'ID de n'importe quelle instance de votre service (disponible dans les journaux d'instance ou à partir du serveur de métadonnées).

Cette requête génère un graphique semblable à celui-ci :

Métrique personnalisée interrogée à l'aide de PromQL

Effectuer un nettoyage

Si vous avez créé un projet pour ce tutoriel, supprimez-le. Si vous avez utilisé un projet existant et que vous souhaitez le conserver sans les modifications du présent tutoriel, supprimez les ressources créées pour ce tutoriel.

Supprimer le projet

Le moyen le plus simple d'empêcher la facturation est de supprimer le projet que vous avez créé pour ce tutoriel.

Pour supprimer le projet :

  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.

Supprimer les ressources du tutoriel

  1. Supprimez le service Cloud Run que vous avez déployé dans ce tutoriel :

    gcloud run services delete SERVICE-NAME

    SERVICE-NAME est le nom de service que vous avez choisi.

    Vous pouvez également supprimer des services Cloud Run à partir de Google Cloud Console.

  2. Supprimez la configuration régionale gcloud par défaut que vous avez ajoutée lors de la configuration du tutoriel :

     gcloud config unset run/region
    
  3. Supprimez la configuration du projet :

     gcloud config unset project
    
  4. Supprimez les autres ressources Google Cloud créées dans ce tutoriel :

Étapes suivantes

D'autres exemples, y compris des exemples pour les traces et les journaux, sont disponibles sur GitHub.