Premiers pas avec le collecteur OpenTelemetry

Ce document explique comment configurer le collecteur OpenTelemetry pour extraire des métriques Prometheus standards et les transmettre à Google Cloud Managed Service pour Prometheus. Le collecteur OpenTelemetry est un agent que vous pouvez déployer vous-même et configurer pour effectuer des exportations vers Managed Service pour Prometheus. La configuration est semblable à l'exécution de Managed Service pour Prometheus avec une collecte auto-déployée.

Vous pouvez privilégier le collecteur OpenTelemetry à la collecte auto-déployée pour les raisons suivantes :

  • Le collecteur OpenTelemetry vous permet d'acheminer vos données de télémétrie vers plusieurs backends en configurant différents exportateurs dans votre pipeline.
  • Le collecteur accepte également les signaux provenant des métriques, des journaux et des traces. Vous pouvez donc grâce à lui gérer ces trois types de signaux via un seul et même agent.
  • Le format de données d'OpenTelemetry, indépendant du fournisseur (le protocole OpenTelemetry ou OTLP) est compatible avec un robuste écosystème de bibliothèques et de composants de collecteurs connectables. Cela autorise toute une plage d'options de personnalisation pour la réception, le traitement et l'exportation de vos données.

En contrepartie, l'exécution d'un collecteur OpenTelemetry nécessite une approche de déploiement et de maintenance autogérée. L'approche retenue dépendra de vos besoins spécifiques. Toutefois, nous proposons dans ce document les consignes recommandées pour configurer le collecteur OpenTelemetry en utilisant Managed Service pour Prometheus en tant que backend.

Avant de commencer

Cette section décrit la configuration nécessaire pour les tâches décrites dans ce document.

Configurer des projets et des outils

Pour utiliser Google Cloud Managed Service pour Prometheus, vous avez besoin des ressources suivantes :

  • Un projet Google Cloud avec l'API Cloud Monitoring activée.

    • Si vous n'avez pas de projet Google Cloud, procédez comme suit :

      1. Dans la console Google Cloud, accédez à Nouveau projet :

        Créer un projet

      2. Dans le champ Nom du projet, saisissez un nom pour votre projet, puis cliquez sur Créer.

      3. Accéder à la page Facturation :

        Accéder à Facturation

      4. Sélectionnez le projet que vous venez de créer s'il n'est pas déjà sélectionné en haut de la page.

      5. Vous êtes invité à choisir un profil de paiement existant ou à en créer un.

      L'API Monitoring est activée par défaut pour les nouveaux projets.

    • Si vous disposez déjà d'un projet Google Cloud, assurez-vous que l'API Monitoring est activée :

      1. Accédez à la page API et services :

        Accéder à API et services

      2. Sélectionnez votre projet.

      3. Cliquez sur Enable APIs and Services (Activer les API et les services).

      4. Recherchez "Monitoring".

      5. Dans les résultats de recherche, cliquez sur "API Cloud Monitoring".

      6. Si l'option "API activée" ne s'affiche pas, cliquez sur le bouton Activer.

  • Un cluster Kubernetes. Si vous ne disposez pas de cluster Kubernetes, suivez les instructions du guide de démarrage rapide pour GKE.

Vous avez également besoin des outils de ligne de commande suivants :

  • gcloud
  • kubectl

Les outils gcloud et kubectl font partie de Google Cloud CLI. Pour en savoir plus sur leur installation, consultez la page Gérer les composants de Google Cloud CLI. Pour afficher les composants de la CLI gcloud que vous avez installés, exécutez la commande suivante :

gcloud components list

Configurer votre environnement

Pour éviter de saisir à plusieurs reprises l'ID de votre projet ou le nom de votre cluster, effectuez la configuration suivante :

  • Configurez les outils de ligne de commande comme suit :

    • Configurez limited-feature mode pour faire référence à l'ID de votre projet Google Cloud :

      gcloud config set project PROJECT_ID
      
    • Configurez la CLI kubectl pour utiliser votre cluster :

      kubectl config set-cluster CLUSTER_NAME
      

    Pour en savoir plus sur ces outils, consultez les articles suivants :

Configurer un espace de noms

