Primeiros passos com o OpenTelemetry Collector

Neste documento, descrevemos como configurar o OpenTelemetry Collector para coletar métricas padrão do Prometheus e informá-las ao Google Cloud Managed Service para Prometheus. O OpenTelemetry Collector é um agente que pode ser implantado e configurado para exportar para o Managed Service para Prometheus. A configuração é semelhante à execução do Managed Service para Prometheus com coleção autoimplantada.

É possível escolher o coletor do OpenTelemetry em vez da coleção implantada automaticamente pelos seguintes motivos:

  • O OpenTelemetry Collector permite encaminhar dados de telemetria para vários back-ends configurando diferentes exportadores no pipeline.
  • O Collector também é compatível com sinais de métricas, registros e traces. Portanto, ao usá-lo, é possível lidar com todos os três tipos de indicadores em um agente.
  • O formato de dados independentes de fornecedor (OpenOTelemetry Protocol, ou OTLP) do OpenTelemetry é compatível com um forte ecossistema de bibliotecas e componentes do Collector conectáveis. Isso oferece várias opções de personalização para receber, processar e exportar dados.

A desvantagem desses benefícios é que a execução do OpenTelemetry Collector exige uma abordagem de implantação e manutenção autogerenciada. A abordagem escolhida depende das suas necessidades específicas, mas, neste documento, oferecemos diretrizes recomendadas para configurar o OpenTelemetry Collector usando o Managed Service para Prometheus como back-end.

Antes de começar

Nesta seção, descrevemos a configuração necessária para as tarefas descritas neste documento.

Configurar projetos e ferramentas

Para usar o Google Cloud Managed Service para Prometheus, você precisa dos seguintes recursos:

  • Um projeto do Google Cloud com a API Cloud Monitoring ativada.

    • Se você não tiver um projeto do Google Cloud, faça o seguinte:

      1. No Console do Google Cloud, acesse Novo projeto:

        Crie um novo projeto

      2. No campo Project Name, insira um nome para o projeto e clique em Criar.

      3. Acesse o Faturamento:

        Acessar "Faturamento"

      4. Selecione o projeto recém-criado se ele ainda não estiver selecionado na parte superior da página.

      5. Você precisará escolher um perfil para pagamentos atual ou criar um novo.

      A API Monitoring é ativada por padrão para novos projetos.

    • Se você já tem um projeto do Google Cloud, verifique se a API Monitoring está ativada:

      1. Acessar APIs e serviços

        Acessar APIs e serviços

      2. Selecione o projeto.

      3. Clique em Ativar APIs e serviços.

      4. Pesquise "Monitoring".

      5. Nos resultados da pesquisa, clique em "API Cloud Monitoring".

      6. Se a opção "API ativada" não for exibida, clique no botão Ativar.

  • Um cluster do Kubernetes. Se você não tiver um cluster do Kubernetes, siga as instruções no Guia de início rápido do GKE.

Você também precisa das seguintes ferramentas de linha de comando:

  • gcloud
  • kubectl

As ferramentas gcloud e kubectl fazem parte da Google Cloud CLI. Para mais informações sobre como instalá-los, consulte Como gerenciar componentes da CLI do Google Cloud. Para ver os componentes da CLI gcloud que você instalou, execute o seguinte comando:

gcloud components list

Configurar o ambiente

Para evitar inserir repetidamente o ID do projeto ou o nome do cluster, execute a seguinte configuração:

  • Configure as ferramentas de linha de comando da seguinte maneira:

    • Configure a CLI gcloud para se referir ao ID do projeto do Google Cloud:

      gcloud config set project PROJECT_ID
      
    • Configure a CLI kubectl para usar o cluster:

      kubectl config set-cluster CLUSTER_NAME
      

    Para mais informações sobre essas ferramentas, consulte estes recursos:

Configurar um namespace

Crie o namespace NAMESPACE_NAME do Kubernetes para os recursos que você criar como parte do aplicativo de exemplo:

kubectl create ns NAMESPACE_NAME

Verificar as credenciais da conta de serviço

Pule esta seção se o cluster do Kubernetes tiver a Federação de identidade da carga de trabalho para GKE ativada.

Quando executado no GKE, o Managed Service para Prometheus recuperará automaticamente as credenciais do ambiente com base na conta de serviço padrão do Compute Engine. A conta de serviço padrão tem as permissões necessárias, monitoring.metricWriter e monitoring.viewer, por padrão. Se você não usar a Federação de identidade da carga de trabalho para o GKE e tiver removido qualquer um desses papéis da conta de serviço do nó padrão, será necessário adicionar novamente essas permissões que faltam antes de continuar.

Se você não estiver executando no GKE, consulte Fornecer credenciais explicitamente.

Configurar uma conta de serviço para a Federação de Identidade da Carga de Trabalho para o GKE

