تتبع باستخدام OpenTelemetry و Jaeger

التتبع، وهو مكون حاسم، يتعقب الطلبات عبر الأنظمة المعقدة. توفر هذه الرؤية الكشف عن الاختناقات والأخطاء، مما يتيح حلولًا أسرع. في منشور سابق من سلسلة خدمات الويب الخاصة بنا باستخدام Go، استكشفنا أهمية قابلية الملاحظة. اليوم، نركز على التتبع. يقوم Jaeger بجمع وتخزين وتصور التتبعات من الأنظمة الموزعة. يوفر رؤى حاسمة في تدفقات الطلبات عبر الخدمات. من خلال دمج Jaeger مع OpenTelemetry، يمكن للمطورين توحيد نهج التتبع الخاص بهم، مما يضمن رؤية متسقة وشاملة. يبسط هذا التكامل تشخيص مشاكل الأداء ويعزز موثوقية النظام. في هذا المنشور، سنقوم بإعداد Jaeger، ودمجه مع OpenTelemetry في تطبيقنا، واستكشاف تصور التتبعات للحصول على رؤى أعمق.

الدافع

ما نسعى إليه هو لوحة تحكم Jaeger تبدو كما يلي:

عندما ننتقل إلى أجزاء مختلفة من التطبيق (على واجهة Onehub الأمامية)، يتم جمع تتبعات الطلبات المختلفة (من نقطة الوصول إلى بوابة grpc) مع ملخص لكل منها. يمكننا حتى التعمق في أحد التتبعات للحصول على عرض أكثر تفصيلاً. انظر إلى أول طلب POST (لإنشاء/إرسال رسالة في موضوع):

هنا نرى جميع المكونات التي يمسها طلب Create مع أوقات الدخول/الخروج والوقت المستغرق داخل وخارج الطرق. قوي جدًا بالفعل.

البدء

ملخص سريع: لرؤية هذا قيد التنفيذ والتحقق من صحة بقية المدونة:

  1. مصدر هذا هو في تفريق PART11_TRACING.
  2. بناء جميع الأشياء المطلوبة (بمجرد تحميل الفرع):
make build

  1. لقد قمنا بتفكيك docker-compose إلى قسمين (سيتم تفسير ذلك أعلاه), لذا تأكد من أن لديك نافذتان في جريدة.
  • ترميل 1: make updb dblogs
  • ترميل 2: make up logs
  1. توجه إلى localhost:7080 وتفتح.

تأمين عنصر عالي

إن نظامنا يعمل حاليًا:

مع تقنية قياس بواسطة OpenTelemetry، سيتطور نظامنا إلى:

وكما لاحظنا من قبل، فإنه من الصعب جدًا على كل خدمة لإستخدام متصفحات منفصلة لإرسالها لموردين معينين. بدلاً من ذلك، باستخدام مجموع ل OpenTelemetry يعمل بصورة منعزلة، يمكننا أن نضمن أن جميع الخدمات (المهتمة) يمكن أن ترسل المعاملات/الأسطر الأخبارية/التتبعات إلى هذا المجموع، ويمكنه بعدها تصديرها إلى الخلايا الخارجية المطلوبة — في هذه الحالة، Jaeger للتتبعات.

دعونا نبدأ.

إنشاء مجموع OpenTelemetry

الخطوة الأولى هي إضافة مجموع تشغيل OpenTelemetry في البيئة الدوكر مع Jaeger حتى يكونوا قابلين للوصول.

ملاحظة: قمنا بتفكيك ملف docker-compose.yml الأساسي إلى قسمين:

  1. db-docker-compose.yml: يحتوي على جميع المكونات الخارجية والبنية التحتية (غير التطبيقات) مثل البases بيانات (Postgres، Typesense) وخدمات
  2. docker-compose.yml: يحتوي على جميع خدمات تطبيقات ذات الصلة (Nginx، بوابة gRPC، dbsync، واجهة المستخدم، إلخ.)

تتصل البيئتان docker-compose بشبكة مشتركة (onehubnetwork) يمكن من خلالها أن تتواصل الخدمات في هذه البيئات مع بعضها البعض. مع هذا الفصل، نحتاج فقط إلى إعادة تشغيل جزء من الخدمات عند حدوث تغييرات مما يسرع عملية التطوير.

العودة إلى إعداداتنا: في db-docker-compose.yml، أضف الخدمات التالية:

YAML

 

سهل بما فيه الكفاية، هذا يعد الخدمات التالية في بيئة Docker:

  1. otel-collector: المستقبل لجميع الإشارات (القياسات/السجلات/الآثار) التي ترسلها الخدمات المختلفة المراقبة (سنواصل إضافة إلى هذه القائمة عبر الزمن)، يستخدم صورة OTel القياسية مع تكوين OTel المخصص لدينا (أدناه) الذي يصف خطوط الأنابيب المختلفة للرصد (أي، كيفية استقبال الإشارات ومعالجتها وتصديرها بطرق مختلفة).
  2. jaeger: مثيل Jaeger الخاص بنا الذي سيستقبل ويخزن الآثار (تصديرها من قبل otel-collector)، يستضيف كلا من التخزين ولوحة القيادة (واجهة المستخدم) التي سنصدرها على مسار بادئة HTTP /jaeger ليكون متاحًا من خلال nginx.
  3. prometheus: على الرغم من أنه غير مطلوب لهذا المنشور، سنصدر أيضًا القياسات حتى يتمكن Prometheus من جمعها. لن نناقش هذا بالتفصيل في هذا المنشور.

يجب ملاحظة بعض الأمور:

  • على الرغم من أنه غير مطلوب لهذا المنشور، نحن نمرر تفاصيل الاتصال POSTGRES (كمتغيرات بيئية) إلى otel-collector حتى يتمكن من جمع قياسات حالة Postgres.
  • يدعم Jaeger (منذ v1.35) OTLP بشكل بنيادي.
  • جمالية OTLP هي أنه يمكن توصيل المجموعات OTel لتشكيل شبكة من المجموعات / معالجات / متوجهين / مرشحين وهلم جرا.
  • يمكن تقديم OTLP عبر نقطة بدء GRPC أو نقطة بدء HTTP (على أنحاء 4317 و 4318 من الأوعية بالمرة).
  • بشكل تلقائي، يتم بدء خدمات OTLP على localhost:4317/4318. هذا جيد إذا كان Jaeger يجري في نفس المضيف / البوت الذي يشتغل فيه الخدمات المراقبة. ومع ذلك، لأن Jaeger يجري في بوت منعزل، يتوجب أن يتم تعليقه بعناوين خارجية (0.0.0.0). لم يكن هذا واضحا في المستندات وأدى إلى تأثير كبير من التشتت.
  • COLLECTOR_OTLP_ENABLED: true هو الافتراضي الآن ولا يتوجب أن يكون معروف بوضوح.

إعدادات OTel

يتوجب أيضًا تكوين OTel مع مُستقبلات ومعالجات ومصدرين واحدين. سنقوم بذلك في configs/otel-collector.yaml.

إضافة مُستقبلات

يتوجب علينا أن نخبر المجموع المتوجه أي مُستقبلات يجب تفعيلها. يتم تعريف هذا في القسم receivers:

YAML

 

يمكن تفعيل مُستقبل لـOTLP على الممرات 4317 و 4318 (grpc, http بالتقليد). وهناك أنواع من المُستقبلات التي يمكن بدءها. على سبيل المثال أضفنا أيضًا مُستقبل “postgresql” الذي يستخدم للتقاط المباشر للمؤشرات في Postgres (وهذا ليس من المهم لهذه المقالة). يمكن أيضًا أن تكون المُستقبلات قائمة على التنقل المتواجد أو التنقل المبذول. يقوم مُستقبلات التنقل المتواجد بالتقاط مرة في كل فترة لأهداف معينة (مثل postgres ، على سبيل المثال) ، بينما يتم بالإستمرار إسماع واستقبال المؤشرات/الملاحظات/التتبعات من التطبيقات باستخدام SDK المستخدم الخاص بOTel.

هذا كل شيء. حاليًا يستعد مجموعتنا للاستقبال (أو التقاط) للمؤشرات المناسبة.

إضافة معالجات

المعالجات في OTel هي طريقة لتحويل ، توجيه ، تجميع ، تصفية و/أو تجديد الإشارات التي يتم استقبالها قبل التصديرها. على سبيل المثال يمكن للمعالجات أن تقوم بعمل عينة على المؤشرات ، تصفية الملاحظات أو تجميع الإشارات للكفاءة. بالإفتراض لا يتم إضافة معالجات (جعل المجموعة مرورية). سنتخلص من هذا لحالة.