Créez l'espace de noms Kubernetes NAMESPACE_NAME pour les ressources que vous créez dans le cadre de l'exemple d'application :

kubectl create ns NAMESPACE_NAME

Vérifier les identifiants du compte de service

Vous pouvez ignorer cette section si Workload Identity est activé pour votre cluster Kubernetes.

Lors de l'exécution sur GKE, Managed Service pour Prometheus récupère automatiquement les identifiants de l'environnement en fonction du compte de service Compute Engine par défaut. Le compte de service par défaut dispose des autorisations nécessaires, monitoring.metricWriter et monitoring.viewer, par défaut. Si vous n'utilisez pas Workload Identity et que vous avez précédemment supprimé l'un de ces rôles du compte de service de nœud par défaut, vous devrez rajouter ces autorisations manquantes avant de continuer.

Si vous n'exécutez pas sur GKE, consultez la section Fournir les identifiants explicitement.

Configurer un compte de service pour Workload Identity

Vous pouvez ignorer cette section si Workload Identity n'est pas activé pour votre cluster Kubernetes.

Managed Service pour Prometheus capture les données de métriques à l'aide de l'API Cloud Monitoring. Si votre cluster utilise Workload Identity, vous devez autoriser votre compte de service Kubernetes à accéder à l'API Monitoring. Cette section décrit les opérations suivantes :

Créer et associer le compte de service

Cette étape apparaît à plusieurs endroits de la documentation de Managed Service pour Prometheus. Si vous avez déjà effectué cette étape dans le cadre d'une tâche précédente, vous n'avez pas besoin de la répéter. Passez directement à la section Autoriser le compte de service.

La séquence de commandes suivante crée le compte de service gmp-test-sa et l'associe au compte de service Kubernetes par défaut dans l'espace de noms NAMESPACE_NAME :

gcloud config set project PROJECT_ID \
&&
gcloud iam service-accounts create gmp-test-sa \
&&
gcloud iam service-accounts add-iam-policy-binding \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE_NAME/default]" \
  gmp-test-sa@PROJECT_ID.iam.gserviceaccount.com \
&&
kubectl annotate serviceaccount \
  --namespace NAMESPACE_NAME \
  default \
  iam.gke.io/gcp-service-account=gmp-test-sa@PROJECT_ID.iam.gserviceaccount.com

Si vous utilisez un autre espace de noms ou compte de service GKE, ajustez les commandes en conséquence.

Autoriser le compte de service

Les groupes d'autorisations associées sont collectés dans des rôles que vous attribuez à un compte principal, dans cet exemple, le compte de service Google Cloud. Pour en savoir plus sur ces rôles, consultez la page Contrôle des accès.

La commande suivante accorde au compte de service Google Cloud gmp-test-sa les rôles de l'API Monitoring dont il a besoin pour écrire les données de métriques.

Si vous avez déjà attribué un rôle spécifique au compte de service Google Cloud dans le cadre de la tâche précédente, vous n'avez pas besoin de le faire à nouveau.

gcloud projects add-iam-policy-binding PROJECT_ID\
  --member=serviceAccount:gmp-test-sa@PROJECT_ID.iam.gserviceaccount.com \
  --role=roles/monitoring.metricWriter

Déboguer votre configuration Workload Identity

Si vous rencontrez des difficultés pour utiliser Workload Identity, consultez la documentation sur la vérification de la configuration de Workload Identity et le guide de dépannage de Workload Identity.

Les fautes de frappe et les copier-coller partiels sont les sources d'erreurs les plus courantes lors de la configuration de Workload Identity. Nous vous recommandons vivement d'utiliser les variables modifiables et les icônes de copier-coller cliquables intégrées dans les exemples de code figurant dans ces instructions.

Workload Identity dans les environnements de production

L'exemple décrit dans ce document associe le compte de service Google Cloud au compte de service Kubernetes par défaut et accorde au compte de service Google Cloud toutes les autorisations nécessaires pour utiliser l'API Monitoring.

Dans un environnement de production, vous pouvez utiliser une approche plus précise, avec un compte de service pour chaque composant, chacun disposant d'autorisations minimales. Pour en savoir plus sur la configuration des comptes de service pour la gestion des identités de charge de travail, consultez la page Utiliser Workload Identity.

Configurer le collecteur OpenTelemetry

Cette section vous guide dans la configuration et l'utilisation du collecteur OpenTelemetry pour extraire les métriques à partir d'un exemple d'application, et envoyer les données à Google Cloud Managed Service pour Prometheus. Pour obtenir des informations détaillées sur la configuration, consultez les sections suivantes :

Le collecteur OpenTelemetry est semblable au binaire de l'agent Managed Service pour Prometheus. La communauté OpenTelemetry publie régulièrement des versions, comprenant code source, binaires, et images de conteneurs.

Vous pouvez déployer ces artefacts sur des VM ou des clusters Kubernetes en suivant les bonnes pratiques par défaut, ou utiliser le compilateur de collecteur pour créer votre propre collecteur, qui ne va réunir que les composants dont vous avez besoin. Pour créer un collecteur à utiliser avec Managed Service pour Prometheus, vous devez spécifier les composants suivants :

  • L'exportateur de Managed Service pour Prometheus, qui écrit vos métriques dans Managed Service pour Prometheus.
  • Un récepteur pour extraire vos métriques. Ce document part du principe que vous utilisez le récepteur Prometheus OpenTelemetry, mais l'exportateur de Managed Service pour Prometheus est compatible avec n'importe quel récepteur de métriques OpenTelementry.
  • Des processeurs pour assurer le traitement par lot et le balisage de vos métriques, afin d'inclure des identifiants de ressources importants en fonction de votre environnement.

Ces composants sont activés à l'aide d'un fichier de configuration transmis au collecteur à l'aide de l'option --config.

Les sections suivantes expliquent plus en détail comment configurer chacun de ces composants. Ce document explique comment exécuter le collecteur sur GKE, mais aussi dans n'importe quel autre environnement.

Configurer et déployer le collecteur

Que vous exécutiez votre collection sur Google Cloud ou dans un autre environnement, vous pouvez toujours configurer le collecteur OpenTelemetry pour réaliser des exportations vers Managed Service pour Prometheus. La principale différence réside dans la configuration du collecteur. Dans les environnements autres que Google Cloud, une procédure supplémentaire de mise en forme des données des métriques peut être nécessaire pour assurer leur compatibilité avec Managed Service pour Prometheus. Tandis que sur Google Cloud, une grande partie de cette mise en forme peut être détectée automatiquement par le collecteur.

Exécuter le collecteur OpenTelemetry sur GKE

Vous pouvez copier la configuration suivante dans un fichier nommé config.yaml pour configurer le collecteur OpenTelemetry sur GKE :

receivers:
  prometheus:
    config:
      scrape_configs:
      - job_name: 'SCRAPE_JOB_NAME'
        kubernetes_sd_configs:
        - role: pod
        relabel_configs:
        - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_name]
          action: keep
          regex: prom-example
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
          action: replace
          target_label: __metrics_path__
          regex: (.+)
        - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
          action: replace
          regex: (.+):(?:\d+);(\d+)
          replacement: $$1:$$2
          target_label: __address__
        - action: labelmap
          regex: __meta_kubernetes_pod_label_(.+)

processors:
  resourcedetection:
    detectors: [gcp]
    timeout: 10s

  transform:
    # "location", "cluster", "namespace", "job", "instance", and "project_id" are reserved, and
    # metrics containing these labels will be rejected.  Prefix them with exported_ to prevent this.
    metric_statements:
    - context: datapoint
      statements:
      - set(attributes["exported_location"], attributes["location"])
      - delete_key(attributes, "location")
      - set(attributes["exported_cluster"], attributes["cluster"])
      - delete_key(attributes, "cluster")
      - set(attributes["exported_namespace"], attributes["namespace"])
      - delete_key(attributes, "namespace")
      - set(attributes["exported_job"], attributes["job"])
      - delete_key(attributes, "job")
      - set(attributes["exported_instance"], attributes["instance"])
      - delete_key(attributes, "instance")
      - set(attributes["exported_project_id"], attributes["project_id"])
      - delete_key(attributes, "project_id")

  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

# Note that the googlemanagedprometheus exporter block is intentionally blank
exporters:
  googlemanagedprometheus:

service:
  pipelines:
    metrics:
      receivers: [prometheus]
      processors: [batch, memory_limiter, resourcedetection, transform]
      exporters: [googlemanagedprometheus]