Pule esta seção se o cluster do Kubernetes não tiver a Federação de identidade da carga de trabalho para GKE ativada.

O Managed Service para Prometheus captura dados de métricas usando a API Cloud Monitoring. Se o cluster estiver usando a federação de identidade da carga de trabalho para o GKE, conceda permissão à conta de serviço do Kubernetes para a API Monitoring. Esta seção descreve:

Criar e vincular a conta de serviço

Essa etapa aparece em vários lugares na documentação do Managed Service para Prometheus. Se você já realizou esta etapa como parte de uma tarefa anterior, não é necessário repeti-la. Pule para Autorizar a conta de serviço.

A sequência de comandos a seguir cria a conta de serviço gmp-test-sa e a vincula à conta de serviço padrão do Kubernetes no namespace 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

Se você estiver usando um namespace ou uma conta de serviço diferente do GKE, ajuste os comandos adequadamente.

Autorizar a conta de serviço

Grupos de permissões relacionadas são coletados em papéis, e você concede os papéis a um principal, neste exemplo, a conta de serviço do Google Cloud. Para mais informações sobre os papéis do Monitoring, consulte Controle de acesso.

O comando a seguir concede à conta de serviço do Google Cloud, gmp-test-sa, os papéis da API Monitoring necessários para gravar dados de métricas.

Se você já concedeu à conta de serviço do Google Cloud um papel específico como parte da tarefa anterior, não é necessário fazer isso novamente.

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

Depurar a configuração da Federação de Identidade da Carga de Trabalho para o GKE

Se você estiver com problemas para fazer a Federação de identidade da carga de trabalho para o GKE funcionar, consulte a documentação para verificar a configuração da Federação de identidade da carga de trabalho para o GKE e o Guia de solução de problemas da Federação de identidade da carga de trabalho para o GKE.

Como erros de digitação e cópias e colagens incompletas são as fontes mais comuns de erros ao configurar a Federação de identidade da carga de trabalho para o GKE, é altamente recomendável usar as variáveis editáveis e os ícones clicáveis de copiar/colar incorporados nos exemplos de código nestas instruções.

Federação de identidade da carga de trabalho para o GKE em ambientes de produção

O exemplo descrito neste documento vincula a conta de serviço do Google Cloud à conta de serviço padrão do Kubernetes e concede à conta de serviço do Google Cloud todas as permissões necessárias para usar a API Monitoring.

Em um ambiente de produção, convém usar uma abordagem mais refinada, com uma conta de serviço para cada componente, cada uma com permissões mínimas. Para mais informações sobre como configurar contas de serviço para gerenciamento de identidades de carga de trabalho, consulte Como usar a Federação de identidade da carga de trabalho para o GKE.

Configurar o OpenTelemetry Collector

Nesta seção, vamos mostrar como configurar e usar o OpenTelemetry Collector para extrair métricas de um aplicativo de exemplo e enviar os dados para o Google Cloud Managed Service para Prometheus. Para informações de configuração detalhadas, consulte as seguintes seções:

O coletor do OpenTelemetry é análogo ao binário de agente do Managed Service para Prometheus. A comunidade do OpenTelemetry publica regularmente lançamentos, incluindo código-fonte, binários e imagens de contêiner.

É possível implantar esses artefatos em VMs ou clusters do Kubernetes usando as práticas recomendadas padrão ou usar o criador de coletores para criar seu próprio coletor, consistindo apenas nos componentes necessários. Para criar um coletor para uso com o Managed Service para Prometheus, você precisa dos seguintes componentes:

  • O Exportador do Managed Service para Prometheus, que grava suas métricas no Managed Service para Prometheus.
  • Um receptor para extrair suas métricas. Neste documento, presumimos que você esteja usando o receptor do OpenTelemetry Prometheus, mas o exportador do Managed Service para Prometheus é compatível com qualquer receptor de métricas do OpenTelemetry.
  • Processadores para agrupar e marcar suas métricas em lotes para incluir identificadores de recursos importantes, dependendo do seu ambiente.

Esses componentes são ativados usando um arquivo de configuração transmitido ao Collector com a sinalização --config.

As seções a seguir explicam como configurar cada um desses componentes com mais detalhes. Neste documento, descrevemos como executar o coletor no GKE e em outro lugar.

Configurar e implantar o Collector

Não importa se você está executando a coleção no Google Cloud ou em outro ambiente, ainda é possível configurar o Coletor OpenTelemetry para exportar para o Managed Service para Prometheus. A maior diferença está em como você configura o coletor. Em ambientes que não são do Google Cloud, pode haver mais formatação de dados de métricas necessários para que ela seja compatível com o Managed Service para Prometheus. No entanto, no Google Cloud, grande parte dessa formatação pode ser detectada automaticamente pelo Collector.

Executar o OpenTelemetry Collector no GKE

