Der OpenTelemetry Collector befindet sich im Zentrum der OpenTelemetry-Architektur, hat jedoch keinen Bezug zum W3C-Trace-Kontext. In meiner Tracing-Demo verwende ich Jaeger anstelle des Collectors. Dennoch ist es allgegenwärtig, wie in jedem Beitrag zum Thema OpenTelemetry. Ich wollte es weiter erforschen.
In diesem Beitrag erkunde ich die verschiedenen Aspekte des Collectors:
Vor langer Zeit gab es die Beobachtbarkeit , wie wir sie kennen, nicht; Was wir stattdessen hatten, war Überwachung . Damals bestand die Überwachung aus einer Gruppe von Leuten, die auf Bildschirme schauten, auf denen Dashboards angezeigt wurden. Die Dashboards selbst bestanden aus Metriken und nur aus Systemmetriken: hauptsächlich CPU-, Speicher- und Festplattennutzung. Aus diesem Grund beginnen wir mit Metriken.
Prometheus ist eine der wichtigsten Überwachungslösungen. Es funktioniert nach einem Pull-basierten Modell: Prometheus erfasst kompatible Endpunkte Ihrer Anwendung(en) und speichert sie intern.
Wir werden den OTEL Collector verwenden, um einen Prometheus-kompatiblen Endpunkt zu scrappen und das Ergebnis in der Konsole auszudrucken. Grafana Labs bietet ein Projekt an, das zufällige Metriken zum Spielen generiert. Der Einfachheit halber verwende ich Docker Compose; das Setup sieht wie folgt aus:
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
Wie oben erwähnt, kann der OTEL Collector einiges. Daher ist Konfiguration alles.
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
Empfängerprometheus
Empfänger ab und sendet sie an den logging
Exporter, dh druckt sie aus
Hier ist ein Beispiel des Ergebnisses:
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)
Das Obige ist ein ausgezeichneter erster Schritt, aber es geht um mehr als nur das Drucken auf der Konsole. Wir werden die Metriken offenlegen, die von einer regulären Prometheus-Instanz gescrapt werden sollen. Wir können ein Grafana-Dashboard hinzufügen, um sie zu visualisieren. Auch wenn es sinnlos erscheint, haben Sie Geduld damit, denn es ist nur ein Trittstein.
Um das oben Gesagte zu erreichen, ändern wir lediglich die OTEL Collector-Konfiguration:
exporters: prometheus: #1 endpoint: ":${env:PROMETHEUS_PORT}" #2 service: pipelines: metrics: receivers: [ "prometheus" ] exporters: [ "prometheus" ] #3
prometheus
Exporter hinzu
Das ist es. Der OTEL Collector ist sehr flexibel.
Beachten Sie, dass der Collector über mehrere Eingänge und mehrere Ausgänge verfügt. Um Daten sowohl zu drucken als auch über den Endpunkt verfügbar zu machen, fügen wir sie der Pipeline hinzu:
exporters: prometheus: #1 endpoint: ":${env:PROMETHEUS_PORT}" logging: #2 loglevel: debug service: pipelines: metrics: receivers: [ "prometheus" ] exporters: [ "prometheus", "logging" ] #3
Wenn der Prometheus-Exporter konfiguriert ist, können wir Metriken in Grafana visualisieren.
Beachten Sie, dass Empfänger und Exporteure ihren Typ angeben und jeder von ihnen eindeutig sein muss. Um die letzte Anforderung zu erfüllen, können wir ein Qualifikationsmerkmal anhängen, um zwischen ihnen zu unterscheiden, z. B. prometheus/foo
und prometheus/bar.
Eine berechtigte Frage wäre, warum der OTEL Collector zwischen der Quelle und Prometheus platziert wird, da er das Gesamtdesign fragiler macht. In dieser Phase können wir die wahre Leistungsfähigkeit des OTEL Collectors nutzen: die Datenverarbeitung. Bisher haben wir Rohmetriken aufgenommen, aber das Quellformat ist möglicherweise nicht an die Art und Weise angepasst, wie wir die Daten visualisieren möchten. In unserem Setup stammen die Metriken beispielsweise von unserem Fake-Generator „Business“ und der zugrunde liegenden NodeJS-Plattform „Technical“. Dies spiegelt sich im Namen der Metriken wider. Wir könnten eine dedizierte Quellenbezeichnung hinzufügen und das unnötige Präfix entfernen, um effizienter zu filtern.
Datenverarbeiter deklarieren Sie im Abschnitt processors
der Konfigurationsdatei. Der Collector führt sie in der Reihenfolge aus, in der sie deklariert werden. Lassen Sie uns die obige Transformation implementieren.
Der erste Schritt zu unserem Ziel besteht darin, zu verstehen, dass der Collector zwei Varianten hat: eine „nackte“ Variante und eine Contrib-Variante, die darauf aufbaut. Die im ersteren enthaltenen Prozessoren sind sowohl in ihrer Anzahl als auch in ihren Fähigkeiten begrenzt; Daher müssen wir die Contrib-Version wechseln.
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
Variante
An dieser Stelle können wir den Prozessor selbst hinzufügen:
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}
Abschließend fügen wir den definierten Prozessor zur Pipeline hinzu:
service: pipelines: metrics: receivers: [ "prometheus" ] processors: [ "metricstransform" ] exporters: [ "prometheus" ]
Hier sind die Ergebnisse:
Ein Connector ist sowohl Empfänger als auch Exporter und verbindet zwei Pipelines. Das Beispiel aus der Dokumentation empfängt die Anzahl der Spans (Tracing) und exportiert die Anzahl, die eine Metrik hat. Ich habe versucht, das Gleiche mit 500 Fehlern zu erreichen – Spoiler: Es funktioniert nicht wie beabsichtigt.
Fügen wir zunächst einen Protokollempfänger hinzu:
receivers: filelog: include: [ "/var/logs/generated.log" ]
Dann fügen wir einen Connector hinzu:
connectors: count: requests.errors: description: Number of 500 errors condition: [ "status == 500 " ]
Zuletzt verbinden wir den Log-Receiver und den Metrik-Exporter:
service: pipelines: logs: receivers: [ "filelog" ] exporters: [ "count" ] metrics: receivers: [ "prometheus", "count" ]
Die Metrik heißt log_record_count_total
, ihr Wert bleibt jedoch bei 1.
Prozessoren ermöglichen die Datenmanipulation; Operatoren sind spezialisierte Prozessoren, die Protokolle bearbeiten. Wenn Sie mit dem Elasticsearch Logstash Kibana-Stack vertraut sind, sind sie das Äquivalent von Logstash.
Ab sofort ist der Protokollzeitstempel der Aufnahmezeitstempel. Wir werden es in den Zeitstempel seiner Erstellung ändern.
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
. Der Operator hat einen speziell interpretierten Wert 5xx
(und ähnlich) für HTTP-Status.An diesem Punkt können wir die Protokolle an jede Protokollaggregationskomponente senden. Wir bleiben im Grafana Labs-Bereich und verwenden Loki.
exporters: loki: endpoint: "http://loki:3100/loki/api/v1/push"
Wir können auch Protokolle vom Collector selbst verwenden:
service: telemetry: logs:
Zum Schluss fügen wir noch eine weitere Pipeline hinzu:
service: pipelines: logs: receivers: [ "filelog" ] exporters: [ "loki" ]
Grafana kann die Protokolle auch visualisieren. Wählen Sie Loki als Datenquelle.
In diesem Beitrag haben wir uns intensiv mit dem OpenTelemetry-Kollektor befasst. Obwohl es kein zwingender Bestandteil der OTEL-Architektur ist, ist es ein nützliches Schweizer Messer für alle Ihre Datenverarbeitungsanforderungen. Für den Fall, dass Sie nicht an einen bestimmten Stapel gebunden sind oder dies nicht möchten, ist dies eine enorme Hilfe.
Den vollständigen Quellcode für diesen Beitrag finden Sie auf GitHub .
Um weiter zu gehen:
Ursprünglich veröffentlicht bei A Java Geek am 12. November 2023