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.
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.
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.