É possível copiar a configuração a seguir em um arquivo chamado config.yaml para configurar o OpenTelemetry Collector no 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]

A configuração anterior usa o receptor do Prometheus e o exportador do Managed Service para o Prometheus para extrair os endpoints de métricas nos pods do Kubernetes e exportar para o Managed Service para Prometheus. Os processadores de pipelines formatam e agrupam os dados em lote.

Para saber mais detalhes sobre o que cada parte dessa configuração faz, além de configurações para diferentes plataformas, consulte as seções detalhadas abaixo sobre como extrair dados e como adicionar processadores.

Ao usar uma configuração do Prometheus com o OpenTelemetry Receptor prometheus do coletor, substitua todos os caracteres $ por $$ 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 $$ para evitar acionar a substituição de variável de ambiente. Para mais informações, consulte Rastrear métricas do Prometheus.

Para informações sobre as práticas recomendadas para configurar o coletor em outras nuvens, consulte Amazon EKS ou Azure AKS.

Implantar o aplicativo de exemplo

O aplicativo de exemplo emite a métrica de contador example_requests_total e a métrica de histograma example_random_numbers (entre outras) na porta metrics. O manifesto desse exemplo define três réplicas.

Para implantar o aplicativo de exemplo, execute o seguinte comando:

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

Criar a configuração do coletor como um ConfigMap

Depois de criar a configuração e colocá-la em um arquivo chamado config.yaml, use esse arquivo para criar um ConfigMap do Kubernetes com base no arquivo config.yaml. Quando o coletor é implantado, ele monta o ConfigMap e carrega o arquivo.

Para criar um ConfigMap chamado otel-config com a sua configuração, use o seguinte comando:

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

Implantar o coletor

Crie um arquivo chamado collector-deployment.yaml com o conteúdo a seguir:

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.106.0
        args:
        - --config
        - /etc/otel/config.yaml
        - --feature-gates=exporter.googlemanagedprometheus.intToDouble
        volumeMounts:
        - mountPath: /etc/otel/
          name: otel-config
      volumes:
      - name: otel-config
        configMap:
          name: otel-config

Crie a implantação do coletor no cluster do Kubernetes executando o seguinte comando:

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

Depois de iniciar o pod, ele verifica o aplicativo de amostra e informa as métricas ao Managed Service para Prometheus.

Para informações sobre as maneiras de consultar seus dados, veja Consultar usando o Cloud Monitoring ou Consultar usando o Grafana.

Fornecer credenciais explicitamente

Durante a execução no GKE, o avaliador de regras recupera as credenciais automaticamente do ambiente com base na conta de serviço do nó. Em clusters do Kubernetes que não são do GKE, as credenciais precisam ser explicitamente fornecidas ao OpenTelemetry Collector usando sinalizações ou a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS.

  1. Defina o contexto para seu projeto de destino:

    gcloud config set project PROJECT_ID
    
  2. Crie uma conta de serviço:

    gcloud iam service-accounts create gmp-test-sa
    

    Nesta etapa, é criada a conta de serviço que você pode já ter criado nas instruções da Federação de Identidade da Carga de Trabalho para GKE.

  3. Conceda as permissões necessárias à conta de serviço:

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

  4. Crie e faça o download de uma chave para a conta de serviço:

    gcloud iam service-accounts keys create gmp-test-sa-key.json \
      --iam-account=gmp-test-sa@PROJECT_ID.iam.gserviceaccount.com
    
  5. Adicione o arquivo de chave como secret ao cluster que não é do GKE:

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

  6. Abra o recurso de implantação do OpenTelemetry para edição:

    kubectl -n NAMESPACE_NAME edit deployment otel-collector
    
  1. Adicione o texto exibido em negrito ao recurso:

    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. Salve o arquivo e feche o editor. Depois que a alteração é aplicada, os pods são recriados e começam a autenticar no back-end da métrica com a conta de serviço especificada.

Coletar métricas do Prometheus

Esta seção e a seção seguinte fornecem mais informações de personalização para usar o OpenTelemetry Collector. Essas informações podem ser úteis em determinadas situações, mas nenhuma delas é necessária para executar o exemplo descrito em Configurar o OpenTelemetry Collector.

Se os aplicativos já estiverem expondo endpoints do Prometheus, o OpenTelemetry Collector poderá coletar esses endpoints usando o mesmo formato de configuração de coleta que você usaria com qualquer configuração padrão do Prometheus. Para fazer isso, ative o receptor do Prometheus na configuração do coletor.

Uma configuração de receptor simples do Prometheus para pods do Kubernetes pode ter a seguinte aparência:

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]

Essa é uma configuração de extração simples baseada em descoberta de serviços que você pode modificar conforme necessário para extrair seus aplicativos.

Ao usar uma configuração do Prometheus com o OpenTelemetry Receptor prometheus do coletor, substitua todos os caracteres $ por $$ 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.106.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.106.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