
sonar v0.4.1
أداة سطر أوامر لفحص وإدارة الخدمات التي تستمع على منافذ localhost
██████ ███ ██████ ██ ██████
██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ████
██ ██ ██ ██ ██ ██ ██ ██
██████ ███ ██ ██ ██ ██ ██ ██
اعرف ما الذي يعمل على جهازك.
يعرض Sonar كل ما يستمع على localhost ويرتّبه: كل منفذ
ينتمي إلى مجموعة — عادةً المستودع الذي بدأ منه — وداخل
تلك المجموعة إلى خدمة مُسمّاة. ابدأ خوادم التطوير الخاصة بك باستخدام
sonar start وسيصبح المشروع بأكمله شيئًا واحدًا يمكنك سرده كشجرة،
والانتظار له، وتتبّع سجلاته، وإيقافه بأمر واحد. كما يتم التقاط حاويات Docker ومشاريع
Compose والعمليات التي بدأتها يدويًا، دون أي
إعداد.
$ sonar list --tree
my-app (3 ports, running) ~/code/my-app
├─ 5432 db postgres:17 http://localhost:5432
├─ 5173 frontend vite (v5.4) http://localhost:5173
└─ 8000 api uvicorn app:app http://localhost:8000
ungrouped (1 port)
└─ 3000 next-server (v16.1.6) http://localhost:3000
التثبيت
Homebrew (macOS / Linux)
brew install raskrebs/sonar/sonar
Homebrew 6 يرفض الصيغ من النقرات الخارجية حتى تثق بالنقرة مرة واحدة
(Error: Refusing to load formula raskrebs/sonar/sonar from untrusted tap):
brew trust raskrebs/sonar
نص التثبيت
curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | bash
يقوم بتنزيل أحدث ملف تنفيذي إلى ~/.local/bin ويضيفه إلى PATH الخاص بك إذا لزم الأمر. أعد تشغيل الطرفية أو نفّذ source ~/.zshrc.
على Windows (PowerShell):
irm https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.ps1 | iex
موقع تثبيت مخصص:
curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | SONAR_INSTALL_DIR=/usr/local/bin bash
تثبيت إصدار محدد:
curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | SONAR_VERSION=vX.Y.Z bash
$env:SONAR_VERSION="vX.Y.Z"; irm https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.ps1 | iex
استخدام Go
go install github.com/raskrebs/sonar@latest
إكمالات الصدفة (إكمال تلقائي لأرقام المنافذ):
sonar completion zsh > "${fpath[1]}/_sonar" # zsh
sonar completion bash > /etc/bash_completion.d/sonar # bash
sonar completion fish | source # fish
ستون ثانية
صف كيفية تشغيل مشروعك في sonar.yaml في جذر المستودع، بدلاً من dev.sh:
name: my-app
services:
- name: db
cmd: docker compose up db
port: 5432
- name: api
cmd: uv run uvicorn app:app --port ${port}
port: auto
depends_on: [db]
- name: frontend
cmd: npm run dev -- --port ${port} --strictPort
port: auto
depends_on: [api]
env:
VITE_API_URL: ${api.url}
ثم شغّله:
sonar start
✓ db http://localhost:5432 pid 41022 ~/.config/sonar/logs/my-app/db.log
✓ api http://localhost:21408 pid 41040 ~/.config/sonar/logs/my-app/api.log
✓ frontend http://localhost:21409 pid 41077 ~/.config/sonar/logs/my-app/frontend.log
3 started
following the logs; Ctrl+C stops the 3 services started here
api | INFO: Uvicorn running on http://127.0.0.1:21408
frontend | VITE v5.4 ready in 312 ms
Sonar يختار منفذًا حرًا لكل خدمة port: auto ويخبر كل خدمة
بأماكن الخدمات الأخرى، بحيث يعمل worktree ثانٍ بجانب الأول دون
تعارض أي منفذ. يفعل sonar start -d الشيء نفسه في الخلفية،
ويوقفه sonar down ويعيد المنافذ. في طرفية أخرى:
sonar list --tree
my-app (3 ports, running) ~/code/my-app
├─ 5432 db postgres:17 http://localhost:5432
├─ 21408 api uvicorn app:app http://localhost:21408
└─ 21409 frontend vite (v5.4) http://localhost:21409
لا يوجد sonar.yaml؟ يقوم sonar start -- npm run dev بتشغيل أمر واحد كخدمة مُسمّاة، ويعمل sonar list و sonar kill على أي شيء يستمع.
الأمثلة أدناه المعلَّمة بـ # check تُنفَّذ مقابل بناء جديد بواسطة
scripts/readme-check.sh في كل تشغيل لـ CI.
الأوامر
sonar list
sonar list
sonar list --tree
sonar list --group my-app
sonar list --json
# check
sonar list --stats # CPU, memory, threads, uptime, state
sonar list --health # HTTP health checks
sonar list --filter docker # only Docker ports
sonar list --sort name # port | pid | name | type
sonar list -a # include desktop apps
sonar list -c port,process,group,cpu,mem
sonar list --host user@server # scan a remote machine over SSH
الأعمدة الافتراضية هي port، process، group، container، image،
containerport، url، حيث يعرض process الاسم الذي أعطيته للمنفذ
(sonar rename)، ثم اسم الخدمة، ثم ما تم اكتشافه.
الأعمدة المتاحة: port، process، pid، type، url، group، cpu،
mem، threads، uptime، state، connections، health، latency،
container، image، containerport، compose، project، user، bind،
ip.
تطبيقات سطح المكتب وخدمات النظام التي تصادف أنها تستمع — Figma، Discord،
Spotify، ControlCenter، حزم .app في macOS، خدمات /System/Library/ — تكون
مخفية ما لم تمرر -a.
sonar start
ابدأ مشروعًا من ملف sonar.yaml الخاص به:
sonar start # every service in the nearest sonar.yaml
sonar start api frontend # only these (they still wait for their dependencies)
sonar start ../other-project # the sonar.yaml in or above another directory
sonar start -d # in the background, like `sonar up`
في المقدمة، يبدأ sonar الخدمات عبر الخدمة الخلفية (daemon)، ويتابع سجلاتها مع اسم الخدمة أمام كل سطر، وعندما تضغط على Ctrl+C يوقف الخدمات التي بدأها. أما الخدمة التي كانت تعمل بالفعل فيُتركها دون مساس، ويعود sonar من تلقاء نفسه بمجرد انتهاء كل خدمة بدأها.
تسمّي الوسائط قبل -- دليلاً أو خدمات؛ وكل ما يأتي بعد -- هو أمر. أو شغّل أمراً واحداً كخدمة مُسمّاة ضمن مجموعة:
sonar start -- npm run dev
sonar start --group my-app --name frontend -- npm run dev
sonar start --port 5173 -- npm run dev # expected port, before it binds
sonar start --detach --name api -- uv run uvicorn app:app
sonar start --list
لا شيء يجب تمريره:
- Group —
--group، وإلا فإنnameفي أقربsonar.yaml، وإلا فإن اسم دليل جذر git (تصبح worktreerepo@worktree)، وإلا فإن اسم الدليل الحالي. - Name —
--name، وإلا فإن خدمةsonar.yamlالتي يطابقcmdالخاص بها، وإلا فإنه يُستنتج من الأمر (npm run dev→dev،uv run api→api،python -m uvicorn→uvicorn،./dev.sh→dev.sh). - Port —
--portهو تلميح، وليس ارتباطًا: يظهر التشغيل كـstartingحتى يصبح المنفذ في حالة استماع فعليًا، ويستخدمه الخادم لمطابقة العملية بالمنفذ.
يرث العملية الفرعية stdin وstdout وstderr وcwd والبيئة، بالإضافة إلى SONAR_GROUP وSONAR_NAME وSONAR_RUN_ID. ويحصل على مجموعة عمليات خاصة به، لذا فإن sonar kill يُسقط الشجرة بأكملها — خادم تطوير مع مراقبيه وعماله. يتم تمرير Ctrl+C، ويخرج sonar برمز خروج العملية الفرعية.
يعود --detach فورًا ويكتب المخرجات إلى ~/.config/sonar/logs/<group>/<name>.log. يعرض --list ما بدأه sonar، وتحته ما انتهى منذ ذلك الحين — مع رمز الخروج، وما إذا كان قد تعطل أو تم إيقافه (--json للصيغة القابلة للقراءة آليًا):
sonar start --list
sonar start --detach --name demo --port 8123 -- sleep 5
sonar start --list --json
# check
sonar.yaml
يُعرِّف المشروع نفسه وخدماته في ملف sonar.yaml في جذر المستودع.
وهو اختياري — إذ يقوم sonar بالتجميع حسب جذر git بدونه — والغرض منه
أن يتم الالتزام به: