
sonar v0.4.1
Outil CLI pour inspecter et gérer les services écoutant sur les ports localhost.
██████ ███ ██████ ██ ██████
██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ████
██ ██ ██ ██ ██ ██ ██ ██
██████ ███ ██ ██ ██ ██ ██ ██
Sachez ce qui tourne sur votre machine.
Sonar affiche tout ce qui écoute sur localhost et le met en ordre : chaque port
appartient à un groupe — normalement le dépôt depuis lequel il a été démarré — et
à l'intérieur de ce groupe à un service nommé. Démarrez vos serveurs de développement avec
sonar start et tout le projet devient une seule chose que vous pouvez lister sous forme d'arbre,
attendre, suivre et arrêter avec une seule commande. Les conteneurs Docker, les projets
Compose et les processus que vous avez démarrés à la main sont également détectés, sans aucune
configuration.
$ 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
Installation
Homebrew (macOS / Linux)
brew install raskrebs/sonar/sonar
Homebrew 6 refuse les formules des taps tiers tant que vous n'avez pas approuvé le tap une fois
(Error: Refusing to load formula raskrebs/sonar/sonar from untrusted tap) :
brew trust raskrebs/sonar
Script d'installation
curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | bash
Télécharge le dernier binaire dans ~/.local/bin et l'ajoute à votre PATH si nécessaire. Redémarrez votre terminal ou exécutez source ~/.zshrc.
Sur Windows (PowerShell) :
irm https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.ps1 | iex
Emplacement d'installation personnalisé :
curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | SONAR_INSTALL_DIR=/usr/local/bin bash
Installer une version spécifique :
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
Utilisation de Go
go install github.com/raskrebs/sonar@latest
Complétions du shell (complétion par tabulation des numéros de port) :
sonar completion zsh > "${fpath[1]}/_sonar" # zsh
sonar completion bash > /etc/bash_completion.d/sonar # bash
sonar completion fish | source # fish
Soixante secondes
Décrivez comment votre projet s'exécute dans un sonar.yaml à la racine du dépôt, à
la place d'un 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}
Puis démarrez-le :
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 choisit un port libre pour chaque service port: auto et indique à chaque service
où se trouvent les autres, de sorte qu'un second worktree s'exécute à côté du premier sans
qu'un seul port n'entre en conflit. sonar start -d fait la même chose en arrière-plan, et
sonar down l'arrête et libère les ports. Dans un autre terminal :
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
Pas de sonar.yaml ? sonar start -- npm run dev exécute une commande en tant que
service nommé, et sonar list et sonar kill fonctionnent sur tout ce qui écoute.
Les exemples ci-dessous marqués # check sont exécutés sur une version fraîche par
scripts/readme-check.sh à chaque exécution de la CI.
Commandes
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
Les colonnes par défaut sont port, process, group, container, image,
containerport, url, où process affiche le nom que vous avez donné au port
(sonar rename), puis le nom du service, puis ce qui a été détecté.
Colonnes disponibles : port, process, pid, type, url, group, cpu,
mem, threads, uptime, state, connections, health, latency,
container, image, containerport, compose, project, user, bind,
ip.
Les applications de bureau et les services système qui se trouvent écouter — Figma, Discord,
Spotify, ControlCenter, les bundles .app de macOS, les démons de /System/Library/ — sont
masqués sauf si vous passez -a.
sonar start
Démarrer un projet à partir de son 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`
Au premier plan, sonar démarre les services via le démon, suit leurs journaux avec le nom du service devant chaque ligne, et lorsque vous appuyez sur Ctrl+C arrête les services qu'il a démarrés. Un service qui était déjà en cours d'exécution est laissé tranquille, et sonar revient de lui-même une fois que chaque service qu'il a démarré s'est terminé.
Les arguments avant -- désignent un répertoire ou des services ; tout ce qui suit -- est une
commande. Ou exécutez une commande en tant que service nommé dans un groupe :
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
Rien ne doit être passé :
- Group —
--group, sinon lenamedans lesonar.yamlle plus proche, sinon le nom du répertoire de la racine git (un worktree devientrepo@worktree), sinon le nom du répertoire courant. - Name —
--name, sinon le servicesonar.yamldont lecmdcorrespond, sinon déduit de la commande (npm run dev→dev,uv run api→api,python -m uvicorn→uvicorn,./dev.sh→dev.sh). - Port —
--portest un indice, pas une liaison : l'exécution apparaît commestartingjusqu'à ce que le port soit réellement en écoute, et le daemon l'utilise pour faire correspondre le processus au port.