paint-brush
Plonger dans le collecteur OpenTelemetryby@nfrankel
1,303
1,303

Plonger dans le collecteur OpenTelemetry

Nicolas Fränkel18m2023/11/18
Read on Terminal Reader

Bien qu'il ne s'agisse pas d'un élément obligatoire de l'architecture OTEL, OTEL Collector est un couteau suisse utile pour tous vos besoins en matière de traitement de données.
featured image - Plonger dans le collecteur OpenTelemetry
Nicolas Fränkel HackerNoon profile picture
0-item
1-item


Le collecteur OpenTelemetry se trouve au centre de l'architecture OpenTelemetry mais n'est pas lié au contexte de trace du W3C. Dans ma démo de traçage , j'utilise Jaeger au lieu du Collector. Pourtant, c'est omniprésent, comme dans chaque article lié à OpenTelemetry. Je voulais l'explorer davantage.


Dans cet article, j'explore les différents aspects du Collector :


  • Le type de données : journaux, métriques et traces
  • Modèles pousser et tirer
  • Opérations : lectures, transformations et écritures

Premiers pas

Il y a longtemps, l’observabilité telle que nous la connaissons n’existait pas ; ce que nous avions à la place, c'était la surveillance . À l’époque, la surveillance consistait en un groupe de personnes regardant des écrans affichant des tableaux de bord. Les tableaux de bord eux-mêmes étaient constitués de métriques et uniquement de métriques système : principalement l'utilisation du processeur, de la mémoire et du disque. Pour cette raison, nous commencerons par les métriques.


Prometheus est l'une des principales solutions de surveillance. Il fonctionne sur un modèle basé sur l'extraction : Prometheus récupère les points de terminaison compatibles de votre (vos) application (s) et les stocke en interne.


Nous utiliserons le collecteur OTEL pour récupérer un point de terminaison compatible Prometheus et imprimer le résultat dans la console. Grafana Labs propose un projet qui génère des métriques aléatoires avec lesquelles jouer. Par souci de simplicité, j'utiliserai Docker Compose ; la configuration ressemble à ce qui suit :


 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
  1. Aucune image Docker n'est disponible pour le projet de fausses métriques ; par conséquent, nous devons le construire
  2. Dernière version d'OTEL Collector au moment d'écrire ces lignes
  3. Paramétrez le fichier de configuration suivant
  4. Tout se passe ici


Comme je l'ai mentionné ci-dessus, l'OTEL Collector peut faire beaucoup de choses. Par conséquent, la configuration est primordiale.


 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
  1. Liste des destinataires. Un récepteur lit les données ; il peut être basé sur le push ou sur le pull.
  2. Nous utilisons le récepteur prédéfini prometheus
  3. Définir des tâches d'extraction
  4. Configuration du travail
  5. Liste des exportateurs. Contrairement aux destinataires, un exportateur écrit des données.
  6. L'exportateur le plus simple consiste à écrire des données sur la sortie standard
  7. Les pipelines assemblent les récepteurs et les exportateurs
  8. Définir un pipeline lié aux métriques
  9. Le pipeline récupère les données du récepteur prometheus précédemment défini et les envoie à l'exportateur logging , c'est-à-dire les imprime.


Voici un exemple du résultat :


 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)

Au-delà de l'impression

Ce qui précède est une excellente première étape, mais il y a bien plus que l’impression sur la console. Nous exposerons les métriques à récupérer par une instance Prometheus standard ; nous pouvons ajouter un tableau de bord Grafana pour les visualiser. Même si cela peut sembler inutile, soyez patient, car ce n’est qu’une étape.


Pour réaliser ce qui précède, nous modifions uniquement la configuration du collecteur OTEL :


 exporters: prometheus: #1 endpoint: ":${env:PROMETHEUS_PORT}" #2 service: pipelines: metrics: receivers: [ "prometheus" ] exporters: [ "prometheus" ] #3
  1. Ajouter un exportateur prometheus
  2. Exposer un point de terminaison compatible Prometheus
  3. Remplacer l'impression par l'exposition


C'est ça. Le collecteur OTEL est très flexible.


Notez que le collecteur est multi-entrées, multi-sorties. Pour à la fois imprimer les données et les exposer via le point de terminaison, nous les ajoutons au pipeline :


 exporters: prometheus: #1 endpoint: ":${env:PROMETHEUS_PORT}" logging: #2 loglevel: debug service: pipelines: metrics: receivers: [ "prometheus" ] exporters: [ "prometheus", "logging" ] #3
  1. Exposer les données
  2. Imprimer les données
  3. Le pipeline imprimera les données et les exposera


Avec l'exportateur Prometheus configuré, nous pouvons visualiser les métriques dans Grafana.


Visualiser les métriques


Notez que les destinataires et les exportateurs précisent leur type et que chacun d'entre eux doit être unique. Pour respecter cette dernière exigence, nous pouvons ajouter un qualificatif pour les distinguer, c'est-à-dire prometheus/foo et prometheus/bar.

