OpenTelemetry Collector se encuentra en el centro de la arquitectura de OpenTelemetry, pero no está relacionado con el contexto de seguimiento del W3C. En mi demostración de rastreo , uso Jaeger en lugar del Collector. Sin embargo, es omnipresente, como en todas las publicaciones relacionadas con OpenTelemetry. Quería explorarlo más.
En esta publicación, exploro los diferentes aspectos del Coleccionista:
Hace mucho tiempo, la observabilidad tal como la conocemos no existía; lo que teníamos en cambio era monitoreo . En aquel entonces, el monitoreo consistía en un grupo de personas mirando pantallas que mostraban paneles. Los paneles en sí consistían en métricas y solo en métricas del sistema: principalmente uso de CPU, memoria y disco. Por este motivo, comenzaremos con las métricas.
Prometheus es una de las principales soluciones de monitoreo. Funciona en un modelo basado en extracción: Prometheus extrae los puntos finales compatibles de sus aplicaciones y los almacena internamente.
Usaremos OTEL Collector para extraer un punto final compatible con Prometheus e imprimir el resultado en la consola. Grafana Labs ofrece un proyecto que genera métricas aleatorias con las que jugar. En aras de la simplicidad, usaré Docker Compose; la configuración se parece a la siguiente:
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
Como mencioné anteriormente, OTEL Collector puede hacer mucho. Por tanto, la configuración lo 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" ] #9
prometheus
prometheus
previamente definido y los envía al exportador logging
, 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)
Lo anterior es un excelente primer paso, pero hay más que imprimir en la consola. Expondremos las métricas que una instancia normal de Prometheus eliminará; Podemos agregar un panel de Grafana para visualizarlos. Si bien puede parecer inútil, tenga paciencia, ya que es sólo un peldaño.
Para lograr lo anterior, solo cambiamos la configuración de OTEL Collector:
exporters: prometheus: #1 endpoint: ":${env:PROMETHEUS_PORT}" #2 service: pipelines: metrics: receivers: [ "prometheus" ] exporters: [ "prometheus" ] #3
prometheus
Eso es todo. El OTEL Collector es muy flexible.
Tenga en cuenta que el recopilador es de múltiples entradas y 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
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 distinguirlos, es decir , prometheus/foo
y prometheus/bar.
Una pregunta válida sería por qué el Colector OTEL está colocado entre la fuente y Prometheus, ya que hace que el diseño general sea más frágil. En esta etapa, podemos aprovechar el verdadero poder de OTEL Collector: el procesamiento de datos. Hasta ahora, hemos ingerido métricas sin procesar, pero es posible que el formato de origen no se adapte a cómo queremos visualizar los datos. Por ejemplo, en nuestra configuración, las métricas provienen de nuestro generador falso, "negocio", y de la plataforma NodeJS subyacente, "técnica". Se refleja en el nombre de las métricas. Podríamos agregar una etiqueta de fuente dedicada y eliminar el prefijo innecesario para filtrar de manera más eficiente.
Usted declara procesadores de datos en la sección processors
del archivo de configuración. El cobrador los ejecuta en el orden en que son declarados. Implementemos la transformación anterior.
El primer paso hacia nuestro objetivo es comprender que el coleccionista tiene dos versiones: una "simple" y una contribución que se basa en él. Los procesadores incluidos en los primeros son limitados, tanto en número como en capacidades; por lo tanto, necesitamos cambiar la versión de 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
contrib
En este punto, podemos agregar el propio procesador:
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 # Do the same with metrics generated by NodeJS
$${x}
Finalmente, agregamos el procesador definido al pipeline:
service: pipelines: metrics: receivers: [ "prometheus" ] processors: [ "metricstransform" ] exporters: [ "prometheus" ]
Aquí están los resultados:
Un conector es a la vez receptor y exportador y conecta dos tuberías. El ejemplo de la documentación recibe el número de tramos (rastreo) y exporta el recuento, que tiene una métrica. Intenté lograr lo mismo con 500 errores - spoiler: no funciona como se esperaba.
Primero agreguemos un receptor de registros:
receivers: filelog: include: [ "/var/logs/generated.log" ]
Luego, agregamos un conector:
connectors: count: requests.errors: description: Number of 500 errors condition: [ "status == 500 " ]
Por último, conectamos el receptor de registros y el exportador de métricas:
service: pipelines: logs: receivers: [ "filelog" ] exporters: [ "count" ] metrics: receivers: [ "prometheus", "count" ]
La métrica se denomina log_record_count_total
, pero su valor permanece en 1.
Los procesadores permiten la manipulación de datos; Los operadores son procesadores especializados que trabajan con troncos. Si está familiarizado con la pila Kibana de Elasticsearch Logstash, es el equivalente a Logstash.
A partir de ahora, la marca de tiempo del registro es la marca de tiempo de ingesta. Lo cambiaremos a la marca de tiempo de su 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
501-599
. El operador tiene un valor interpretado especial 5xx
(y similar) para los estados HTTP.En este punto, podemos enviar los registros a cualquier componente de agregación de registros. Nos quedaremos en la esfera de Grafana Labs y usaremos a Loki.
exporters: loki: endpoint: "http://loki:3100/loki/api/v1/push"
También podemos utilizar registros del propio recopilador:
service: telemetry: logs:
Finalmente, agreguemos otra canalización:
service: pipelines: logs: receivers: [ "filelog" ] exporters: [ "loki" ]
Grafana también puede visualizar los registros. Elija Loki como fuente de datos.
En esta publicación, profundizamos en el recopilador OpenTelemetry. Si bien no es una parte obligatoria de la arquitectura OTEL, es una útil navaja suiza para todas sus necesidades de procesamiento de datos. En caso de que no estés apegado a una pila específica o no quieras, es de gran ayuda.
El código fuente completo de esta publicación se puede encontrar en GitHub .
Para llegar más lejos:
Publicado originalmente en A Java Geek el 12 de noviembre de 2023