O OpenTelemetry Collector ocupa o centro da arquitetura do OpenTelemetry, mas não está relacionado ao W3C Trace Context. No meu demo de rastreamento, utilizo o Jaeger em vez do Collector. No entanto, é onipresente, como em cada post relacionado ao OpenTelemetry. Eu queria explorá-lo mais a fundo.
Neste post, explorarei os diferentes aspectos do Collector:
- O tipo de dados: logs, métricas e rastreamentos
- Modelos de push e pull
- Operações: leituras, transformações e escritas
Primeiros Passos
A long time ago, observability as we know it didn’t exist; what we had instead was monitoring. Back then, monitoring was a bunch of people looking at screens displaying dashboards. Dashboards themselves consisted of metrics and only system metrics, mainly CPU, memory, and disk usage. For this reason, we will start with metrics.
Prometheus é uma das principais soluções de monitoramento. Funciona com um modelo baseado em pull: o Prometheus raspa pontos finais compatíveis de sua aplicação(ões) e armazena-os internamente.
Utilizaremos o OTEL Collector para raspar um ponto final compatível com o Prometheus e imprimir o resultado no console. O Grafana Labs oferece um projeto que gera métricas aleatórias para brincar. Por simplicidade, vou usar o Docker Compose; a configuração é a seguinte:
version: "3"
services:
fake-metrics:
build: ./fake-metrics-generator #1
collector:
image: otel/opentelemetry-collector:0.87.0 #2
environment: #3
- METRICS_HOST=fake-metrics
- METRICS_PORT=5000
volumes:
- ./config/collector/config.yml:/etc/otelcol/config.yaml:ro #4
- Não há imagem Docker disponível para o projeto de métricas falsas; portanto, precisamos construí-la
- Versão mais recente do OTEL Collector na época da redação deste texto
- Parametrizar o seguinte arquivo de configuração
- Tudo acontece aqui
Como mencionei acima, o OTEL Collector pode fazer muito. Portanto, a configuração é tudo.
receivers: #1
prometheus: #2
config:
scrape_configs: #3
- job_name: fake-metrics #4
scrape_interval: 3s
static_configs:
- targets: [ "${env.METRICS_HOST}:${env.METRICS_PORT}" ]
exporters: #5
logging: #6
loglevel: debug
service:
pipelines: #7
metrics: #8
receivers: [ "prometheus" ] #9
exporters: [ "logging" ] #10
- Lista de receptores. Um receptor lê dados; pode ser baseado em push ou pull.
- Utilizamos o receptor pré-definido
prometheus
- Definir tarefas de pull
- Configuração do trabalho
- Lista de exportadores. Em contraste com os receptores, um exportador escreve dados.
- O exportador mais simples é escrever dados no standard out
- Pipelines montam receptores e exportadores
- Definir um pipeline relacionado a métricas
- O pipeline obtém dados do receptor
prometheus
previamente definido e envia-os para o exportadorlogging
, ou seja, imprime-os
Aqui está um exemplo do resultado:
2023-11-11 08:28:54 otel-collector-collector-1 | StartTimestamp: 1970-01-01 00:00:00 +0000 UTC 2023-11-11 08:28:54 otel-collector-collector-1 | Timestamp: 2023-11-11 07:28:54.14 +0000 UTC 2023-11-11 08:28:54 otel-collector-collector-1 | Value: 83.090000 2023-11-11 08:28:54 otel-collector-collector-1 | NumberDataPoints #1 2023-11-11 08:28:54 otel-collector-collector-1 | Data point attributes: 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__embrace_world_class_systems: Str(concept) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__exploit_magnetic_applications: Str(concept) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__facilitate_wireless_architectures: Str(extranet) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__grow_magnetic_communities: Str(challenge) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__reinvent_revolutionary_applications: Str(support) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__strategize_strategic_initiatives: Str(internet_solution) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__target_customized_eyeballs: Str(concept) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__transform_turn_key_technologies: Str(framework) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__whiteboard_innovative_partnerships: Str(matrices) 2023-11-11 08:28:54 otel-collector-collector-1 | StartTimestamp: 1970-01-01 00:00:00 +0000 UTC 2023-11-11 08:28:54 otel-collector-collector-1 | Timestamp: 2023-11-11 07:28:54.14 +0000 UTC 2023-11-11 08:28:54 otel-collector-collector-1 | Value: 53.090000 2023-11-11 08:28:54 otel-collector-collector-1 | NumberDataPoints #2 2023-11-11 08:28:54 otel-collector-collector-1 | Data point attributes: 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__expedite_distributed_partnerships: Str(approach) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__facilitate_wireless_architectures: Str(graphical_user_interface) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__grow_magnetic_communities: Str(policy) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__reinvent_revolutionary_applications: Str(algorithm) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__transform_turn_key_technologies: Str(framework) 2023-11-11 08:28:54 otel-collector-collector-1 | StartTimestamp: 1970-01-01 00:00:00 +0000 UTC 2023-11-11 08:28:54 otel-collector-collector-1 | Timestamp: 2023-11-11 07:28:54.14 +0000 UTC 2023-11-11 08:28:54 otel-collector-collector-1 | Value: 16.440000 2023-11-11 08:28:54 otel-collector-collector-1 | NumberDataPoints #3 2023-11-11 08:28:54 otel-collector-collector-1 | Data point attributes: 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__exploit_magnetic_applications: Str(concept) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__grow_magnetic_communities: Str(graphical_user_interface) 2023-11-11 08:28:54 otel-collector-collector-1 | -> fake__target_customized_eyeballs: Str(extranet)
Além da Impressão
O que foi mencionado é um excelente primeiro passo, mas há mais do que apenas imprimir no console. Vamos expor as métricas para serem raspadas por uma instância regular de Prometheus; podemos adicionar um painel do Grafana para visualizá-las. Embora possa parecer sem sentido, tenha paciência, pois é apenas um passo intermediário.
Para alcançar o que foi mencionado, basta alterar a configuração do OTEL Collector:
exporters:
prometheus: #1
endpoint: ":${env:PROMETHEUS_PORT}" #2
service:
pipelines:
metrics:
receivers: [ "prometheus" ]
exporters: [ "prometheus" ] #3
- Adicionar um exportador
prometheus
- Expor um ponto final compatível com o Prometheus
- Substituir impressão por exposição
É isso. O OTEL Collector é muito flexível.
Note que o Collector é multi-entrada, multi-saída. Para imprimir dados e expor via ponto de extremidade, adicionamos-os ao pipeline:
exporters:
prometheus: #1
endpoint: ":${env:PROMETHEUS_PORT}"
logging: #2
loglevel: debug
service:
pipelines:
metrics:
receivers: [ "prometheus" ]
exporters: [ "prometheus", "logging" ] #3
- Expor dados
- Imprimir dados
- O pipeline irá imprimir dados e expor eles
Com o exportador do Prometheus configurado, podemos visualizar métricas no Grafana.
Note que os receptores e exportadores especificam seu tipo e cada um deles deve ser único. Para cumprir com o último requisito, podemos adicionar um qualificador para distinguir entre eles, por exemplo, prometheus/foo
e prometheus/bar.
Processamento de Dados Intermediário
A valid question would be why the OTEL Collector is set between the source and Prometheus, as it makes the overall design more fragile. At this stage, we can leverage the true power of the OTEL Collector: data processing. So far, we have ingested raw metrics, but the source format may not be adapted to how we want to visualize data. For example, in our setup, metrics come from our fake generator, “business,” and the underlying NodeJS platform, “technical.” It is reflected in the metrics’ name. We could add a dedicated source label and remove the unnecessary prefix to filter more efficiently.
Você declara processadores de dados na seção processors
do arquivo de configuração. O coletor os executa na ordem em que são declarados. Vamos implementar a transformação acima.
O primeiro passo para alcançar nosso objetivo é entender que o coletor possui duas versões: uma “básica” e uma contrib que se baseia nela. Os processadores incluídos na primeira são limitados, tanto em número quanto em capacidades; portanto, precisamos mudar para a versão contrib.
collector:
image: otel/opentelemetry-collector-contrib:0.87.0 #1
environment:
- METRICS_HOST=fake-metrics
- METRICS_PORT=5000
- PROMETHEUS_PORT=8889
volumes:
- ./config/collector/config.yml:/etc/otelcol-contrib/config.yaml:ro #2
- Use o sabor
contrib
- Para adicionar diversão, o arquivo de configuração está em outro caminho
Neste ponto, podemos adicionar o próprio processador:
processors:
metricstransform: #1
transforms: #2
- include: ^fake_(.*)$ #3
match_type: regexp #3
action: update
operations: #4
- action: add_label #5
new_label: origin
new_value: fake
- include: ^fake_(.*)$
match_type: regexp
action: update #6
new_name: $${1} #6-7
# Faça o mesmo com métricas geradas por NodeJS
- Invoque o processador de transformação de métricas
- Lista de transformações aplicadas na ordem
- Corresponde a todas as métricas com o regexp definido
- Lista de operações aplicadas na ordem
- Adicione a etiqueta
- Renomeie a métrica removendo o prefixo do grupo de regexp
- Coisas divertidas: a sintaxe é
$${x}
Finalmente, adicionamos o processador definido ao pipeline:
service:
pipelines:
metrics:
receivers: [ "prometheus" ]
processors: [ "metricstransform" ]
exporters: [ "prometheus" ]
Aqui estão os resultados:
Conectando Receptores e Exportadores
A connector is both a receiver and an exporter and connects two pipelines. The example from the documentation receives the number of spans (tracing) and exports the count, which has a metric. I tried to achieve the same with 500 errors — spoiler: it doesn’t work as intended.
Primeiro, vamos adicionar um receptor de logs:
receivers:
filelog:
include: [ "/var/logs/generated.log" ]
Em seguida, adicionamos um conector:
connectors:
count:
requests.errors:
description: Number of 500 errors
condition: [ "status == 500 " ]
Por último, conectamos o receptor de logs e o exportador de métricas:
service:
pipelines:
logs:
receivers: [ "filelog" ]
exporters: [ "count" ]
metrics:
receivers: [ "prometheus", "count" ]
A métrica é nomeada como log_record_count_total
, mas seu valor permanece em 1.
Manipulação de Logs
Processadores permitem a manipulação de dados; operadores são processadores especializados que trabalham com logs. Se você está familiarizado com a pilha ELK, eles são equivalentes ao Logstash.
Até agora, o timestamp do log é o timestamp de ingestão. Vamos mudá-lo para o timestamp de criação.
receivers:
filelog:
include: [ "/var/logs/generated.log" ]
operators:
- type: json_parser #1
timestamp: #2
parse_from: attributes.datetime #3
layout: "%d/%b/%Y:%H:%M:%S %z" #4
severity: #2
parse_from: attributes.status #3
mapping: #5
error: 5xx #6
warn: 4xx
info: 3xx
debug: 2xx
- id: remove_body #7
type: remove
field: body
- id: remove_datetime #7
type: remove
field: attributes.datetime
- id: remove_status #7
type: remove
field: attributes.status
- O log está em formato JSON; podemos usar o fornecido analisador JSON
- Atributos de metadados para definir
- Campos para ler
- Padrão de análise
- Tabela de mapeamento
- Aceitar uma faixa, por exemplo,
501-599
. O operador tem um valor interpretado especial5xx
(e similares) para status HTTP. - Remover dados duplicados
Logs
Neste ponto, podemos enviar os logs para qualquer componente de agregação de logs. Vamos permanecer no ambiente Grafana Labs e usar o Loki.
exporters:
loki:
endpoint: "http://loki:3100/loki/api/v1/push"
Também podemos usar logs do próprio coletor:
service:
telemetry:
logs:
Finalmente, vamos adicionar outra pipeline:
service:
pipelines:
logs:
receivers: [ "filelog" ]
exporters: [ "loki" ]
O Grafana também pode visualizar os logs. Escolha o Loki como fonte de dados.
Conclusão
Neste post, exploramos o coletor OpenTelemetry. Embora não seja parte obrigatória da arquitetura do OTEL, é uma faca suíça útil para todos os seus processamentos de dados. Caso você não esteja preso a uma pilha específica ou não queira estar, isso é de grande ajuda.
O código-fonte completo deste post pode ser encontrado no GitHub.
Para ir mais longe
Source:
https://dzone.com/articles/exploring-the-opentelemetry-collector