De OpenTelemetry Collector staat centraal in de OpenTelemetry-architectuur, maar is ongerelateerd aan de W3C Trace Context. In mijn tracing demo gebruik ik Jaeger in plaats van de Collector. Toch is het overal aanwezig, zoals in elk OpenTelemetry-gerelateerd bericht. Ik wilde het verder onderzoeken.
In deze post onderzoek ik de verschillende aspecten van de Collector:
- Het soort gegevens: logs, metrische gegevens en traceringen
- Push- en pullmodellen
- Operaties: lezen, transformaties en schrijven
Eerste stappen
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 is een van de primaire bewakingsoplossingen. Het werkt volgens een pull-based model: Prometheus scrapt compatibele eindpunten van uw applicatie(s) en slaat ze intern op.
We zullen de OTEL Collector gebruiken om een Prometheus-compatibel eindpunt te scrapen en het resultaat in de console af te drukken. Grafana Labs biedt een project dat willekeurige metrische gegevens genereert om mee te spelen. Voor de eenvoud gebruik ik Docker Compose; de setup ziet er als volgt uit:
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
- Er is geen Docker-installatiekopie beschikbaar voor het nep-metrics project; daarom moeten we deze bouwen
- Laatste versie van de OTEL Collector op het moment van schrijven
- Configureer het volgende configuratiebestand
- Alles gebeurt hier
Zoals ik hierboven al zei, kan de OTEL Collector veel. Daarom is configuratie 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" ] #10
- Lijst van ontvangers. Een ontvanger leest gegevens; het kan zowel push-gebaseerd als pull-gebaseerd zijn.
- We gebruiken de
prometheus
vooraf gedefinieerde ontvanger - Definieer pull taken
- Configuratie van de taak
- Lijst van exporters. In tegenstelling tot ontvangers, schrijft een exporter gegevens.
- De eenvoudigste exporter is om gegevens naar standaard uit te schrijven
- Pipelines assembleren ontvangers en exporters
- Definieer een metrisch gerelateerde pipeline
- De pipeline haalt gegevens op van de eerder gedefinieerde
prometheus
ontvanger en stuurt deze door naar delogging
exporter, dwz, print ze
Hier is een voorbeeld van het resultaat:
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)
Verder dan afdrukken
Het bovenstaande is een uitstekende eerste stap, maar er is meer dan alleen afdrukken naar de console. We zullen de metrische gegevens blootstellen om te worden opgehaald door een reguliere Prometheus-instantie; we kunnen een Grafana dashboard toevoegen om deze te visualiseren. Hoewel het misschien nutteloos lijkt, aarzel niet, want het is slechts een tussenstap.
Om het bovenstaande te bereiken, veranderen we alleen de configuratie van de OTEL Collector:
exporters:
prometheus: #1
endpoint: ":${env:PROMETHEUS_PORT}" #2
service:
pipelines:
metrics:
receivers: [ "prometheus" ]
exporters: [ "prometheus" ] #3
- Voeg een
prometheus
exporter toe - Bespreek een Prometheus-compatibel eindpunt
- Vervang afdrukken door blootleggen
Dat is het. De OTEL Collector is zeer flexibel.
Merk op dat de Collector multi-input, multi-output is. Om zowel gegevens af te drukken als ze te blootleggen via het eindpunt, voegen we ze toe aan de pipeline:
exporters:
prometheus: #1
endpoint: ":${env:PROMETHEUS_PORT}"
logging: #2
loglevel: debug
service:
pipelines:
metrics:
receivers: [ "prometheus" ]
exporters: [ "prometheus", "logging" ] #3
- Blootstelling van gegevens
- Print gegevens
- De pijplijn zal zowel gegevens afdrukken als ze ontsluiten
Met de Prometheus-exporter geconfigureerd, kunnen we metrische gegevens in Grafana visualiseren.
Merk op dat ontvangers en exporters hun type aangeven en ieder van hen uniek moet zijn. Om aan de laatste vereiste te voldoen, kunnen we een kwalificatie toevoegen om ze te onderscheiden, bijvoorbeeld, prometheus/foo
en prometheus/bar.
Tussendataverwerking
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.
Je declareert gegevensverwerkers in de processors
sectie van het configuratiebestand. De verzamelaar voert ze uit in de volgorde waarin ze zijn gedeclareerd. Laten we de bovenstaande transformatie implementeren.
De eerste stap naar ons doel is om te begrijpen dat de verzamelaar twee varianten heeft: een “nuda” en een contrib die hierop bouwt. De aanwezige processors in de eerste zijn beperkt, zowel in aantal als in mogelijkheden; daarom moeten we overschakelen naar de contrib-versie.
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
- Gebruik de
contrib
smaak - Voor extra plezier ligt het configuratiebestand op een andere locatie
Op dit punt kunnen we de processor zelf toevoegen:
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
# Doe hetzelfde met de door NodeJS gegenereerde metrische gegevens
- Roep de metrische gegevenstransformatieprocessor aan
- Lijst van toegepaste transformaties in volgorde
- Vereist alle metrische gegevens met de gedefinieerde regexp
- Lijst van toegepaste operaties in volgorde
- Voeg de label toe
- Verander de metrische naam door het regexp groepsprefix te verwijderen
- Leuk feit: de syntaxis is
$${x}
Tenslotte voegen we de gedefinieerde processor toe aan de pijplijn:
service:
pipelines:
metrics:
receivers: [ "prometheus" ]
processors: [ "metricstransform" ]
exporters: [ "prometheus" ]
Hier zijn de resultaten:
Verbinden van ontvangers en exporteurs
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.
Laten we eerst een logboekontvanger toevoegen:
receivers:
filelog:
include: [ "/var/logs/generated.log" ]
Vervolgens voegen we een connector toe:
connectors:
count:
requests.errors:
description: Number of 500 errors
condition: [ "status == 500 " ]
Tot slot verbinden we de logboekontvanger en de metrissexporter:
service:
pipelines:
logs:
receivers: [ "filelog" ]
exporters: [ "count" ]
metrics:
receivers: [ "prometheus", "count" ]
De metriek heet log_record_count_total
, maar de waarde blijft op 1.
Logboekmanipulatie
Processors stellen manipulatie van gegevens mogelijk; operatoren zijn specifieke processors die werken op logboeken. Als je bekend bent met de ELK stack, zijn ze het equivalent van Logstash.
Voor zover nu, is de logboektimestamp de opname-timestamp. We zullen deze wijzigen naar de tijdstempel van de creatie.
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
- Het logboek is in JSON-formaat; we kunnen de meegeleverde JSON-parser gebruiken
- Metagegevensattributen instellen
- Velden om te lezen
- Parsermuster
- Toewijzingsschema
- Accepteer een bereik, bijvoorbeeld,
501-599
. De operator heeft een speciale geïnterpreteerde waarde5xx
(en soortgelijke) voor HTTP-statussen. - Verwijder dubbele gegevens
Logboeken
Op dit punt kunnen we de logboeken naar elke logboekaggregatiecomponent verzenden. We blijven in het Grafana Labs-gebied en gebruiken Loki.
exporters:
loki:
endpoint: "http://loki:3100/loki/api/v1/push"
We kunnen ook logboeken gebruiken van de verzamelaar zelf:
service:
telemetry:
logs:
Tot slot, laten we nog een pipeline toevoegen:
service:
pipelines:
logs:
receivers: [ "filelog" ]
exporters: [ "loki" ]
Grafana kan ook de logboeken visualiseren. Kies Loki als datasource.
Conclusie
In deze post hebben we ons verdiept in de OpenTelemetry collector. Hoewel het geen verplicht onderdeel is van de OTEL-architectuur, is het een handig Zwitsers zakmes voor al je gegevensverwerkingsbehoeften. Mocht je niet gebonden zijn aan een specifieke stack of dat niet wilt, is het een onschatbare hulp.
Het volledige broncode voor deze post is te vinden op GitHub.
Verdergaan
Source:
https://dzone.com/articles/exploring-the-opentelemetry-collector