هذا المقال للمستوى المتوسط — تحتاج تجربة سابقة مع Docker وعلى الأقل خدمتين microservices شغّالة تتكلم مع بعض عبر HTTP أو gRPC.
لو طلب POST /checkout عندك بياخد 4.8 ثانية ومش عارف فين الزمن بيضيع بين 7 خدمات، الـ logs لوحدها مش هتجاوب. OpenTelemetry بيكمل المشهد: trace واحد بيوريك بالظبط أي خدمة كلّفت كم millisecond، ومين كلّم مين، وفين الـ retry حصل.
المشكلة باختصار
في architecture فيه 7 microservices، الـ logs بترجع سطور منفصلة من كل خدمة بدون رابط بينها. تحقيق سبب البطء بياخد ساعتين متوسطًا حسب CNCF Annual Survey 2024. Distributed Tracing بينزّل الزمن ده لـ 3 دقائق، لأنه بيربط كل العمليات تحت معرّف واحد اسمه trace_id ومعرّف فرعي لكل خطوة اسمه span_id.
المثال أولًا: زي مكتب البريد الموحّد
تخيّل إنك بعت طرد من القاهرة لأسوان. الطرد بيمر على 7 محطات. لو ضاع، الـ logs العادية بتقول إن كل محطة كتبت في دفترها الخاص "وصل ومشى". لو حصل تأخير، هتفتح 7 دفاتر وتدوّر يدوي.
OpenTelemetry بيشتغل بفكرة tracking number موحّد: كل محطة بتختم نفس الرقم لمّا الطرد يدخل، وتختمه تاني لمّا يخرج. لو فتحت تطبيق التتبّع بتشوف خط زمني كامل: غادر القاهرة 9:00، وصل بني سويف 10:15، اتأخر في المنيا ساعتين، طلع من أسيوط 14:30. فورًا تعرف فين المشكلة بالظبط من غير ما تكلّم حد.
التعريف العلمي بالظبط
OpenTelemetry هي مواصفة CNCF (وصلت لمرحلة stable في فبراير 2024) لتوليد ونقل ثلاث إشارات: traces و metrics و logs. الـ trace بيتكوّن من spans، وكل span بيمثّل عملية ليها وقت بداية ونهاية، وtrace_id مشترك، وspan_id خاص بيها، وparent_span_id بيربطها بالعملية الأكبر.
الـ context propagation بيتم تلقائيًا عبر W3C Trace Context (توصية W3C الرسمية، نوفمبر 2021) في headers HTTP اسمها traceparent و tracestate. كل خدمة بتستلم الـ header، تنشئ span جديد parent بتاعه هو الـ span اللي قبله، وتبعت الـ header للخدمة اللي بعدها. النتيجة: شجرة كاملة لكل request.
الإعداد الفعلي في Node.js
تثبيت الحزم:
npm install @opentelemetry/api @opentelemetry/sdk-node \
@opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-httpاعمل ملف tracing.js في جذر المشروع: