هذا المقال يتطلب مستوى محترف.
لو في endpoint بياخد 2.4 ثانية، وكل APM tool عندك بيقول إن الـ DB سليمة والـ CPU 30% بس، فالزمن المفقود في المسافة بين الـ kernel والـ application thread. eBPF بيخلّيك تشوف كل syscall وكل network packet بدون ما تضيف سطر واحد في كود تطبيقك، وبأقل من 1% overhead على hot path.
eBPF: المراقبة على مستوى الـ kernel بدون kernel module
المشكلة باختصار
كل أداة تقليدية فيها عيب: strace بيبطّأ التطبيق 50 مرة على hot path. perf بيديك CPU profile بس مش syscalls كاملة بـ context. tcpdump بيمسك الشبكة بس بياكل CPU في حركة عالية. لو محتاج تربط الـ syscall بالـ user أو بالـ DB query من غير ما تعدّل التطبيق، الأدوات دي مش كافية.
تشبيه قبل التعريف العلمي
تخيّل إنك بترعى مصنع فيه 200 ماكينة. الطريقة القديمة: تروح كل ساعة على كل ماكينة وتفتحها وتقيس الحرارة باليد. ده زي strace — بيشتغل بس بيوقّف الإنتاج وقت ما بتقيس. الطريقة الجديدة: تركّب على كل ماكينة sensor صغير لاصق في الفرن، يبعت إشارة في اللحظة اللي الحرارة تعدي حد معين فقط. الـ sensor مش بيوقّف الماكينة، مش بياخد قرار بنفسه، بس بيراقب ويبلّغ لمكان مركزي. ده eBPF بالظبط.
التعريف العلمي الدقيق
eBPF (extended Berkeley Packet Filter) عبارة عن virtual machine مدمجة في Linux kernel من نسخة 4.4 (2015). بتكتب برنامج بـ C محدود جداً (no unbounded loops، no recursion، حد أقصى مليون instruction)، compiler بيحوّله لـ bytecode، وverifier جوّا الـ kernel بيتأكد إنه آمن قبل ما يشغّله — يعني مش هيعمل crash للـ kernel ومش هيدخل في loop لانهائي.
البرنامج بيعلّق على hook معروف: kprobe (دالة جوّا الـ kernel)، uprobe (دالة في user-space)، tracepoint (نقطة معرّفة سلفاً ومستقرّة من الـ kernel)، أو XDP (نقطة على driver الشبكة قبل ما الحزمة تدخل الـ network stack). كل event بيشغّل البرنامج، والنتايج بترجع لـ user space عبر ring buffer أو map.
مثال تنفيذي بـ bpftrace
# عدّ كل openat() syscall لكل process على السيرفر لمدة 30 ثانية
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat { @[comm] = count(); }' \
-c 'sleep 30'
# نتيجة فعلية على سيرفر إنتاج:
# @[systemd-journald]: 142
# @[node]: 388
# @[postgres]: 1947
# @[nginx]: 4821