Traitement des données intermédiaires

Une question valable serait de savoir pourquoi le collecteur OTEL est placé entre la source et Prometheus, car cela rend la conception globale plus fragile. À ce stade, nous pouvons exploiter la véritable puissance du collecteur OTEL : le traitement des données. Jusqu'à présent, nous avons ingéré des métriques brutes, mais le format source n'est peut-être pas adapté à la manière dont nous souhaitons visualiser les données. Par exemple, dans notre configuration, les métriques proviennent de notre faux générateur, « business », et de la plateforme NodeJS sous-jacente, « technique ». Cela se reflète dans le nom des métriques. Nous pourrions ajouter une étiquette source dédiée et supprimer le préfixe inutile pour filtrer plus efficacement.


Vous déclarez les sous-traitants dans la section processors du fichier de configuration. Le collecteur les exécute dans l'ordre dans lequel ils sont déclarés. Implémentons la transformation ci-dessus.


La première étape vers notre objectif est de comprendre que le collectionneur a deux saveurs : une version « nue » et une version contrib qui s'appuie sur elle. Les processeurs inclus dans le premier sont limités, tant en nombre qu'en capacités ; par conséquent, nous devons changer la version 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
  1. Utiliser la saveur contrib
  2. Pour plus de plaisir, le fichier de configuration se trouve sur un autre chemin


À ce stade, nous pouvons ajouter le processeur lui-même :


 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
  1. Invoquer le processeur de transformation de métriques
  2. Liste des transformations appliquées dans l'ordre
  3. Correspond à toutes les métriques avec l'expression rationnelle définie
  4. Liste des opérations appliquées dans l'ordre
  5. Ajouter l'étiquette
  6. Renommez la métrique en supprimant le préfixe du groupe d'expression rationnelle
  7. Trucs amusants : la syntaxe est $${x}


Enfin, nous ajoutons le processeur défini au pipeline :


 service: pipelines: metrics: receivers: [ "prometheus" ] processors: [ "metricstransform" ] exporters: [ "prometheus" ]


Voici les résultats:


Résultats

Connecter les récepteurs et les exportateurs

Un connecteur est à la fois un récepteur et un exportateur et relie deux pipelines. L'exemple de la documentation reçoit le nombre de travées (traçage) et exporte le nombre, qui a une métrique. J'ai essayé de faire la même chose avec 500 erreurs - spoiler : cela ne fonctionne pas comme prévu.


Ajoutons d'abord un récepteur de journaux :


 receivers: filelog: include: [ "/var/logs/generated.log" ]


Ensuite, on ajoute un connecteur :


 connectors: count: requests.errors: description: Number of 500 errors condition: [ "status == 500 " ]


Enfin, nous connectons le récepteur de journaux et l'exportateur de métriques :


 service: pipelines: logs: receivers: [ "filelog" ] exporters: [ "count" ] metrics: receivers: [ "prometheus", "count" ]


La métrique est nommée log_record_count_total , mais sa valeur reste à 1.

Manipulation des journaux

Les processeurs permettent la manipulation des données ; les opérateurs sont des processeurs spécialisés qui travaillent sur les journaux. Si vous connaissez la pile Elasticsearch Logstash Kibana, elle est l'équivalent de Logstash.


Pour l’instant, l’horodatage du journal est l’horodatage de l’ingestion. Nous le remplacerons par l'horodatage de sa création.


 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
  1. Le journal est au format JSON ; nous pouvons utiliser l'analyseur JSON fourni
  2. Attributs de métadonnées à définir
  3. Champs à partir desquels lire
  4. Modèle d'analyse
  5. Tableau de mappage
  6. Acceptez une plage, par exemple 501-599 . L'opérateur a une valeur interprétée spéciale 5xx (et similaire) pour les statuts HTTP.
  7. Supprimer les données dupliquées

Journaux

À ce stade, nous pouvons envoyer les journaux à n’importe quel composant d’agrégation de journaux. Nous resterons dans la sphère Grafana Labs et utiliserons Loki.


 exporters: loki: endpoint: "http://loki:3100/loki/api/v1/push"


Nous pouvons également utiliser les logs du collecteur lui-même :


 service: telemetry: logs:


Enfin, ajoutons un autre pipeline :


 service: pipelines: logs: receivers: [ "filelog" ] exporters: [ "loki" ]


Grafana peut également visualiser les journaux. Choisissez Loki comme source de données.

Conclusion

Dans cet article, nous avons exploré le collecteur OpenTelemetry. Bien que ce ne soit pas une partie obligatoire de l'architecture OTEL, c'est un couteau suisse utile pour tous vos besoins en traitement de données. Si vous n'êtes pas limité à une pile spécifique ou si vous ne le souhaitez pas, c'est d'une aide précieuse.


Le code source complet de cet article peut être trouvé sur GitHub .


Pour aller plus loin:


Publié initialement sur A Java Geek le 12 novembre 2023