التتبع الموزع وOpenTelemetry

مُجمِّع OpenTelemetry

18 دقيقة الدرس 5 من 28

مُجمِّع OpenTelemetry

كل خدمة تُضيف إليها أدوات القياس ستحتاج في نهاية المطاف إلى إيصال بياناتها إلى مكان مفيد — backend للتتبع، أو مخزن مقاييس، أو نظام تجميع سجلات. يمكنك توصيل كل SDK مباشرةً بكل backend، لكن هذا النهج ينهار أمام واقع التشغيل: بيانات اعتماد مبعثرة عبر كل pod، ولا طريقة لإثراء البيانات أو تصفيتها قبل مغادرتها التطبيق، وإعادة نشر في كل مرة تغيّر فيها backend. يحل مُجمِّع OpenTelemetry المشكلات الثلاث دفعةً واحدة. إنه خط أنابيب بيانات قياس محايد من الموردين ومصمم للإنتاج: يستقبل الإشارات من تطبيقاتك ويحوّلها ويوجّهها إلى backend واحد أو أكثر — دون لمس كود التطبيق.

في منظمات بحجم Google، المُجمِّع ليس خياراً. إنه الجهاز العصبي المركزي لمنظومة المراقبة: المستوى الواحد الذي تُطبَّق فيه حوكمة البيانات (أخذ العينات، وحذف PII، والتحكم في التكلفة) قبل وصول أي شيء إلى backend مدفوع.

المعمارية: المُستقبِلات والمُعالِجات والمُصدِّرات

المُجمِّع هو خط أنابيب قابل للتركيب. كل خط أنابيب له ثلاث مراحل بالترتيب:

  1. المُستقبِلات (Receivers) — تستوعب بيانات القياس من المصادر. يقبل مُستقبِل otlp بيانات OTLP عبر gRPC (المنفذ 4317) وHTTP (المنفذ 4318). تسحب مُستقبِلات أخرى من نقاط Prometheus ومن Jaeger وZipkin وKafka وFluent Bit وغيرها. يمكن لمثيل المُجمِّع الواحد تشغيل مُستقبِلات متعددة في آنٍ واحد.
  2. المُعالِجات (Processors) — تحوّل البيانات وتصفّيها وتُجمّعها وتُثريها أثناء التدفق. إنها العضلة التشغيلية لخط الأنابيب: تحذف الامتدادات غير الضرورية، وتضيف بيانات وصفية من Kubernetes، وتُحدِّد عدد السمات، وتُجمّع عمليات التصدير لتحسين الإنتاجية.
  3. المُصدِّرات (Exporters) — ترسل البيانات المحوّلة إلى backends. يتحدث مُصدِّر OTLP مع Grafana Tempo وHoneycomb وأي backend يدعم OTel. يعرض مُصدِّر Prometheus نقطة جمع بيانات (scrape). أما مُصدِّر debug فيطبع على stdout — لا غنى عنه أثناء التطوير.

تُعلَن خطوط الأنابيب لكل نوع إشارة (traces وmetrics وlogs) ويمكنها التشعب إلى مُصدِّرات متعددة في آنٍ واحد. ربط نفس المُعالِج بخطوط أنابيب متعددة يتيح تطبيق قاعدة تطبيع واحدة على جميع أنواع الإشارات.