إضافة مصدريات

الآن حان الوقت لتحديد المكان الذي نريد أن يتم تصدير الإشارات إليه: الأنظمة الخلفية الأنسب للإشارات المعنية. تمامًا مثل المستقبِلين، يمكن أن يكون المصدِّرين أيضًا يعتمدون على السحب أو الدفع. تُستخدم المصدِّرات المعتمدة على الدفع لإرسال الإشارات إلى مستقبِل آخر يعمل في وضع الدفع. هذه تكون صادرة. المصدِّرات المعتمدة على السحب تعرض نقاط النهاية التي يمكن استخلاصها بواسطة مستقبِلين آخرين يعتمدون على السحب (مثل prometheus). سنضيف مصدِّرًا من كل نوع: واحد للتتبع وواحد لـ Prometheus للاستخلاص من (على الرغم من أن Prometheus ليس موضوع هذا المنشور):

YAML

 

هنا لدينا مصدِّر إلى Jaeger يقوم بتشغيل جامع OTLP، كما هو موضح بواسطة otlp/jaeger. هذا المصدِّر سيدفع التتبعات بانتظام إلى Jaeger. نحن أيضًا نضيف نقطة نهاية “scraper” على المنفذ 9090 والتي سيقوم Prometheus بالاستخلاص منها بانتظام.

يُستخدم المصدِّر “debug” ببساطة لتفريغ الإشارات إلى تيارات الإخراج/الخطأ القياسية.

تحديد الأنابيب

أقسام المستقبِل، المعالج، والمصدِّر ببساطة تحدد الوحدات التي سيتم تفعيلها بواسطة الجامع. لم يتم استدعائهم بعد. لتفعيلهم فعليًا، يجب الإشارة إليهم كـ “أنابيب”. الأنابيب تحدد كيف تتدفق الإشارات ويتم معالجتها بواسطة الجامع. تعاريف الأنابيب الخاصة بنا (في قسم services) ستوضح ذلك:

YAML

 

هنا نحن نحدد أنبوبين. لاحظ مدى تشابه الأنابيب ولكنها تسمح بوضعين مختلفين للتصدير (Jaeger و Prometheus). الآن نرى قوة OTel في إنشاء الأنابيب داخله.

  1. traces:

  • استقبال الإشارات من واجهات برمجة التطبيقات العميلة
  • بدون معالجة
  • تصدير المعطيات الى الكونزول و Jaeger
  1. ميتركس:
  • تلقي الإشارات من أجهزة المستخدمين الخاصة بنا
  • بدون معالجة
  • تصدير المعطيات الى الكونزول و Prometheus (من خلال تعريف نقطة انتهاء للتسجيل فيها).

تعريف الوحات من خلال Nginx

يقدم Jaeger وحة لتعريف بيانات المعطيات حول جميع موافقاتنا. يمكن رؤيتها في المتصفح بتفعيل التالي في 配置 Nginxمناهجنحن نقدم أيضًا وحدة إبداء الوحات Prometheus من خلال nginx في المسار الHTTP السابق /prometheus.

YAML

 

تعريف المعطيات في Jaeger

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

تحليل الجداول الزمنية للمعطيات في المعاملات المختلفة لتفهم التسلسل المتوالي للعمليات. كل مربع يمثل وحدة عمل ويظهر أوقات البدء والنهاية، المدة والمعلومات المرتبطة. هذه المنظورة التفصيلية مفيدة جدًا في تحديد القنابل الأخيرة للأداء والأخطاء في المعطيات.

توافير المعاملات الخاصة بالمستخدمين وإدماجها.

حتى الآن أنشأنا أنظمتنا لتجسير وتستهلك الإشارات وما إلى ذلك. ومع ذلك لم يتم تحديث خدماتنا بشكل كافي لتبعث عن الإشارات إلى OTel. سندمج مع متغير (Golang) للSDK في أجزاء متنوعة من برمجياتنا. التوثيق التقني للSDK هو مكان رائع للتأكد من بعض من المفاهيم.

المفاهيم الرئيسية التي سنتعامل بها توضح أدناه.

الموارد

الموارد هي الكائنات التي تنتج الإشارات. في حالتنا ، نطاق مواردنا هو التشغيل التي تضم الخدمات. في الوقت الحالي لدينا موارد واحدة لجميع خدمة Onehub ، ولكن يمكن تقسيمها في المستقبل.

