Skip to main content

Collector vs SDK

O collector é um componente do backend.

É responsável por ingerir os dados de telemetria, todos os registros, traces e metricas, e toda as outras coisas que serão implementadas no futuro. Primeiramente ele coleta tudo e depois faz algum processamento, se necessário, e por fim faz o export.

É bem semelhante ao SDK em algumas partes, mas não necessáriamente gera os dados, ele recebe os dados.

  • SKD

    • Gera dados
    • Processa dados
    • Exporta os dados
    • Exclusivo da aplicação
  • Collector

    • Recebe os dados
    • Processa os dados (Pode fazer, não é obrigatório.)
    • Exporta os dados
    • Pode ser escolonado para receber vários registros de várias fontes.
    • Serve como uma ponte entre o vendor e a infra local.

Se toda as aplicações enviarem o dado para o colector teremos uma configuração centralizada para onde vamos armazenar os dados. Vamos imaginar que hoje estamos usando o Datadog, mas daqui um tempo vamos passar para o Dynatrace, somente a mudança de configuração no colector seria necessário se todas as aplicação utilizassem o colector, caso contrário seria necessário mudar o exporter de todas elas.

Um colector tem a função de separar os dados de métrica, logs e traces e enviá-los à difernetes vendors.

Trace pipeline: receiver>>>>processor>>>>exporter
Metric pipeline: receiver>>>>processor>>>>exporter
Logs pipeline: receiver>>>>processor>>>>exporter

O vendor para métricas pode ser diferentes do vendor para traces e para logs. Poderíamos usar o elastic search para trace, prometheus para métricas e grafana loki para logs.

Vamos analisar o que tinhamos até agora.

O SDK de cada aplicação envia os dados para o Jaeger e expoe o /metric para que o prometheus vá buscar as métricas e para isso configuramos o prometheus com os targets dessas aplicações.

alt text

o que queremos? Que as aplicações enviem tudo para o collector e ele distribua para os lugares corretos. O Prometheus agora irá fazer o scrape no collector.

alt text

Para isso vamos configurar um collector que na verdade é uma configuração yaml simples.

Vamos adicionar o collector ao docker-compose

##código...
collector:
image: otel/opentelemetry-collector-contrib
command:
- '--config=/etc/collector/collector.yaml'
ports:
- 8889:8889
- 4317:4317
- 4318:4318
volumes:
- ./collector:/etc/collector
depends_on:
- prometheus
- jaeger

Basicamente precisamos expor as portas que usaremos e passar o arquivo de configuração.

Agora precisamos definir o arquivo de configuração do collector.

Agora vamos olhar esse arquivo de configuração.

# Configurações de receivers
receivers:
otlp: # Vamos usar referenciar essa configuração em services.
protocols:
http:
endpoint: 0.0.0.0:4318
cors:
allowed_origins: ["*"]
grpc:
endpoint: 0.0.0.0:4317

# Configurações de processors
processors:

# Configurações de exporters
exporters:
# O prometheus irá fazer o scrape no nosso collector ao invés de fazer na aplicação, logo é necessário mudar as configurações nele.
prometheus:
endpoint: 0.0.0.0:8889
send_timestamps: true
namespace: otel
const_labels:
via: collector

otlphttp: ## Para exportar para o jaeger usando o otlp com http
endpoint: "http://jaeger:4318"
tls:
insecure: true

# Configurações de extensions falaremos mais tarde
extensions:
health_check:

# Configurações de services
service:
extensions:
- health_check
pipelines: # Teremos dois pipelines no nosso cenário
# Cada um desses pipelines tem o seu receivers, processors e exporters
traces:
# Aqui estamos dizendo como vamos ingerir os dados, poderia ser em formatods diferentes,
# com níveis diferentes de segurança, com diferentes encondings, etc
# no nosso caso vamos usar o receiver com o nome otlp que definimos acima que aceita http e grpc
receivers: # podemos ingerir dados de vários lugares por isso é um array
- otlp
processors:
# poderíamos exportar para vários lugares ao mesmo tempo no nosso caso só o jaeger para traces
exporters:
- otlphttp
metrics:
receivers:
- otlp
processors:
# poderíamos exportar para vários lugares ao mesmo tempo no nosso caso só o prometheus para métricas
exporters:
- prometheus

Como mensionado acima precisamos mudar o target do Prometheus no arquivo prometheus.yaml para fazer o scrape do collector ao invés das nossas aplicações.

global:
scrape_interval: "5s"

scrape_configs:
- job_name: 'opentelemetry'
metrics_path: /metrics
scheme: http
static_configs:
- targets:
# - todo:9464
# - auth:9464
- collector:8889

Também será necessário mudar a configuração do sdk da nossa aplicação. O novo código estará na branch collector incluindo todos os arquivos aqui mensionados.

No nosso intrumentation.ts vamos fazer as seguintes alterações

import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-proto";
//Código....

function start(serviceName: string) {
//Código....

// NÃO VAMOS MAIS EXPOR OS DADOS EM UM ENDPOINT, PRECISAMOS FAZER O PUSH DOS DADOS PARA O COLLECTOR.
// const prometheusExporter = new PrometheusExporter(
// {
// port: PrometheusExporter.DEFAULT_OPTIONS.port,
// endpoint: PrometheusExporter.DEFAULT_OPTIONS.endpoint,
// },
// () => {
// console.log(
// `prometheus scrape endpoint: http://localhost:${PrometheusExporter.DEFAULT_OPTIONS.port}${PrometheusExporter.DEFAULT_OPTIONS.endpoint}`
// );
// }
// );

// VAMO USAR AGORA O OTLPMetricExporter

const metricReader = new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter({
url: "http://collector:4318/v1/metrics",
}),
});

const meterProvider = new MeterProvider({
resource,
// readers: [prometheusExporter],
readers: [metricReader],
});

const traceExporter = new OTLPTraceExporter({
// url: "http://jaeger:4318/v1/traces",
// Ao invés de enviar para o jaeger vamos enviar para o collector.
url: "http://collector:4318/v1/traces",
});
//Código....
}

É isso ai... se verificar vai ver que temos tudo funcionando. Execute o compose novamente, verifique o jaeger e o prometheus com as métricas.