استكشاف مجمع OpenTelemetry

يقع جهاز OpenTelemetry Collector في مركز بنية مبادرة OpenTelemetry ولكنه غير مرتبط بسياق W3C Trace Context. في عرض العمليات التتبعية التجريبي التتبع الخاص بي، استخدمت Jaeger بدلاً من الجهاز المُجمِّع. ومع ذلك، فإنه سائد، كما هو الحال في كل منشور متعلق بـ OpenTelemetry. أردت استكشافه بشكل أكبر.

في هذه المشاركة، أستكشف الجوانب المختلفة للجهاز المُجمِّع:

  • نوع البيانات: السجلات، المقاييس، والتتبعات
  • النماذج المدفوعة والمُسحوبة
  • العمليات: القراءات، التحويلات، والكتابات

الخطوات الأولى

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.

بروميثيوس هي واحدة من الحلول الأساسية للمراقبة. إنها تعمل على نموذج قائم على السحب: بروميثيوس تجميع النقاط المتوافقة مع تطبيقاتك (المتعددة) وتخزينها داخليًا.

سنستخدم جهاز OTEL Collector لتجميع نقطة متوافقة مع بروميثيوس وطباعة النتيجة في ال counsel. تقدم Grafana Labs مشروع يولد مقاييس عشوائية للعب بها. من أجل البساطة، سأستخدم Docker Compose؛ الإعداد يبدو كما يلي:

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. لا يوجد صورة Docker متاحة لمشروع المقاييس الزائفة؛ وبالتالي، نحتاج لبنائها
  2. أحدث إصدار من جهاز OTEL Collector عند نشر هذا المنشور
  3. تعديل ملف التكوين التالي
  4. كل شيء يحدث هنا

كما ذكرت أعلاه، يمكن لجهاز OTEL Collector القيام بالكثير. وبالتالي، التكوين هو كل شيء.

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. قائمة المستقبلات. المستقبل يقرأ البيانات؛ يمكن أن يكون إما على أساس دفع أو سحب.
  2. نستخدم مستقبل prometheus محدد مسبقًا
  3. تحديد وظائف السحب
  4. تكوين الوظيفة
  5. قائمة المصدرين. بالمقابل للمستقبلات، المصدر يكتب البيانات.
  6. أبسط المصدرين هو كتابة البيانات على الإخراج القياسي
  7. تجميع المحاور المستقبلين والمصدرين
  8. تحديد محاور متعلقة بالمقاييس
  9. المحور يجلب البيانات من المستقبل prometheus المحدد سابقًا ويرسلها إلى مصدر logging، أي، يطبعها

فيما يلي نموذج من النتيجة:

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)

أبعد من الطباعة

ما سبق هو خطوة رائعة أولى، لكن هناك أكثر من مجرد طباعة للوحدة النمطية. سنعرض المقاييس ليتم سحبها بواسطة مثيل Prometheus عادي؛ يمكننا إضافة لوحة Grafana لتصورها. رغم أن ذلك قد يبدو عديم الفائدة، إلا أن تأتي مع ذلك، لأنه مجرد خطوة.

لتحقيق ما سبق، نغير فقط تكوين OTEL Collector:

YAML

 

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

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

  1. إضافة مصدر prometheus
  2. تعريض نقطة نهاية متوافقة مع Prometheus
  3. استبدال الطباعة بالتعريض

هذا كل شيء. OTEL Collector مرن للغاية.

لاحظ أن المجمع هو عدة مدخلات، عدة مخرجات. لكل من طباعة البيانات وتعريضها عبر النقطة النهاية، نضيفها إلى المحور:

YAML

 

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

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

  1. تعريض البيانات
  2. طباعة البيانات
  3. سيقوم الخط الإنتاجي بطباعة البيانات وتعريضها

مع تكوين موصل Prometheus، يمكننا تصور المقاييس في Grafana.