يتم تعريفه في cmd/backend/obs.go. تلاحظ أنه لم يتوجب علينا إكتفاء بذلك بالتفاصيل التعريفية للموارد بواسطة الSDK الزائر. يسمح لنا المساعد القياسي الاستاندارد (sdktrace.WithResource) بإنشاء تعريف للموارد من خلال تخمين الأجزاء الأكثر فائدة (مثل اسم التشغيل، اسم البود الخاص به، إلخ) في الوقت الحالي.

كان علينا تغيير شيء واحد فقط: متغير البيئة OTEL_RESOURCE_ATTRIBUTES: service.name=onehub.backend,service.version=0.0.1 لخدمة onehub في docker-compose.yml.

توسيع البيانات السابقة

توسيع البيانات هو موضوع هام جدا في المراقبة. تكون الأعمدة المختلفة قوية بالفعل عندما يمكننا ترابط الإشارات من كل من الأعمدة لتحديد المشاكل في نظامنا. تخيل البيانات الإضافية كمعلومات قابلة للربط بالإشارات: أي يمكن “الترابط” بطريقة فريدة لتربط الإشارات المختلفة لمجموعة خاصة (قد تكون طلب ما).

المقدمون/المصدرون

لكل من الإشارات، يقدم تقنية من المبيعات (مثل TracerProvider لتصدير البوايات/التتبعات، MeterProvider لتصدير المعاملات، LoggerProvider لتصدير الملاحظات، و هلم هلم). لكل من هذه الواجهات، يمكن وجود عدة تنفيذات، على سبيل المثال، معدل تجاري لإرسال البيانات إلى سرائيل الرسائل العامة/خطأ، معدل تقنية لتصدير البيانات إلى نقطة جهة أخرى في التسلسل (في سلسلة),أو حتى مباشرة من خلال مجموعة متنوعة من المصدرون. ومع ذلك، في حالتنا، نريد تأجيل خيار أي مورد خارج خدماتنا وبعدة إشارات المراقبة إلى مجموعة التصليح المعيشة في بيئتنا.

لتجعيل هذا، سنقوم بإنشاء نوع ” OTELSetup” الذي يستقبل المقدمين المختلفين الذين قد نريد استخدامهم أو تغييرهم. في cmd/backend/obs.go، لدينا:

Go

 

هذا خاتم بسيط يتبع الجوانب الشائعة المطلوبة من قبل متنقل OTel SDK. هنا نحن نحصل على معاملات (ملفات تتبع, مترابع, ومؤشرات) وطرق لتوفير السياق (للتتبع). المورد الرئيسي الذي يستخدمه جميع المعاملات أيضًا يعرف هنا. والوظائف التي تُطلب إلغاءها مثيرة للإعجاب. هي وظائف تطلبها المعاملات عندما يتوقف المصدر الأساسي عن التصدي (بشكل مناسب أو بسبب خروج). الخاتم نفسه يأخذ معه توالي عام ليمكن للمعاملات بالفعل أن تستخدم معاملاتهم الخاصة.

يحتوي المخزون على دوالين تطويرات لهذه:

سنقوم بإنشاء الثاني في تطبيقنا. لن نخوض في تفاصيل التطويرات الخاصة لأنها تم اخذها من ال أمثلة في ال SDK وبعدها تم إصلاحها وتنظيمها بشكل صغير. بالتحديد, ألقو نظرة على مثال otel-collector للإلهام.

تكوين معاملات OTelProviders.

والجوانب الرئيسية لتمكين المجموع في خدماتنا هي أن نوع من البيانات المرتبطة بOTel يتم بدءها في جميع النقاط الدخولية. إذا تم إنشاء هذه البيانات في البداية، فسيتم إرسالها إلى جميع الأهالي هنا، ومن ثم تتم تنسيقها بعد (أن نفعل الشيء الصحيح).

لنأخذ دعوة ListTopics البسيطة (api/vi/topics)، يتم توجيه طلبنا وإعادته بهذه الطريقة:

[ Browser ] ---> [ Nginx ] ---> [ gRPC Gateway ] ---> [ gRPC Service ] ---> [ Database ]

