De OpenTelemetry Collector onderzoeken

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:

YAML

 

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. Er is geen Docker-installatiekopie beschikbaar voor het nep-metrics project; daarom moeten we deze bouwen
  2. Laatste versie van de OTEL Collector op het moment van schrijven
  3. Configureer het volgende configuratiebestand
  4. Alles gebeurt hier

Zoals ik hierboven al zei, kan de OTEL Collector veel. Daarom is configuratie alles.

YAML

 

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

  1. Lijst van ontvangers. Een ontvanger leest gegevens; het kan zowel push-gebaseerd als pull-gebaseerd zijn.
  2. We gebruiken de prometheus vooraf gedefinieerde ontvanger
  3. Definieer pull taken
  4. Configuratie van de taak
  5. Lijst van exporters. In tegenstelling tot ontvangers, schrijft een exporter gegevens.
  6. De eenvoudigste exporter is om gegevens naar standaard uit te schrijven
  7. Pipelines assembleren ontvangers en exporters
  8. Definieer een metrisch gerelateerde pipeline
  9. De pipeline haalt gegevens op van de eerder gedefinieerde prometheus ontvanger en stuurt deze door naar de logging 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:

YAML

 

exporters:
  prometheus:                                                               #1
    endpoint: ":${env:PROMETHEUS_PORT}"                                     #2

service:
  pipelines:
    metrics:
      receivers: [ "prometheus" ]
      exporters: [ "prometheus" ]                                           #3

  1. Voeg een prometheus exporter toe
  2. Bespreek een Prometheus-compatibel eindpunt
  3. 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:

YAML

 

exporters:
  prometheus:                                                               #1
    endpoint: ":${env:PROMETHEUS_PORT}"
  logging:                                                                  #2
    loglevel: debug

service:
  pipelines:
    metrics:
      receivers: [ "prometheus" ]
      exporters: [ "prometheus", "logging" ]                                #3

  1. Blootstelling van gegevens
  2. Print gegevens
  3. 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.

YAML

 

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. Gebruik de contrib smaak
  2. Voor extra plezier ligt het configuratiebestand op een andere locatie

Op dit punt kunnen we de processor zelf toevoegen:

YAML

 

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

  1. Roep de metrische gegevenstransformatieprocessor aan
  2. Lijst van toegepaste transformaties in volgorde
  3. Vereist alle metrische gegevens met de gedefinieerde regexp
  4. Lijst van toegepaste operaties in volgorde
  5. Voeg de label toe
  6. Verander de metrische naam door het regexp groepsprefix te verwijderen
  7. Leuk feit: de syntaxis is $${x}

Tenslotte voegen we de gedefinieerde processor toe aan de pijplijn:

YAML

 

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:

YAML

 

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

Vervolgens voegen we een connector toe:

YAML

 

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

Tot slot verbinden we de logboekontvanger en de metrissexporter:

YAML

 

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.

YAML

 

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. Het logboek is in JSON-formaat; we kunnen de meegeleverde JSON-parser gebruiken
  2. Metagegevensattributen instellen
  3. Velden om te lezen
  4. Parsermuster
  5. Toewijzingsschema
  6. Accepteer een bereik, bijvoorbeeld, 501-599. De operator heeft een speciale geïnterpreteerde waarde 5xx (en soortgelijke) voor HTTP-statussen.
  7. 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.

YAML

 

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

We kunnen ook logboeken gebruiken van de verzamelaar zelf:

YAML

 

service:
  telemetry:
    logs:

Tot slot, laten we nog een pipeline toevoegen:

YAML

 

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