لاحظ أن المستقبلات والموصلات يحددون نوعهمويجب أن يكون كل منها فريدًا. للامتثال للمتطلب الأخير، يمكننا إضافة معيار للتمييز بينهم،على سبيل المثال، prometheus/foo وprometheus/bar.

معالجة البيانات الوسيطة

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.

تعلن عن معالجات البيانات في قسم processors من ملف التكوين. ينفذ الجمع بينهما بالترتيب الذي يعلنون به. دعونا نطبق التحويل أعلاه.

الخطوة الأولى نحو هدفنا هي فهم أن الجمع بينهما له نوعان: النوع “الخام” ونوع contrib الذي يبني عليه. المعالجات المدرجة في الأولى محدودة، في العدد وفي القدرات؛ ولذا نحتاج لتبديل الإصدار contrib.

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. استخدم نكهة contrib
  2. لإضافة متعة، ملف التكوين في مسار آخر

عند هذه النقطة، يمكننا إضافة المعالج نفسه:

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
# افعل الشيء نفسه مع المقاييس التي تولدها NodeJS

  1. استدعاء معالج تحويل المقاييس
  2. قائمة بالتحويلات المطبقة بالترتيب
  3. يطابق جميع المقاييس مع العبارة التعبيرية المعرفة
  4. قائمة بالعمليات المطبقة بالترتيب
  5. إضافة التسمية
  6. إعادة تسمية المقياس عن طريق إزالة مقدمة مجموعة العبارة التعبيرية
  7. الأشياء الممتعة: بناء الجملة هو $${x}

أخيرًا، نضيف المعالج المحدد إلى الخط:

YAML

 

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

إليكم النتائج:

ربط المتلقيات والمصدرين

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.

لنبدأ أولاً بإضافة متلقي للسجلات:

YAML

 

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

ثم نضيف موصل:

YAML

 

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

أخيرًا، نربط متلقي السجلات بمصدر المعلومات:

YAML

 

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

المقياس يسمى log_record_count_total، لكن قيمته تبقى عند 1.

معالجة السجلات

تتيح المعالجات معالجة البيانات؛ المشغلون هم معالجون متخصصون يعملون على السجلات. إذا كنت على دراية بمكونات الـ ELK، فهم يعادلون Logstash.

حتى الآن، تواريخ السجل هي تواريخ الاستيعاب. سنغيرها إلى تواريخ إنشائها.

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. السجل في شكل JSON؛ يمكننا استخدام محلل JSON المُقدم
  2. إعداد سمات البيانات
  3. الحقول التي يجب قراءتها
  4. نمط التحليل
  5. جدول التعيين
  6. قبول نطاق، مثلا، 501-599. المشغل لديه قيمة مفسرة خاصة 5xx (ومشابهة) للأعمال التجارية التشفيرية HTTP.
  7. إزالة البيانات المكررة

السجلات

في هذه المرحلة، يمكننا إرسال السجلات إلى أي مكون تجميع السجلات. سنبقى في جوانب Grafana Labs ونستخدم Loki.

YAML

 

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

يمكننا أيضًا استخدام سجلات الجمع:

YAML

 

service:
  telemetry:
    logs:

أخيرًا، لنضيف خطوط إرسال أخرى:

YAML

 

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

Grafana يمكنها أيضًا تصور السجلات. اختر Loki كمصدر بيانات.

الخاتمة

في هذا المنشور، تعمقنا في مجمع OpenTelemetry. وبينما لا يعد جزءًا إجباريًا من هيكل OTEL، إلا أنه سكينة سويسرية مفيدة لجميع احتياجاتكم في معالجة البيانات. في حال لم تكن ملتزمًا بمكون معين أو لا ترغب في ذلك، فإنه يعد مساعدة هائلة.

يمكن العثور على الشفرة المصدرية الكاملة لهذا المنشور على GitHub.

للمضي قدمًا

Source:
https://dzone.com/articles/exploring-the-opentelemetry-collector