Arquitetura

O conteúdo desta página pode estar desatualizado e alguns links podem ser inválidos. Uma versão mais recente desta página existe em Inglês.

Mais informações ...

Para visualizar as alterações na página em inglês desde a última atualização: visite GitHub compare 2871fe3c..714d6cc9 e procure por content/en/docs/collector/architecture.md.

O OpenTelemetry Collector é um arquivo executável que pode receber telemetria, processá-la e exportá-la para múltiplos destinos, como backends de observabilidade.

O Collector suporta vários protocolos populares de código aberto para receber e enviar dados de telemetria, e oferece uma arquitetura extensível para adicionar mais protocolos.

O recebimento, processamento e exportação de dados são feitos usando pipelines. Você pode configurar o Collector para ter um ou mais pipelines.

Cada pipeline inclui:

  • Um conjunto de receivers que coletam os dados.
  • Uma série de processors opcionais que recebem os dados dos receivers e os processam.
  • Um conjunto de exporters que recebem os dados dos processors e os enviam para fora do Collector.

O mesmo receiver pode ser incluído em múltiplos pipelines, e múltiplos pipelines podem incluir o mesmo exporter.

Pipelines

Um pipeline define um caminho que os dados seguem no Collector: desde a recepção, passando pelo processamento (ou modificação), até a exportação.

Os pipelines podem operar em três tipos de dados de telemetria: rastros, métricas e logs. O tipo de dado é uma propriedade do pipeline definida por sua configuração. Os receivers, processors e exporters utilizados em um pipeline devem suportar o tipo de dado específico, caso contrário a exceção pipeline.ErrSignalNotSupported é reportada quando a configuração é carregada.

O diagrama a seguir representa um pipeline típico:

---
title: Pipeline
---
flowchart LR
  R1(Receiver 1) --> P1[Processor 1]
  R2(Receiver 2) --> P1
  RM(...) ~~~ P1
  RN(Receiver N) --> P1
  P1 --> P2[Processor 2]
  P2 --> PM[...]
  PM --> PN[Processor N]
  PN --> FO((distribuidor))
  FO --> E1[[Exporter 1]]
  FO --> E2[[Exporter 2]]
  FO ~~~ EM[[...]]
  FO --> EN[[Exporter N]]

Os pipelines podem ter um ou mais receivers. Os dados de todos os receivers são enviados para o primeiro processor, que processa os dados e os repassa para o próximo processor. Um processor também pode descartar os dados caso esteja realizando amostragem ou filtragem. Esse processo continua até que o último processor do pipeline envie os dados para os exporters. Cada exporter recebe uma cópia de cada elemento de dado. O último processor usa um fanoutconsumer para enviar os dados para múltiplos exporters.

O pipeline é construído durante a inicialização do Collector com base na definição do pipeline na configuração.

Uma configuração típica de pipeline se parece com isso:

service:
  pipelines: # seção que pode conter várias subseções, uma por tubulação
    traces: # tipo do _pipeline_
      receivers: [otlp, zipkin]
      processors: [memory_limiter]
      exporters: [otlp, zipkin]

O exemplo anterior define um pipeline para o tipo rastro de dado de telemetria, que inclui dois receivers, um processor e dois exporters. O receiver com dois receivers, um processor e dois exporters.

Receivers

Os receivers normalmente escutam em uma porta de rede e recebem dados de telemetria. Eles também podem obter dados ativamente, como scrapers. Normalmente um receiver é configurado para enviar os dados recebidos para um pipeline. No entanto, também é possível configurar o mesmo receiver para enviar os mesmos dados recebidos para múltiplos pipelines. Isso pode ser feito listando o mesmo receiver na chave receivers de vários pipelines:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: localhost:4317

