El OpenTelemetry Collector se encuentra en el centro de la arquitectura de OpenTelemetry pero no está relacionado con el W3C Trace Context. En mi demo de trazado, utilizo Jaeger en lugar del Collector. Sin embargo, es ubicuo, como en cada publicación relacionada con OpenTelemetry. Quería explorarlo más a fondo.
En esta publicación, exploro los diferentes aspectos del Collector:
- El tipo de datos: registros, métricas y trazas
- Modelos de push y pull
- Operaciones: lecturas, transformaciones y escrituras
Primeros pasos
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 es una de las principales soluciones de monitoreo. Funciona con un modelo basado en pull: Prometheus raspa los puntos finales compatibles de tu aplicación(es) y los almacena internamente.
Utilizaremos el OTEL Collector para raspar un punto final compatible con Prometheus y mostrar el resultado en la consola. Grafana Labs ofrece un proyecto que genera métricas aleatorias para jugar. Por simplicidad, utilizaré Docker Compose; la configuración se ve de la siguiente manera:
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
- No hay una imagen de Docker disponible para el proyecto de métricas falsas; por lo tanto, necesitamos construirla
- Última versión del OTEL Collector en el momento de escribir esto
- Parametrizar el siguiente archivo de configuración
- Todo sucede aquí
Como mencioné anteriormente, el OTEL Collector puede hacer mucho. Por lo tanto, la configuración es todo.
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. Un receptor lee datos; puede ser de tipo push o pull.
- Utilizamos el receptor predefinido
prometheus
- Definir trabajos de pull
- Configuración del trabajo
- Lista de exportadores. A diferencia de los receptores, un exportador escribe datos.
- El exportador más simple es escribir datos en la salida estándar
- Las canalizaciones ensamblan receptores y exportadores
- Definir una canalización relacionada con las métricas
- La canalización obtiene datos del receptor
prometheus
previamente definido y los envía al exportadorlogging
,es decir, los imprime
Aquí hay una muestra del 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)
Más allá de la impresión
Lo anterior es un excelente primer paso, pero hay más que imprimir en la consola. Expondremos las métricas para que sean raspadas por una instancia regular de Prometheus; podemos agregar unpanel de Grafana para visualizarlas. Aunque puede parecer inútil, tenga paciencia, ya que es solo un escalón.
Para lograr lo anterior, solo cambiamos la configuración del OTEL Collector:
exporters:
prometheus: #1
endpoint: ":${env:PROMETHEUS_PORT}" #2
service:
pipelines:
metrics:
receivers: [ "prometheus" ]
exporters: [ "prometheus" ] #3
- Agregar un exportador
prometheus
- Exponer un punto final compatible con Prometheus
- Reemplazar la impresión por exposición
Eso es. El OTEL Collector es muy flexible.
Tenga en cuenta que el Collector es de múltiples entradas, múltiples salidas. Para imprimir datos y exponerlos a través del punto final, los agregamos a la canalización:
exporters:
prometheus: #1
endpoint: ":${env:PROMETHEUS_PORT}"
logging: #2
loglevel: debug
service:
pipelines:
metrics:
receivers: [ "prometheus" ]
exporters: [ "prometheus", "logging" ] #3
- Exponer datos
- Imprimir datos
- La tubería imprimirá datos y los exponerá
Con el exportador de Prometheus configurado, podemos visualizar métricas en Grafana.
Tenga en cuenta que los receptores y exportadores especifican su tipo y cada uno de ellos debe ser único. Para cumplir con el último requisito, podemos agregar un calificador para distinguir entre ellos, por ejemplo, prometheus/foo
y prometheus/bar.
Procesamiento de Datos Intermedios
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.
Declara los procesadores de datos en la sección processors
del archivo de configuración. El recopilador los ejecuta en el orden en que se declaran. Implementemos la transformación anterior.
El primer paso hacia nuestro objetivo es comprender que el recopilador tiene dos versiones: una “básica” y una contribuyente que se basa en ella. Los procesadores incluidos en el primero son limitados, tanto en número como en capacidades; por lo tanto, necesitamos cambiar a la versión 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
- Utiliza el sabor
contrib
- Para mayor diversión, el archivo de configuración está en otro camino
En este punto, podemos agregar el procesador en sí:
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
# Haz lo mismo con las métricas generadas por NodeJS
- Invoca el procesador de transformación de métricas
- Lista de transformaciones aplicadas en orden
- Coincide con todas las métricas con la expresión regular definida
- Lista de operaciones aplicadas en orden
- Agrega la etiqueta
- Renombra la métrica eliminando el prefijo del grupo de expresiones regulares
- Cosas divertidas: la sintaxis es
$${x}
Finalmente, agregamos el procesador definido a la tubería:
service:
pipelines:
metrics:
receivers: [ "prometheus" ]
processors: [ "metricstransform" ]
exporters: [ "prometheus" ]
Aquí están los resultados:
Conexión de Receptores y 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.
Primero, agreguemos un receptor de logs:
receivers:
filelog:
include: [ "/var/logs/generated.log" ]
Luego, agregamos un conector:
connectors:
count:
requests.errors:
description: Number of 500 errors
condition: [ "status == 500 " ]
Finalmente, conectamos el receptor de logs y el exportador de métricas:
service:
pipelines:
logs:
receivers: [ "filelog" ]
exporters: [ "count" ]
metrics:
receivers: [ "prometheus", "count" ]
La métrica se llama log_record_count_total
, pero su valor se mantiene en 1.
Manipulación de Logs
Los procesadores permiten la manipulación de datos; los operadores son procesadores especializados que trabajan con logs. Si estás familiarizado con la pila ELK, son equivalentes a Logstash.
Hasta ahora, la marca de tiempo del log es la marca de tiempo de ingesta. Cambiaremos esto por la marca de tiempo de creación.
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
- El log está en formato JSON; podemos usar el parser JSON proporcionado
- Atributos de metadatos para establecer
- Campos para leer
- Patrón de análisis
- Tabla de mapeo
- Aceptar un rango, por ejemplo,
501-599
. El operador tiene un valor interpretado especial5xx
(y similares) para los códigos de estado HTTP. - Eliminar datos duplicados
Logs
En este punto, podemos enviar los logs a cualquier componente de agregación de logs. Nos mantendremos en el ámbito de Grafana Labs y usaremos Loki.
exporters:
loki:
endpoint: "http://loki:3100/loki/api/v1/push"
También podemos usar logs del propio colector:
service:
telemetry:
logs:
Finalmente, agreguemos otra pipeline:
service:
pipelines:
logs:
receivers: [ "filelog" ]
exporters: [ "loki" ]
Grafana también puede visualizar los logs. Elige Loki como fuente de datos.
Conclusión
En esta publicación, profundizamos en el colector de OpenTelemetry. Si bien no es parte obligatoria de la arquitectura de OTEL, es un útil cuchillo suizo para todas tus necesidades de procesamiento de datos. En caso de que no estés atado a una pila específica o no quieras estarlo, es de gran ayuda.
El código fuente completo de esta publicación se puede encontrar en GitHub.
Para Avanzar Más
Source:
https://dzone.com/articles/exploring-the-opentelemetry-collector