
متعقب استدعاءات النظام الحديث المبني على eBPF. فكر في strace، ولكن مع واجهة مستخدم نصية حقيقية، وفلاتر ذكية، وفك تشفير TLS، ومخرجات قابلة للقراءة بالفعل.
متعقّع استدعاءات النظام للينكس، مبني على eBPF. مثل strace لكن مع واجهة TUI حية، مرشحات ذكية، وفك تشفير وسيطات يمكنك قراءتها فعلاً.

$ sudo snoop curl https://example.com
[ 0.001] curl(1234/1234) openat(AT_FDCWD, "/etc/ssl/certs/ca-certificates.crt", O_RDONLY) = 4 <0.031ms>
[ 0.002] curl(1234/1234) read(4, 0x7f3a1c000b20, 4096) = 4096 <0.012ms>
[ 0.003] curl(1234/1234) socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 5 <0.008ms>
[ 0.004] curl(1234/1234) connect(5, 93.184.216.34:443) = 0 <42.187ms>
[ 0.046] curl(1234/1234) sendto(5, 0x55a3bc001b40, 78, MSG_NOSIGNAL) = 78 <0.011ms>
أو شغّله بدون --raw لتحصل على واجهة TUI بملء الشاشة:
snoop pid:1234 comm:curl events:142 elapsed:0.341s
┌── syscall stream ─────────────────────────────────────┐┌── top syscalls ─────────┐
│ [ 0.001] curl openat("/etc/ssl/…") = 4 <0.031ms> ││ syscall count pct│
│ [ 0.002] curl read(4, …) = 4096 ││ read 38 26.8%│
│ [ 0.003] curl socket(AF_INET, …) = 5 ││ write 21 14.8%│
│ [ 0.004] curl connect(5, 93.184.216.34:443) = 0 ││ openat 18 12.7%│
│ [ 0.046] curl sendto(5, …) = 78 ││ mmap 14 9.9%│
└───────────────────────────────────────────────────────┘└─────────────────────────┘
[q]uit [Space]pause [/]search [f]iles [n]et [c]lear [↑↓]scroll [G]bottom
يستخدم strace أسلوب ptrace، مما يوقف عملية التشغيل عند كل استدعاء نظام. يستخدم snoop نقاط تتبع eBPF بدلاً من ذلك — تستمر عمليتك في العمل بكامل سرعتها بينما يتم التتبع داخل النواة. بالإضافة إلى الأداء، يقوم snoop بفك تشفير الوسيطات إلى شيء يمكنك قراءته فعلاً، ويحتوي على واجهة TUI بلحظة واقعية، ويمكنه حفظ/إعادة تشغيل/مقارنة التتبعات.
--raw (متوافق مع strace)، --json (سطور JSON لـ jq)، --explain (يجمع استدعاءات النظام في ملخصات نشاط عالية المستوى)--files، --net، --slow 10، --syscall openat-p PID) أو التوليد (snoop <cmd>)--follow يتتبع العمليات الفرعية أيضاً--docker <name> و --pod <name> يتتبع كل شيء داخل حاويةلا وحدات نواة، ولا سلسلة أدوات C. برامج eBPF هي كود Rust خالص (aya) ومضمنة في الملف الثنائي.
CAP_BPF + CAP_PERFMONcurl -L https://github.com/pandaadir05/snoop/releases/latest/download/snoop-x86_64-linux.tar.gz \
| tar -xz
sudo install -m755 snoop /usr/local/bin/snoop
بالنسبة لـ aarch64، استبدل x86_64 بـ aarch64.
cargo install --git https://github.com/pandaadir05/snoop snoop
يبني هذا برامج eBPF تلقائياً. لا حاجة لسلسلة أدوات C أو رؤوس النواة، فقط Rust.
# تتبع أمر
sudo snoop ls /etc
sudo snoop -- nginx -g 'daemon off;'
# التعلّق بعملية قيد التشغيل
sudo snoop -p $(pidof postgres)
sudo snoop -p 1234 --follow # تتبع العمليات الفرعية أيضاً
# الحاويات
sudo snoop --docker my-nginx
sudo snoop --pod my-app-pod --namespace production
# التصفية
sudo snoop -p 1234 --files # استدعاءات نظام الملفات فقط
sudo snoop -p 1234 --net # استدعاءات الشبكة فقط
sudo snoop -p 1234 --slow 5 # الاستدعاءات التي تستغرق أكثر من 5 مللي ثانية فقط
sudo snoop -p 1234 --syscall openat --syscall read
--explain يجمع استدعاءات النظام الخام في ملخصات عالية المستوى بدلاً من عرض كل استدعاء على حدة:
sudo snoop -p 1234 --explain
READ /etc/passwd ↓1.2 KB (2 calls, 0.80ms)
NET 127.0.0.1:5432 ↑512 B ↓4.0 KB (18.20ms)
EXEC /usr/bin/python3
يخطّف SSL_write/SSL_read في OpenSSL لالتقاط النصوص الصريحة:
sudo snoop -p 1234 --tls
sudo snoop -p 1234 --ltrace
سجّل تتبعاً، ثم أعد تشغيله لاحقاً دون صلاحية الجذر:
sudo snoop record -p 1234 -o trace.snoop
snoop view trace.snoop
snoop view trace.snoop --files --slow 5 --json | jq 'select(.name=="read")'
مفيد لاكتشاف الانحدارات بعد النشر:
sudo snoop record -p 1234 -o before.snoop
# ... نشر التغيير ...
sudo snoop record -p 1234 -o after.snoop
snoop diff before.snoop after.snoop
SYSCALL COUNTS
read 1200 → 1800 (+50.0%) ▲
openat 340 → 210 (-38.2%) ▼
DURATION REGRESSIONS (median)
read 0.02ms → 0.08ms (+300%)
ONLY IN after
statx (4x)
sudo snoop -p 1234 --json | jq 'select(.name == "connect")'
sudo snoop -p 1234 --flamegraph syscalls.svg
-p, --pid <PID> التعلّق بعملية قيد التشغيل
--follow تتبع العمليات الفرعية (يتطلب --pid)
--docker <NAME|ID> تتبع جميع العمليات في حاوية Docker
--pod <POD> تتبع جميع العمليات في بود Kubernetes
-n, --namespace <NS> مساحة أسماء Kubernetes (الافتراضي: default)
--raw إخراج سطري متوافق مع strace
--json سطور JSON - كائن واحد لكل استدعاء نظام
--explain ملخصات نشاط دلالية
--files استدعاءات نظام الملفات فقط
--net استدعاءات الشبكة فقط
--slow <MILLIS> الاستدعاءات التي تستغرق أكثر من الحد فقط
--syscall <NAME> استدعاء نظام واحد فقط (قابل للتكرار)
--no-decode وسيطات سداسية عشرية خام، بدون فك تشفير
--tls التقاط نصوص TLS الصريحة عبر uprobes لـ SSL_write/SSL_read
--ltrace تتبع malloc/free/calloc/realloc
--flamegraph <PATH> كتابة SVG flamegraph عند الخروج
--ebpf-obj <PATH> تجاوز كائن eBPF المضمن [$SNOOP_EBPF_OBJ]
برنامجان من eBPF يتصلان بـ raw_syscalls/sys_enter و sys_exit. عند الدخول، يُدخل رقم استدعاء النظام والوسيطات في خريطة مسودة خاصة بالخيط. عند الخروج، يُقرن قيمة الإرجاع ببيانات الدخول ويدفع إلى عازلة حلقة. يفرغ مساحة المستخدم العازلة الحلقية عبر واصف ملف غير متزامن ويمرر كل شيء عبر خط أنابيب التصفية/فك التشفير.
kernel userspace
────── ─────────
raw_syscalls/sys_enter ──► SYSCALL_ENTER map (per-tid scratch)
raw_syscalls/sys_exit ──► EVENTS ring buffer (4 MiB)
│
poll consumer (tokio::spawn)
│
┌──────────┴──────────┐
RawOutput TuiApp
(one line/syscall) (ratatui TUI)
برامج eBPF مكتوبة بلغة Rust مع aya، وتُجمع إلى bytecode BPF في وقت البناء، ومضمنة في الملف الثنائي. لا تبعيات وقت التشغيل، ولا رؤوس نواة.
git clone https://github.com/pandaadir05/snoop
cd snoop
# الليلة مطلوبة فقط لهدف BPF
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
# bpf-linker يربط كائن eBPF (لا حاجة لـ LLVM النظام)
cargo install bpf-linker --no-default-features
cargo build --release
sudo ./target/release/snoop -p $$
يقوم سكريبت البناء بتجميع برامج eBPF تلقائياً. لا حاجة لخطوة منفصلة.
أثناء التطوير يمكنك أيضاً استخدام xtask:
cargo xtask run -- -p $$
MIT أو Apache-2.0، حسب اختيارك.
--tls يخطّف SSL_write/SSL_read عبر uprobes لعرض النصوص الصريحة--ltrace يتتبع malloc/free/calloc/reallocsnoop record يحفظ على القرص، snoop view يعيد التشغيل دون اتصال (لا حاجة للصلاحية الجذرية)snoop diff before.snoop after.snoop يُظهر ما تغير بين تشغيلتين--flamegraph out.svg| المفتاح | الوظيفة |
|---|
q | الخروج |
Space | إيقاف مؤقت / استئناف |
/ | بحث تزايدي |
f | تشغيل/إيقاف مرشح نظام الملفات |
n | تشغيل/إيقاف مرشح الشبكة |
c | مسح قائمة الأحداث |
Enter | إظهار نافذة تفاصيل للحدث المحدد |
↑ / k | التمرير لأعلى |
↓ / j | التمرير لأسفل |
G / End | الانتقال لأحدث حدث |
g / Home | الانتقال لأقدم حدث |
| الطبقة | الكريت |
|---|
| برامج eBPF | aya-ebpf |
| مُحمّل eBPF | aya |
| TUI | ratatui + crossterm |
| CLI | clap (derive) |
| وقت تشغيل غير متزامن | tokio |
| Flamegraph | inferno |