service:
  pipelines:
    traces: # o _pipeline_ do tipo "rastro (_traces_)"
      receivers: [otlp]
      processors: [memory_limiter]
      exporters: [otlp]
    traces/2: # outro _pipeline_ do tipo "rastro (_traces_)"
      receivers: [otlp]
      processors: [transform]
      exporters: [otlp]

No exemplo acima, o receiver otlp enviará os mesmos dados para o pipeline traces e para o pipeline traces/2.

A configuração usa nomes de chaves compostas na forma tipo[/nome].

Quando o Collector carrega essa configuração, o resultado se parece com este diagrama (parte dos processors e exporters foram omitidos por brevidade):

flowchart LR
  R1("`#quot;opentelemetry-collector#quot; Receiver`") --> FO((distribuidor))
  FO -->|Pipeline 'traces'| P1["`#quot;memory_limiter#quot; Processor`"]
  FO -->|Pipeline 'traces/2'| P2["`#quot;transform#quot; Processor`"]
  P1 ~~~ M1[...]
  P2 ~~~ M2[...]

Exporters

Os exporters normalmente encaminham os dados que recebem para um destino na rede, mas também podem enviar os dados para outros lugares. Por exemplo, o exporter debug escreve os dados de telemetria no destino de log.

A configuração permite múltiplos exporters do mesmo tipo, no mesmo pipeline. Por exemplo, você pode ter dois exporters otlp definidos, cada um enviando para um endpoint OTLP diferente:

exporters:
  otlp/1:
    endpoint: example.com:4317
  otlp/2:
    endpoint: localhost:14317

Um exporter normalmente recebe dados de um pipeline. No entanto, você pode configurar múltiplos pipelines para enviar dados para o mesmo exporter:

exporters:
  otlp:
    protocols:
      grpc:
        endpoint: localhost:14250

service:
  pipelines:
    traces: # o _pipeline_ do tipo "rastro (_traces_)"
      receivers: [zipkin]
      processors: [memory_limiter]
      exporters: [otlp]
    traces/2: # outro _pipeline_ do tipo "rastro (_traces_)"
      receivers: [otlp]
      processors: [transform]
      exporters: [otlp]

No exemplo acima, o exporter otlp recebe dados do pipeline traces e do pipeline traces/2. Quando o Collector carrega essa configuração, o resultado se parece com este diagrama (parte dos processors e receivers foram omitidos por brevidade):

flowchart LR
  M1[...] ~~~ P1["`#quot;memory_limiter#quot; Processor`"]
  M2[...] ~~~ P2["`#quot;transform#quot; Processor`"]
  P1 -->|Pipeline 'traces'|E1[["`#quot;otlp#quot; Exporter`"]]
  P2 -->|Pipeline 'traces/2'|E1

Processors

Um pipeline pode conter processors conectados em sequência. O primeiro processor recebe os dados de um ou mais receivers configurados para o pipeline, e o último processor envia os dados para um ou mais exporters configurados para o pipeline. Todos os processors entre o primeiro e o último recebem os dados de apenas um processor anterior e enviam dados para apenas um processor sucessor.

Os processors podem transformar os dados antes de encaminhá-los, como adicionar ou remover atributos de trecho. Podem também descartar os dados ao decidir não encaminhá-los (por exemplo, o processor probabilisticsampler). Ou podem gerar novos dados.

O mesmo nome do processor pode ser referenciado na chave processors de múltiplos pipelines. Nesse caso, a mesma configuração é usada para cada um desses processors, mas cada pipeline sempre obtém sua própria instância do processor. Cada um desses processors tem seu próprio estado, e os processors nunca são compartilhados entre pipelines. Por exemplo, se o processor transform for usado em vários pipelines, cada pipeline terá seu próprio processor transform, mas cada processor transform é configurado exatamente da mesma forma se referenciarem a mesma chave na configuração. Veja a seguinte configuração:

processors:
  transform:
    error_mode: ignore
    trace_statements:
      - set(resource.attributes["namespace"],
        resource.attributes["k8s.namespace.name"])
      - delete_key(resource.attributes, "k8s.namespace.name")