في حالتنا، تلك النقاط الدخولية هنا هي في البداية حين يتلقى مركز gRPC الطلبات من Nginx (يمكننا بدء التتبعات من نقطة تلقاء HTTP الطلب بالنغمة إلى Nginx لإبراز التأخيرات في Nginx، لكننا سوف نتماءل قليلًا).

ما يحتاج هو:

  • يتلقى gRPC Gateway دعوة.
  • ينشئ مثاليًا عنصر context.Context المخصص لOTel.
  • ينشئ علاقة مخصصة بالخدمة الgRPC المتعلقة (على سبيل المثال، TopicService) ويتم تحميل هذا الcontext بدلاً عن الواجهة الافتراضية.
  • يستخدم هذا الcontext من خلال الخدمة حين يتم إنبعاث التتبعات.

دعونا نسلك هذه الخطوات بدقة.

تجهيز وتحضير SDK OTel للاستخدام

في main.go، دعونا نبدأ بتجهيز اتصال المجموع:

Go

 

  • الأعمال 8-16: نقوم بإنشاء اتصال إلى otel-collector الذي يجري في بيئتنا الDocker.
  • الأعمال 17-21: من ثم نقوم بإعداد إعدادات OTel مع مزيد من موفرين التتبعات والمؤشرات بحيث يمكن لمجموعتنا الإرسال جميع التتبعات والمؤشرات (تذكر ما أعدنا مستقبليات في إعدادات OTel مسبقاً).
  • الأعمال 23-25: نضبط محللين لتنظيف إشتباكات OTel / موفرين و الماضي.
  • الأعمال 27: نحن نعدل قاعدتنا البيانات والاتصالات كما قمنا من قبل.
  • الأعمال 29 +: ما زلنا نبدأ خدمات GRPC والبوابة في الخلفية وهذا كل شيء. لم نهتم حقًا بما يلي أو توقع أو توفير تلك الخدمات. لأجسامنا البينري سيخرج عندما يخرج أي من هذه الخدمات.

ولنأخذ مثالًا لكيفية استخدام خدمة البوابة من هذه القناة.

بدلًا من بدء مختبر الHTTP (لبوابة grpc-gateway) كما:

1    http.ListenAndServe(gw_addr, mux)

فإننا الآن نملك:

Go

 

أنظر إلى الأعمال 9-14 حيث يتم مراقبة إيقاف الخدمة في جوروتين من الخلفية و الأعمال 15 حيث إذا كان هناك خطأ حين خروج الخدمة ، سيتم إرساله من خلال القناة “الإخطار” التي تم تقديمها كما تلك التي تم تقديمها لهذه الطريقة.

الآن لدينا وصول للخدمات المختلفة إلى “اتصال فعال” للOTLP الذي يمكن استخدامه في أي وقت سيكون لترسل إشارات.

المتوسط الخاص بOTel للروادبي الرئيسي

في الأعلى، نستخدم مثالية للمؤلف الHTTP http.Server لبدء روادبي الرئيسي الرفعي. يستخدم معالج مخصص: معالج الHTTP http.Handler في حزمة OTel HTTP. يأخذ معالج موجود من النوع http.Handler، يزيده مع السياق الOTel، ويتأكد من توسيعه إلى أي توجيه أخر يتم مناداةه.

Go

 

معالجنا الHTTP بسيط:

  • خط 4: نصنع تجاوز خاص بOTel للتعامل مع معالجات الHTTP.
  • خط 5: نضع الخيار SpanFormatter حتى يتم تحديد التتبعات بشكل فريد من خلال الطريقة ومسارات ال solicitud HTTP. بدون هذا ال SpanNameFormatter، سيكون اسم التتبع بالفعالية ببساطة "gateway" ويتم إنشاء جميع التتبعات بهذا الشكل:

تغليف روادبي الرئيسي لممارسات الرفعي مع OTel

بشكل افتراضي، يقوم مكتبة روادبي الرئيسي بإنشاء “مساحة بسيطة” حين تخلق/تدارك الاتصالات إلى الخدمات الرفعية الأساسية. بعد كل شيء، لا يعرف الرفعي أي شيء عن OTel. في هذه المقامة، سيتم معالجة اتصال (من المستخدم/المتصفح) إلى روادبي الرئيسي والاتصال من خلال الرؤية إلى الخدمة الرفعية كمساحتين مختلفتين من التتبعات.