La configuration précédente utilise le récepteur Prometheus et l'exportateur de Managed Service pour Prometheus pour extraire les points de terminaison des métriques sur les pods Kubernetes et exporter ces métriques vers Managed Service pour Prometheus. Les processeurs du pipeline mettent en forme et regroupent les données.

Pour en savoir plus sur le rôle de chacune des parties de cette configuration, ainsi que sur les configurations des différentes plates-formes, consultez les sections détaillées ci-après sur le scraping des métriques et l'ajout de processeurs.

Lorsque vous utilisez une configuration Prometheus existante avec le récepteur prometheus du collecteur OpenTelemetry, remplacez les caractères $ par $$ to avoid triggering environment variable substitution. For more information, see Scrape Prometheus metrics.

You can modify this config based on your environment, provider, and the metrics you want to scrape, but the example config is a recommended starting point for running on GKE.

Run the OpenTelemetry Collector outside Google Cloud

Running the OpenTelemetry Collector outside Google Cloud, such as on-premises or on other cloud providers, is similar to running the Collector on GKE. However, the metrics you scrape are less likely to automatically include data that best formats it for Managed Service for Prometheus. Therefore, you must take extra care to configure the collector to format the metrics so they are compatible with Managed Service for Prometheus.

You can the following config into a file called config.yaml to set up the OpenTelemetry Collector for deployment on a non-GKE Kubernetes cluster:

receivers:
  prometheus:
    config:
      scrape_configs:
      - job_name: 'SCRAPE_JOB_NAME'
        kubernetes_sd_configs:
        - role: pod
        relabel_configs:
        - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_name]
          action: keep
          regex: prom-example
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
          action: replace
          target_label: __metrics_path__
          regex: (.+)
        - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
          action: replace
          regex: (.+):(?:\d+);(\d+)
          replacement: $$1:$$2
          target_label: __address__
        - action: labelmap
          regex: __meta_kubernetes_pod_label_(.+)

processors:
  resource:
    attributes:
    - key: "cluster"
      value: "CLUSTER_NAME"
      action: upsert
    - key: "namespace"
      value: "NAMESPACE_NAME"
      action: upsert
    - key: "location"
      value: "REGION"
      action: upsert

  transform:
    # "location", "cluster", "namespace", "job", "instance", and "project_id" are reserved, and
    # metrics containing these labels will be rejected.  Prefix them with exported_ to prevent this.
    metric_statements:
    - context: datapoint
      statements:
      - set(attributes["exported_location"], attributes["location"])
      - delete_key(attributes, "location")
      - set(attributes["exported_cluster"], attributes["cluster"])
      - delete_key(attributes, "cluster")
      - set(attributes["exported_namespace"], attributes["namespace"])
      - delete_key(attributes, "namespace")
      - set(attributes["exported_job"], attributes["job"])
      - delete_key(attributes, "job")
      - set(attributes["exported_instance"], attributes["instance"])
      - delete_key(attributes, "instance")
      - set(attributes["exported_project_id"], attributes["project_id"])
      - delete_key(attributes, "project_id")

  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

exporters:
  googlemanagedprometheus:
    project: "PROJECT_ID"

service:
  pipelines:
    metrics:
      receivers: [prometheus]
      processors: [batch, memory_limiter, resource, transform]
      exporters: [googlemanagedprometheus]

This config does the following:

When using an existing Prometheus configuration with the OpenTelemetry Collector's prometheus receiver, replace any $ characters with $$ pour éviter de déclencher une substitution de variables d'environnement. Pour en savoir plus, consultez la section Extraire les métriques Prometheus.

Pour en savoir plus sur les bonnes pratiques concernant la configuration du collecteur sur d'autres clouds, consultez la section Amazon EKS ou Azure AKS.

Déployer l'exemple d'application

L'exemple d'application émet la métrique de compteur example_requests_total et la métrique d'histogramme example_random_numbers (entre autres) sur son port metrics. Le fichier manifeste de cet exemple définit trois instances répliquées.

Pour déployer l'exemple d'application, exécutez la commande suivante :

kubectl -n NAMESPACE_NAME apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/prometheus-engine/v0.12.0/examples/example-app.yaml