service:
  pipelines:
    traces: # o _pipeline_ do tipo "rastro (_traces_)"
      receivers: [zipkin]
      processors: [transform]
      exporters: [otlp]
    traces/2: # outro _pipeline_ do tipo "rastro (_traces_)"
      receivers: [otlp]
      processors: [transform]
      exporters: [otlp]

Quando o Collector carrega essa configuração, o resultado se parece com este diagrama:

---
title: Pipeline "traces"
---
flowchart LR
  R1("`zipkin Receiver`") --> P1["`#quot;transform#quot; Processor`"]
  P1 --> E1[["`#quot;otlp#quot; Exporter`"]]
---
title: Pipeline "traces/2"
---
flowchart LR
  R1("`otlp Receiver`") --> P1["`#quot;transform#quot; Processor`"]
  P1 --> E1[["`#quot;otlp#quot; Exporter`"]]

Observe que cada processor transform é uma instância independente, embora sejam configurados da mesma forma com um send_batch_size de 10000.

O mesmo nome do processor não deve ser referenciado mais de uma vez na chave processors de um único pipeline.

Executando como agente

Em uma VM/container típica, as aplicações do usuário estão sendo executadas em alguns processos/pods com uma biblioteca OpenTelemetry. Anteriormente, a biblioteca fazia todo o registro, coleta, amostragem e agregação de rastros, métricas e logs e, em seguida, exportava os dados para outros backends de armazenamento persistente através dos exporters da biblioteca, ou os exibia em zpages locais. Esse padrão tem várias desvantagens, por exemplo:

  1. Para cada biblioteca OpenTelemetry, os exporters e zpages precisam ser reimplementados em linguagens nativas.
  2. Em algumas linguagens de programação (por exemplo, Ruby ou PHP), é difícil fazer a agregação de estatísticas em processo.
  3. Para habilitar a exportação de trechos, estatísticas ou métricas do OpenTelemetry, os usuários da aplicação precisam adicionar manualmente os exporters da biblioteca e reimplantar seus binários. Isso é especialmente difícil quando um incidente ocorreu e os usuários querem usar o OpenTelemetry para investigar o problema imediatamente.
  4. Os usuários da aplicação precisam assumir a responsabilidade de configurar e inicializar os exporters. Essas tarefas são suscetíveis a erros (por exemplo, configurar credenciais incorretas ou recursos monitorados), e os usuários podem relutar em “poluir” seu código com OpenTelemetry.

Para resolver os problemas acima, você pode executar o OpenTelemetry Collector como um agente. O agente é executado como um daemon na VM/container e pode ser implantado independentemente da biblioteca. Uma vez implantado e em execução, o agente deve ser capaz de recuperar rastros, métricas e logs da biblioteca e exportá-los para outros backends. Também podemos dar ao agente a capacidade de enviar configurações (como a probabilidade de amostragem) para a biblioteca. Para as linguagens que não conseguem fazer a agregação de estatísticas em processo, elas podem enviar medições brutas e deixar o agente fazer a agregação.

flowchart LR
  subgraph S1 ["#nbsp;"]
      subgraph S2 ["#nbsp;"]
        subgraph VM [VM]
            PR["Processo [Biblioteca]"] -->|Amostra trechos, métricas| AB[Agente Binário]
            AB -->|Enviar configurações| PR
        end
        subgraph K8s-pod [K8s Pod]
            AC["`Contêiner de aplicativo [Biblioteca]`"] --> AS[Agente Binário]
            AS --> AC
        end
        subgraph K8s-node [K8s Node]
            subgraph Pod1 [Pod]
                APP1[App] ~~~ APP2[App]
            end
            subgraph Pod2 [Pod]
                APP3[App] ~~~ APP4[App]
            end
            subgraph Pod3 [Pod]
                APP5[App] ~~~ APP6[App]
            end
            subgraph AD [Agente Daemonset]
            end
            APP1 --> AD
            APP2 --> AD
            APP4 --> AD
            APP6 --> AD
        end
      end
      subgraph Backends ["#nbsp;"]
          AB --> BE[Backend]
          AS --> PRM[Prometheus Backend]
          AS --> JA[Jaeger Backend]
          AD --> JA
      end
  end

class S2 noLines;
class VM,K8s-pod,K8s-node,Pod1,Pod2,Pod3,Backends withLines;
class PR,AB,AC,AS,APP1,APP2,APP3,APP4,APP5,APP6,AD,BE,PRM,JA nodeStyle
classDef noLines stroke:#fff,stroke-width:4px,color:#000000;
classDef withLines fill:#fff,stroke:#4f62ad,color:#000000;
classDef nodeStyle fill:#e3e8fc,stroke:#4f62ad,color:#000000;

Para desenvolvedores e mantenedores de outras bibliotecas: adicionando receivers específicos, você pode configurar um agente para aceitar rastros, métricas e logs de outras bibliotecas de rastreamento/monitoramento, como Zipkin, Prometheus, etc. Consulte Receivers para mais detalhes.

Executando como gateway

O OpenTelemetry Collector pode ser executado como uma instância de gateway e receber trechos e métricas exportados por um ou mais agentes ou bibliotecas, ou por tarefas/agentes que emitem em um dos protocolos suportados. O Collector é configurado para enviar dados para os exporter(s) configurados. A figura a seguir resume a arquitetura de implantação:

flowchart LR
  subgraph S1 ["#nbsp;"]
      subgraph S2 ["#nbsp;"]
        subgraph S3 ["#nbsp;"]
          subgraph VM [VM]
              PR["Processo [Biblioteca]"]
          end
          subgraph K8s-pod [K8s Pod]
              AC["`Contêiner de aplicativo [Biblioteca]`"]
          end
          subgraph K8s-node [K8s Node]
              subgraph Pod1 [Pod]
                  APP1[App] ~~~ APP2[App]
              end
              subgraph Pod2 [Pod]
                  APP3[App] ~~~ APP4[App]
              end
              subgraph Pod3 [Pod]
                  APP5[App] ~~~ APP6[App]
              end
              subgraph AD [Agente Daemonset]
              end
              APP1 --> AD
              APP2 --> AD
              APP4 --> AD
              APP6 --> AD
          end
        end
        subgraph S4 ["#nbsp;"]
            PR --> OTEL["`Serviço OpenTelemetry Collector`"]
            AC --> OTEL
            AD --> OTEL
            OTEL ---> BE[Backend X]
        end
      end
      subgraph S5 ["#nbsp;"]
        subgraph S6 ["#nbsp;"]
            JA[Jaeger Backend]
        end
        subgraph S7 ["#nbsp;"]
            PRM[Prometheus Backend]
        end
      end
      JA ~~~ PRM
      OTEL --> JA
      OTEL --> PRM
  end

class S1,S3,S4,S5,S6,S7,S8 noLines;
class VM,K8s-pod,K8s-node,Pod1,Pod2,Pod3 withLines;
class S2 lightLines
class PR,AC,APP1,APP2,APP3,APP4,APP5,APP6,AD,OTEL,BE,JA,PRM nodeStyle
classDef noLines stroke-width:0px,color:#000000;
classDef withLines fill:#fff,stroke:#4f62ad,color:#000000;
classDef lightLines stroke:#acaeb0,color:#000000;
classDef nodeStyle fill:#e3e8fc,stroke:#4f62ad,color:#000000;

O OpenTelemetry Collector também pode ser implantado em outras configurações, como receber dados de outros agentes ou clientes em um dos formatos suportados pelos seus receivers.


Última modificação June 9, 2026: chore: drifted status update (#10303) (ec3134ea)