الامتدادات (Extensions) هي مفهوم رابع على المستوى الأعلى: تضيف قدرات مساعدة كفحوصات الصحة (health_check)، ونقطة pprof للتنميط (pprof)، وواجهة zPages للتصحيح (zpages). تعمل الامتدادات جنباً إلى جنب مع خطوط الأنابيب لكنها ليست جزءاً من تدفق البيانات.
خط أنابيب مُجمِّع OpenTelemetry: المُستقبِلات والمُعالِجات والمُصدِّرات App (OTel SDK) OTLP gRPC :4317 Prometheus scrape / push Fluent Bit Logs :24224 OpenTelemetry Collector Receivers otlp / prometheus Receivers prometheus Receivers fluentforward Processors memory_limiter batch k8sattributes filter tail_sampling attributes resource Exporters prometheus Exporters otlp (Tempo) Exporters loki / otlp Prometheus Metrics Tempo Traces Loki Logs INGEST TRANSFORM DELIVER
خط أنابيب المُجمِّع: المصادر تُغذي المُستقبِلات، والمُعالِجات تُثري البيانات وتصفّيها أثناء التدفق، والمُصدِّرات تُوصل البيانات إلى backends متعددة في آنٍ واحد.

تهيئة مُجمِّع متكاملة للإنتاج

فيما يلي ملف otelcol-config.yaml واقعي ستنشره كـ DaemonSet أو sidecar في Kubernetes. يغطي أهم المُعالِجات وإعداد تصدير متعدد الـ backends.

# otelcol-config.yaml — خط الأساس للإنتاج extensions: health_check: endpoint: 0.0.0.0:13133 pprof: endpoint: 0.0.0.0:1777 zpages: endpoint: 0.0.0.0:55679 receivers: otlp: protocols: grpc: endpoint: 0.0.0.0:4317 http: endpoint: 0.0.0.0:4318 # رصد مقاييس المُجمِّع الداخلية prometheus: config: scrape_configs: - job_name: otel-collector scrape_interval: 15s static_configs: - targets: [0.0.0.0:8888] processors: # مهم جداً: يجب أن يكون أولاً — يمنع OOM عند ازدحام الطابور memory_limiter: check_interval: 1s limit_percentage: 75 spike_limit_percentage: 15 # تجميع للإنتاجية؛ 512KB / مهلة 5 ثوانٍ batch: send_batch_size: 8192 timeout: 5s send_batch_max_size: 16384 # إرفاق بيانات Kubernetes من الـ downward API k8sattributes: auth_type: serviceAccount passthrough: false extract: metadata: [k8s.pod.name, k8s.namespace.name, k8s.node.name, k8s.deployment.name, k8s.container.name] labels: - tag_name: app.version key: app.kubernetes.io/version from: pod # حذف ضجيج فحوصات الصحة والجاهزية filter/drop_health: traces: span: - 'attributes["http.route"] == "/healthz"' - 'attributes["http.route"] == "/readyz"' # حذف PII من سمات الامتدادات قبل مغادرتها الكلاستر attributes/scrub_pii: actions: - key: user.email action: delete - key: http.request.header.authorization action: delete # تطبيع سمات الموارد لتحقيق اتساق لوحات المعلومات resource: attributes: - key: cloud.provider value: aws action: insert exporters: # التتبعات -> Grafana Tempo عبر OTLP otlp/tempo: endpoint: tempo.monitoring.svc.cluster.local:4317 tls: insecure: false ca_file: /var/run/secrets/tls/ca.crt retry_on_failure: enabled: true initial_interval: 5s max_interval: 30s max_elapsed_time: 300s # المقاييس -> Prometheus remote-write prometheusremotewrite: endpoint: http://prometheus.monitoring.svc.cluster.local:9090/api/v1/write tls: insecure: true # السجلات -> Loki loki: endpoint: http://loki.monitoring.svc.cluster.local:3100/loki/api/v1/push default_labels_enabled: exporter: false job: true # للتطوير فقط — لا تُفعّله في الإنتاج على مستوى INFO debug: verbosity: basic service: extensions: [health_check, pprof, zpages] pipelines: traces: receivers: [otlp] processors: [memory_limiter, k8sattributes, filter/drop_health, attributes/scrub_pii, batch] exporters: [otlp/tempo] metrics: receivers: [otlp, prometheus] processors: [memory_limiter, k8sattributes, resource, batch] exporters: [prometheusremotewrite] logs: receivers: [otlp] processors: [memory_limiter, k8sattributes, attributes/scrub_pii, batch] exporters: [loki]
ضع memory_limiter دائماً في أول كل خط أنابيب. إذا اجتاحت موجة مرور كبيرة الطابور الداخلي للمُجمِّع، سيُعيق المُصدِّر وسيُسقط البيانات في نهاية المطاف. بدون memory_limiter، تقتل العملية نفسها بسبب نفاد الذاكرة وتُسقط كل ما في طابورها. بوجوده، يرفض المُجمِّع البيانات الجديدة بشكل لطيف (يُعيد خطأً قابلاً للإعادة إلى SDK) قبل نفاد الذاكرة. إغفال هذا المُعالِج هو أكثر أخطاء تهيئة مُجمِّع الإنتاج شيوعاً.