لذلك يهم أن تزيل مسؤولية إنشاء الاتصالات الرفعية من خلف الرؤ

قبل دمج OTel، كنا نسجل معالج Gateway لـ gRPCs باستخدام:

Go

 

الآن تمرير اتصال مختلف بسيط:

Go

 

ما فعلناه هو أولاً إنشاء client (السطر 6) يعمل كمصنع اتصال لخادم gRPC الخاص بنا. العميل بسيط جداً. يتم استخدام فقط معالج ClientHandler لـ gRPC (otelgrpc.NewClientHandler) لإنشاء الاتصال. هذا يضمن أن سياق التتبع الحالي الذي بدأ بطلب HTTP جديد يتم الآن نشره إلى خادم gRPC عبر هذا المعالج.

هذا كل شيء. الآن يجب أن نبدأ في رؤية الطلب الجديد إلى Gateway وطلب Gateway->gRPC في تتبع موحد واحد بدلاً من اثنين مختلفين.

بداية ونهاية Spans

نحن على وشك الانتهاء. حتى الآن:

  • لقد قمنا بتمكين مجمع OTel وJaeger لاستقبال وتخزين بيانات التتبع (span) (في docker-compose).
  • قمنا بإعداد مجمع OTel الأساسي (يعمل كبود منفصل) كمزود لنا لأدوات التتبع والمقاييس والسجلات (أي أن دمج OTel الخاص بالتطبيق سيستخدم هذا النقطة لوضع جميع الإشارات).
  • لففنا معالج HTTP لـ Gateway ليكون ممكناً من OTel حتى يتم إنشاء التتبع ونشر السياقات.
  • قمنا بتجاوز العميل (gRPC) في البوابة حتى يلف الآن سياق OTel من إعداد OTel الخاص بنا بدلاً من استخدام سياق افتراضي.
  • أنشأنا نسخاً عالمية من أدوات التتبع/القياس/السجل حتى نتمكن من إرسال إشارات فعلية باستخدامها.

الآن يجب علينا إنشاء إطارات لجميع الأماكن ال”مثيرة” في 我们的代码. لأسلوب الListTopics مثال (في services/topics.go):

Go

 

نادلع القاعدة البيانات للمواضيع ونعطيهم. مما يشبه طريقة الوصول إلى القاعدة (في datastore/topicds.go):

Go

 

هنا سنكون مهتمين فقط بكم يمضي في كل من هذه الطرق. نقوم بتوليد الإطارات في كل من هذه ونحن مازلنا. إضافاتنا إلى الخدمة وطريقة الخزانة (بالتقدم) هما:

  • services/topics.go:
Go

 

  • datastore/topicds.go:
Go

 

النموذج العام هو:

1. إنشاء إطار:

ctx, span := Tracer.Start(ctx, "<span name>")

في هذه الحالة يتم “تغليف” الcontext (ctx) ويتم إرجاع معاينة جديدة. يمكننا (ويجب القيام بذلك) بمراجعة هذه المعاينة الجديدة المتلازمة إلى أي مétodos إضافيين. نفعل ذلك عندما نهتمل الطريقة datastore ListTopics .

2. إنهاء الإطار:

defer span.End()

إنهاء إطار (في كل مرة يعود المétodo) يتأكد من تسجيل الأوقات الصحيحة / أو أسماء الكومات وما إلى ذلك. يمكننا أيضًا فعل أشياء أخرى مثل إضافة تغييرات وأولويات إلى هذه إذا كان ذلك ضروريًا لتحميل المزيد من المعلومات لمساعدة على التصحيح.

هذا كل شيء. يمكنك رؤية تتبعاتك الجميلة في Jaeger والحصول على المزيد من المعرفة حول أداء مواقعك من البداية إلى النهاية!

ختام

لقد تمت تغطية الكثير في هذا المنشور ومازالنا نغطي بالكاد جميع التفاصيل وخلف معرفة OTel والتتبع. بدلاً من تحمل هذا المنشور (الذي بالفعل مليء بالمعارف) مع معارف جديدة وتفاصيل معقدة سوف نقدمها في منشورات 未来的. حتى الآن ، أجرب هذا في خدماتك الخاصة وحاول لعب مع ما يزال مجموعة من المصدرين والمستقبلين في المخزون otel-contrib.

Source:
https://dzone.com/articles/tracing-with-opentelemetry-and-jaeger