Créer votre configuration de collecteur en tant que ConfigMap

Une fois que vous avez créé votre configuration et que vous l'avez placée dans un fichier nommé config.yaml, utilisez ce fichier pour créer un ConfigMap Kubernetes basé sur votre fichier config.yaml. Une fois le collecteur déployé, il va installer le ConfigMap et charger le fichier.

Pour créer un ConfigMap nommé otel-config avec votre configuration, exécutez la commande suivante :

kubectl -n NAMESPACE_NAME create configmap otel-config --from-file config.yaml

Déployer le collecteur

Créez un fichier nommé collector-deployment.yaml avec le contenu suivant :

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: NAMESPACE_NAME:prometheus-test
rules:
- apiGroups: [""]
  resources:
  - pods
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: NAMESPACE_NAME:prometheus-test
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: NAMESPACE_NAME:prometheus-test
subjects:
- kind: ServiceAccount
  namespace: NAMESPACE_NAME
  name: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: otel-collector
spec:
  replicas: 1
  selector:
    matchLabels:
      app: otel-collector
  template:
    metadata:
      labels:
        app: otel-collector
    spec:
      containers:
      - name: otel-collector
        image: otel/opentelemetry-collector-contrib:0.101.0
        args:
        - --config
        - /etc/otel/config.yaml
        volumeMounts:
        - mountPath: /etc/otel/
          name: otel-config
      volumes:
      - name: otel-config
        configMap:
          name: otel-config

Créez le déploiement du collecteur dans votre cluster Kubernetes en exécutant la commande suivante :

kubectl -n NAMESPACE_NAME create -f collector-deployment.yaml

Une fois le pod démarré, il va extraire l'exemple d'application et transmettre les métriques à Managed Service pour Prometheus.

Pour en savoir plus sur l'interrogation des données, consultez les pages Interroger à l'aide de Cloud Monitoring ou Interroger à l'aide de Grafana.

Fournir des identifiants de manière explicite

Lors de l'exécution sur GKE, le collecteur OpenTelemetry récupère automatiquement les identifiants de l'environnement en fonction du compte de service du nœud. Dans les clusters Kubernetes non GKE, les identifiants doivent être explicitement fournis au collecteur OpenTelemetry à l'aide d'options ou de la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS.

  1. Définissez le contexte de votre projet cible :

    gcloud config set project PROJECT_ID
    
  2. Créez un compte de service :

    gcloud iam service-accounts create gmp-test-sa
    

    Cette étape crée le compte de service que vous avez peut-être déjà créé dans les instructions de Workload Identity.

  3. Accordez les autorisations requises au compte de service :

    gcloud projects add-iam-policy-binding PROJECT_ID\
      --member=serviceAccount:gmp-test-sa@PROJECT_ID.iam.gserviceaccount.com \
      --role=roles/monitoring.metricWriter
    

  4. Créez et téléchargez une clé pour le compte de service :

    gcloud iam service-accounts keys create gmp-test-sa-key.json \
      --iam-account=gmp-test-sa@PROJECT_ID.iam.gserviceaccount.com
    
  5. Ajoutez le fichier de clé en tant que secret à votre cluster non-GKE :

    kubectl -n NAMESPACE_NAME create secret generic gmp-test-sa \
      --from-file=key.json=gmp-test-sa-key.json
    

  6. Ouvrez la ressource de déploiement d'OpenTelemetry pour la modifier :

    kubectl -n NAMESPACE_NAME edit deployment otel-collector
    
  1. Ajoutez le texte affiché en gras à la ressource :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: NAMESPACE_NAME
      name: otel-collector
    spec:
      template
        spec:
          containers:
          - name: otel-collector
            env:
            - name: "GOOGLE_APPLICATION_CREDENTIALS"
              value: "/gmp/key.json"
    ...
            volumeMounts:
            - name: gmp-sa
              mountPath: /gmp
              readOnly: true
    ...
          volumes:
          - name: gmp-sa
            secret:
              secretName: gmp-test-sa
    ...
    

  2. Enregistrez le fichier et fermez l'éditeur. Une fois la modification appliquée, les pods sont recréés et commencent à s'authentifier auprès du backend de métrique avec le compte de service donné.