أنماط النشر

طريقة نشر المُجمِّع تُحدد خصائصه التشغيلية. ثلاثة أنماط تسود في بيئات الإنتاج:

  • DaemonSet (وضع الوكيل) — pod واحد للمُجمِّع لكل node. يستقبل كل pod بيانات القياس من جميع التطبيقات على تلك الـ node. مسافات شبكة قصيرة، يمكنه إثراء الامتدادات ببيانات وصفية على مستوى الـ node، ويتحمل إعادة تشغيل المُجمِّع مع تأثير محدود. هو الخيار الافتراضي الموصى به في Kubernetes، ويُدار بواسطة مُشغِّل OpenTelemetry عبر CRD باسم OpenTelemetryCollector مع mode: daemonset.
  • وضع Sidecar — حاوية مُجمِّع واحدة لكل pod تطبيق. أقصى عزل؛ مثالي لكلاسترات متعددة المستأجرين حيث لا يجب أن تشترك الفرق في خط أنابيب واحد. تكلفة موارد أعلى. استخدمه للأعباء الحساسة أمنياً أو عند الحاجة إلى سياسات أخذ عينات لكل خدمة.
  • وضع البوابة (Deployment) — أسطول مُجمِّع مركزي وقابل للتوسع أفقياً. تُعيد جميع مُجمِّعات مستوى الـ node إرسال بياناتها إليه عبر OTLP. تُطبِّق البوابة أخذ العينات على مستوى الكلاستر وحذف PII والتشعب إلى backends متعددة. تتيح استخدام مُعالِجات ذات حالة كـ tail_sampling التي تحتاج لرؤية جميع امتدادات التتبع قبل اتخاذ قرار الأخذ. في الكلاسترات الكبيرة (100 node أو أكثر)، هذا التوبولوجي ثنائي المستوى — وكيل + بوابة — هو المعيار.
توبولوجي مُجمِّع ثنائي المستوى: وكلاء DaemonSet يُعيدون الإرسال إلى بوابة مركزية K8s Node 1 App Pod OTel SDK App Pod OTel SDK Collector Agent DaemonSet K8s Node 2 App Pod OTel SDK App Pod OTel SDK Collector Agent DaemonSet OTLP Gateway Collector Deployment tail_sampling · PII scrub Prometheus Metrics Tempo Traces Loki Logs
التوبولوجي ثنائي المستوى: وكلاء DaemonSet خفيفة الوزن تجمع على مستوى الـ node، والبوابة المركزية تُطبق أخذ العينات على مستوى الكلاستر وحذف PII قبل التشعب إلى backends.

أهم المُعالِجات التي يجب معرفتها

