OpenTelemetry Tail Sampling: قلل تكلفة الـ Traces بذكاء
هتعرف هنا إزاي تقلل تكلفة الـ traces من غير ما تعمي نفسك عن الأخطاء والطلبات البطيئة. ركز: الهدف مش إنك تجمع بيانات أقل وخلاص، الهدف إنك تجمع البيانات اللي تساعدك وقت العطل.
مستوى القارئ: متوسط
المشكلة باختصار
لو عندك 10 خدمات بتستقبل 1 مليون request يوميًا، وجمعت trace كامل لكل request، هتلاقي الـ observability backend بيكبر بسرعة. المشكلة إن 95% من الطلبات غالبًا ناجحة وسريعة، لكنك بتدفع تخزين ومعالجة عليها كأنها مهمة بنفس درجة طلب فشل في الدفع أو checkout أخذ 8 ثواني.
الطريقة الشائعة الغلط هي إنك تعمل head sampling بنسبة ثابتة، مثل 10% من أول لحظة. الطريقة دي بتفشل في نقطة مهمة: ممكن ترمي request فشل قبل ما تعرف إنه فشل. Tail Sampling يحل النقطة دي لأنه يقرر بعد ما الـ trace يكتمل.
الفكرة الأساسية: القرار بعد اكتمال الـ Trace
في OpenTelemetry، الـ sampling هو آلية لتقليل كمية traces التي يتم إنشاؤها أو إرسالها للـ backend. التوثيق الرسمي يشرح أن head sampling يحصل بدري جدًا، بينما sampling المتأخر ممكن يحصل داخل الـ Collector. هذا مهم لأن Collector يقدر يشوف الصورة كاملة: هل في span عليها ERROR؟ هل الـ latency عدى threshold؟ هل service.criticality تساوي critical؟
مثال بسيط: عندك مطعم توصيل. مش محتاج تسجل فيديو كامل لكل طلب وصل في 12 دقيقة بدون مشاكل. لكن لو طلب اتأخر 55 دقيقة أو فشل الدفع، هنا محتاج التفاصيل. Tail Sampling بيعمل نفس الفكرة للـ distributed tracing.
إعداد عملي بـ OpenTelemetry Collector
الافتراض إنك تستخدم OpenTelemetry Collector contrib، وعندك OTLP receiver، والـ backend بتاعك يستقبل OTLP. المثال التالي يحتفظ بكل traces التي فيها ERROR، وكل traces أبطأ من 2 ثانية، ويأخذ 10% فقط من الطلبات العادية. الرقم تقديري كبداية، مش قانون ثابت.
receivers:
otlp:
protocols:
grpc:
http:
processors:
memory_limiter:
check_interval: 1s
limit_mib: 512
spike_limit_mib: 128
tail_sampling:
decision_wait: 10s
num_traces: 50000
expected_new_traces_per_sec: 500
policies:
- name: keep-errors
type: status_code
status_code:
status_codes: [ERROR]
- name: keep-slow-requests
type: latency
latency:
threshold_ms: 2000
- name: sample-normal-traffic
type: probabilistic
probabilistic:
sampling_percentage: 10
batch:
timeout: 5s
send_batch_size: 8192
exporters:
otlp:
endpoint: tempo.example.com:4317
tls:
insecure: false
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, tail_sampling, batch]
exporters: [otlp]