Extraire les métriques Prometheus

Cette section et la suivante fournissent des informations de personnalisation supplémentaires sur l'utilisation du collecteur OpenTelemetry. Ces informations peuvent être utiles dans certaines situations, mais aucune n'est nécessaire pour exécuter l'exemple décrit dans la section Configurer le collecteur OpenTelemetry.

Si vos applications exposent déjà des points de terminaison Prometheus, le collecteur OpenTelemetry peut extraire ces points de terminaison à l'aide du même format de configuration de scraping que celui que vous utiliseriez avec n'importe quelle configuration Prometheus standard. Pour ce faire, activez le récepteur Prometheus dans votre configuration de collecteur.

Une configuration basique de récepteur Prometheus pour les pods Kubernetes peut se présenter comme suit :

receivers:
  prometheus:
    config:
      scrape_configs:
      - job_name: 'kubernetes-pods'
        kubernetes_sd_configs:
        - role: pod
        relabel_configs:
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
          action: keep
          regex: true
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
          action: replace
          target_label: __metrics_path__
          regex: (.+)
        - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
          action: replace
          regex: (.+):(?:\d+);(\d+)
          replacement: $$1:$$2
          target_label: __address__
        - action: labelmap
          regex: __meta_kubernetes_pod_label_(.+)

service:
  pipelines:
    metrics:
      receivers: [prometheus]

Il s'agit d'une configuration de scraping simple, basée sur la détection de services, que vous pouvez modifier si nécessaire pour extraire vos applications.

Si vous utilisez une configuration Prometheus existante avec le récepteur prometheus du collecteur OpenTelemetry, remplacez les caractères $ par $$ to avoid triggering environment variable substitution. This is especially important to do for the replacement value within your relabel_configs section. For example, if you have the following relabel_config section:

- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
  action: replace
  regex: (.+):(?:\d+);(\d+)
  replacement: $1:$2
  target_label: __address__

Then rewrite it to be:

- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
  action: replace
  regex: (.+):(?:\d+);(\d+)
  replacement: $$1:$$2
  target_label: __address__


.

For more information, see the OpenTelemetry documentation.

Next, we strongly recommend that you use processors to format your metrics. In many cases, processors must be used to properly format your metrics.

Add processors

OpenTelemetry processors modify telemetry data before it is exported. You can use the processors below to ensure that your metrics are written in a format compatible with Managed Service for Prometheus.

Detect resource attributes

The Managed Service for Prometheus exporter for OpenTelemetry uses the prometheus_target monitored resource to uniquely identify time series data points. The exporter parses the required monitored-resource fields from resource attributes on the metric data points. The fields and the attributes from which the values are scraped are:

  • project_id: auto-detected by Application Default Credentials, gcp.project.id, or project in exporter config (see configuring the exporter)
  • location: location, cloud.availability_zone, cloud.region
  • cluster: cluster, k8s.cluster_name
  • namespace: namespace, k8s.namespace_name
  • job: service.name + service.namespace
  • instance: service.instance.id

Failure to set these labels to unique values can result in "duplicate timeseries" errors when exporting to Managed Service for Prometheus.

The Prometheus receiver automatically sets the service.name attribute based on the job_name in the scrape config, and service.instance.id attribute based on the scrape target's instance. The receiver also sets k8s.namespace.name when using role: pod in the scrape config.

We recommend populating the other attributes automatically using the resource detection processor. However, depending on your environment, some attributes might not be automatically detectable. In this case, you can use other processors to either manually insert these values or parse them from metric labels. The following sections illustration configurations for doing this processing on various platforms

GKE

When running OpenTelemetry on GKE, you only need to enable the resource-detection processor to fill out the resource labels. Be sure that your metrics don't already contain any of the reserved resource labels. If this is unavoidable, see Avoid resource attribute collisions by renaming attributes.

processors:
  resourcedetection:
    detectors: [gcp]
    timeout: 10s

This section can be copied directly into your config file, replacing the processors section if it already exists.

Amazon EKS

The EKS resource detector does not automatically fill in the cluster or namespace attributes. You can provide these values manually by using the resource processor, as shown in the following example:

processors:
  resourcedetection:
    detectors: [eks]
    timeout: 10s

  resource:
    attributes:
    - key: "cluster"
      value: "my-eks-cluster"
      action: upsert
    - key: "namespace"
      value: "my-app"
      action: upsert

You can also convert these values from metric labels using the groupbyattrs processor (see move metric labels to resource labels below).

Azure AKS

The AKS resource detector does not automatically fill in the cluster or namespace attributes. You can provide these values manually by using the resource processor, as shown in the following example:

processors:
  resourcedetection:
    detectors: [aks]
    timeout: 10s

  resource:
    attributes:
    - key: "cluster"
      value: "my-eks-cluster"
      action: upsert
    - key: "namespace"
      value: "my-app"
      action: upsert

You can also convert these values from metric labels by using the groupbyattrs processor; see Move metric labels to resource labels.

On-premises and non-cloud environments

With on-premises or non-cloud environments, you probably can't detect any of the necessary resource attributes automatically. In this case, you can emit these labels in your metrics and move them to resource attributes (see Move metric labels to resource labels), or manually set all of the resource attributes as shown in the following example:

processors:
  resource:
    attributes:
    - key: "cluster"
      value: "my-on-prem-cluster"
      action: upsert
    - key: "namespace"
      value: "my-app"
      action: upsert
    - key: "location"
      value: "us-east-1"
      action: upsert

Create your collector config as a ConfigMap describes how to use the config. That section assumes you have put your config in a file called config.yaml.

The project_id resource attribute can still be automatically set when running the Collector with Application Default Credentials. If your Collector does not have access to Application Default Credentials, see Setting project_id.

Alternatively, you can manually set the resource attributes you need in an environment variable, OTEL_RESOURCE_ATTRIBUTES, with a comma-separated list of key/value pairs, for example:

export OTEL_RESOURCE_ATTRIBUTES="cluster=my-cluster,namespace=my-app,location=us-east-1"

Then use the env resource detector processor to set the resource attributes:

processors:
  resourcedetection:
    detectors: [env]

Avoid resource attribute collisions by renaming attributes

If your metrics already contain labels that collide with the required resource attributes (such as location, cluster, or namespace), rename them to avoid the collision. The Prometheus convention is to add the prefix exported_ to the label name. To add this prefix, use the transform processor.

The following processors config renames any potential collisions and resolves any conflicting keys from the metric:

processors:
  transform:
    # "location", "cluster", "namespace", "job", "instance", and "project_id" are reserved, and
    # metrics containing these labels will be rejected.  Prefix them with exported_ to prevent this.
    metric_statements:
    - context: datapoint
      statements:
      - set(attributes["exported_location"], attributes["location"])
      - delete_key(attributes, "location")
      - set(attributes["exported_cluster"], attributes["cluster"])
      - delete_key(attributes, "cluster")
      - set(attributes["exported_namespace"], attributes["namespace"])
      - delete_key(attributes, "namespace")
      - set(attributes["exported_job"], attributes["job"])
      - delete_key(attributes, "job")
      - set(attributes["exported_instance"], attributes["instance"])
      - delete_key(attributes, "instance")
      - set(attributes["exported_project_id"], attributes["project_id"])
      - delete_key(attributes, "project_id")

Move metric labels to resource labels

In some cases, your metrics might be intentionally reporting labels such as namespace because your exporter is monitoring multiple namespaces. For example, when running the kube-state-metrics exporter.

In this scenario, these labels can be moved to resource attributes using the groupbyattrs processor:

processors:
  groupbyattrs:
    keys:
    - namespace
    - cluster
    - location

In the above example, given a metric with the labels namespace, cluster, and/or location, those labels will be converted to the matching resource attributes.

Limit API requests and memory usage

Two other processors, the batch processor and memory limiter processor allow you to limit the resource consumption of your collector.

Batch processing

Batching requests lets you define how many data points to send in a single request. Note that Cloud Monitoring has a limit of 200 time series per request. Enable the batch processor by using the following settings:

processors:
  batch:
    # batch metrics before sending to reduce API usage
    send_batch_max_size: 200
    send_batch_size: 200
    timeout: 5s

Memory limiting

We recommend enabling the memory-limiter processor to prevent your collector from crashing at times of high throughput. Enable the processing by using the following settings:

processors:
  memory_limiter:
    # drop metrics if memory usage gets too high
    check_interval: 1s
    limit_percentage: 65
    spike_limit_percentage: 20

Configure the googlemanagedprometheus exporter

By default, using the googlemanagedprometheus exporter on GKE requires no additional configuration. For many use cases you only need to enable it with an empty block in the exporters section:

exporters:
  googlemanagedprometheus:

However, the exporter does provide some optional configuration settings. The following sections describe the other configuration settings.

Setting project_id

To associate your time series with a Google Cloud project, the prometheus_target monitored resource must have project_id set.

When running OpenTelemetry on Google Cloud, the Managed Service for Prometheus exporter defaults to setting this value based on the Application Default Credentials it finds. If no credentials are available, or you want to override the default project, you have two options:

  • Set project in the exporter config
  • Add a gcp.project.id resource attribute to your metrics.

We strongly recommend using the default (unset) value for project_id rather than explicitly setting it, when possible.

Set project in the exporter config

The following config excerpt sends metrics to Managed Service for Prometheus in the Google Cloud project MY_PROJECT:

receivers:
  prometheus:
    config:
    ...

processors:
  resourcedetection:
    detectors: [gcp]
    timeout: 10s

exporters:
  googlemanagedprometheus:
    project: MY_PROJECT

service:
  pipelines:
    metrics:
      receivers: [prometheus]
      processors: [resourcedetection]
      exporters: [googlemanagedprometheus]

The only change from previous examples is the new line project: MY_PROJECT. This setting is useful if you know that every metric coming through this Collector should be sent to MY_PROJECT.

Set gcp.project.id resource attribute

You can set project association on a per-metric basis by adding a gcp.project.id resource attribute to your metrics. Set the value of the attribute to the name of the project the metric should be associated with.

For example, if your metric already has a label project, this label can be moved to a resource attribute and renamed to gcp.project.id by using processors in the Collector config, as shown in the following example:

receivers:
  prometheus:
    config:
    ...

processors:
  resourcedetection:
    detectors: [gcp]
    timeout: 10s

  groupbyattrs:
    keys:
    - project

  resource:
    attributes:
    - key: "gcp.project.id"
      from_attribute: "project"
      action: upsert

exporters:
  googlemanagedprometheus:

service:
  pipelines:
    metrics:
      receivers: [prometheus]
      processors: [resourcedetection, groupbyattrs, resource]
      exporters: [googlemanagedprometheus]

Setting client options

The googlemanagedprometheus exporter uses gRPC clients for Managed Service for Prometheus. Therefore, optional settings are available for configuring the gRPC client:

  • compression: Enables gzip compression for gRPC requests, which is useful for minimizing data transfer fees when sending data from other clouds to Managed Service for Prometheus (valid values: gzip).
  • user_agent: Overrides the user-agent string sent on requests to Cloud Monitoring; only applies to metrics. Defaults to the build and version number of your OpenTelemetry Collector, for example, opentelemetry-collector-contrib 0.101.0.
  • endpoint: Sets the endpoint to which metric data is going to be sent.
  • use_insecure: If true, uses gRPC as the communication transport. Has an effect only when the endpoint value is not "".
  • grpc_pool_size: Sets the size of the connection pool in the gRPC client.
  • prefix: Configures the prefix of metrics sent to Managed Service for Prometheus. Defaults to prometheus.googleapis.com. Don't change this prefix; doing so causes metrics to not be queryable with PromQL in the Cloud Monitoring UI.

In most cases, you don't need to change these values from their defaults. However, you can change them to accommodate special circumstances.

All of these settings are set under a metric block in the googlemanagedprometheus exporter section, as shown in the following example:

receivers:
  prometheus:
    config:
    ...

processors:
  resourcedetection:
    detectors: [gcp]
    timeout: 10s

exporters:
  googlemanagedprometheus:
    metric:
      compression: gzip
      user_agent: opentelemetry-collector-contrib 0.101.0
      endpoint: ""
      use_insecure: false
      grpc_pool_size: 1
      prefix: prometheus.googleapis.com

service:
  pipelines:
    metrics:
      receivers: [prometheus]
      processors: [resourcedetection]
      exporters: [googlemanagedprometheus]

What's next