إلى جانب الأساسيات، ثلاثة مُعالِجات تُعرِّف خطوط الأنابيب ذات الجودة الإنتاجية:

  • k8sattributes — يُثري تلقائياً كل امتداد وسجل بـ k8s.pod.name وk8s.namespace.name وk8s.deployment.name وتسميات مثل app.version. يتطلب ClusterRole بصلاحيات get/list/watch على الـ pods. بدونه، ربط تتبع Tempo بعبء Kubernetes الذي أنتجه يستلزم مراجعة متقاطعة يدوية مُضنية.
  • tail_sampling — يتخذ قرارات أخذ العينات بعد رؤية التتبع كاملاً (على عكس الأخذ القائم على الرأس الذي يقرر عند أول امتداد). أنواع السياسات تشمل: latency (احتفظ بأي تتبع يتجاوز 200ms)، وerror (احتفظ بجميع التتبعات التي تحتوي على امتداد خطأ واحد على الأقل)، وprobabilistic (احتفظ بـ 1% من التتبعات السريعة السليمة). يجب أن يعمل في وضع البوابة حتى يتمكن المُجمِّع من تخزين جميع امتدادات التتبع قبل اتخاذ القرار. هذا أكثر المُعالِجات قوةً تشغيلياً.
  • spanmetrics (connector وليس processor) — يشتق مقاييس RED (المعدل، ومعدل الخطأ، ومدرج تكراري للمدة) مباشرةً من امتدادات التتبع دون أدوات قياس إضافية في التطبيق. يُصدر traces_spanmetrics_calls_total وtraces_spanmetrics_duration_milliseconds. هكذا تحصل الفرق الكبيرة على مقاييس مستوى الخدمة مجاناً من خط أنابيب التتبع.
تحقق من تهيئة المُجمِّع قبل النشر. شغّل otelcol validate --config otelcol-config.yaml محلياً أو في CI. سيخرج المُجمِّع برسالة خطأ واضحة في حالة الأخطاء الإملائية أو أسماء المكونات غير المعروفة أو أخطاء توصيل خط الأنابيب. إضافة هذه الخطوة إلى CI يمنع طرح خط أنابيب معطوب إلى الإنتاج — المُجمِّع المُهيَّأ بشكل خاطئ يُسقط جميع بيانات القياس بصمت، وقد لا تكتشف ذلك إلا أثناء حادثة حين تبحث عن التتبعات.
# تثبيت ثنائي otelcol محلياً (macOS / Linux) brew install opentelemetry-collector # macOS # أو التنزيل من https://github.com/open-telemetry/opentelemetry-collector-releases # التحقق من صحة بناء جملة التهيئة وأسماء المكونات otelcol validate --config otelcol-config.yaml # التشغيل محلياً مع مخرجات debug للتطوير otelcol --config otelcol-config.yaml # Kubernetes: النشر عبر CRD الخاص بـ OTel Operator kubectl apply -f - <<EOF apiVersion: opentelemetry.io/v1alpha1 kind: OpenTelemetryCollector metadata: name: otel-agent namespace: monitoring spec: mode: daemonset config: | receivers: otlp: protocols: grpc: endpoint: 0.0.0.0:4317 processors: memory_limiter: limit_percentage: 75 spike_limit_percentage: 15 check_interval: 1s batch: timeout: 5s exporters: otlp: endpoint: otel-gateway.monitoring.svc.cluster.local:4317 tls: insecure: true service: pipelines: traces: receivers: [otlp] processors: [memory_limiter, batch] exporters: [otlp] EOF # فحص صحة المُجمِّع curl -s http://localhost:13133/ # {"status":"Server available","upSince":"..."} # مراقبة مقاييس المُجمِّع الداخلية (scrape على المنفذ :8888) curl -s http://localhost:8888/metrics | grep otelcol_exporter_sent_spans

مُجمِّع OpenTelemetry خادع في بساطته — ثنائي واحد وملف YAML — وبالغ القوة عند تشغيله على نطاق واسع. إتقان سلسلة المُعالِجات وتوبولوجي النشر هو مهارة DevOps جوهرية: هو الفارق بين منظومة مراقبة تتدهور تحت الحمل وأخرى تظل المصدر الأخير الموثوق للحقيقة في اللحظة التي تحتاجها فيها أشد ما يكون.