
Herramienta CLI para inspeccionar y gestionar servicios que escuchan en puertos de localhost
███████╗ ██████╗ ███╗ ██╗ █████╗ ██████╗
██╔════╝██╔═══██╗████╗ ██║██╔══██╗██╔══██╗
███████╗██║ ██║██╔██╗ ██║███████║██████╔╝
╚════██║██║ ██║██║╚██╗██║██╔══██║██╔══██╗
███████║╚██████╔╝██║ ╚████║██║ ██║██║ ██║
╚══════╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝
Sepa lo que se ejecuta en su máquina.
Me cansé de ejecutar lsof -iTCP -sTCP:LISTEN | grep ... cada vez que un puerto ya estaba ocupado, para luego perder otro minuto averiguando si era un contenedor Docker o un servidor de desarrollo huérfano de otro worktree. Así que construí sonar.
Muestra todo lo que está escuchando en localhost, con nombres de contenedores Docker, proyectos Compose, uso de recursos y URLs cliqueables. Puedes matar procesos, ver logs, acceder a contenedores por shell y más — todo por número de puerto.
$ sonar list
PORT PROCESS CONTAINER IMAGE CPORT URL
1780 proxy (traefik:3.0) my-app-proxy-1 traefik:3.0 80 http://localhost:1780
3000 next-server (v16.1.6) http://localhost:3000
5432 db (postgres:17) my-app-db-1 postgres:17 5432 http://localhost:5432
6873 frontend (frontend:latest) my-app-frontend-1 frontend:latest 5173 http://localhost:6873
9700 backend (backend:latest) my-app-backend-1 backend:latest 8000 http://localhost:9700
5 ports (4 docker, 1 user)
brew install raskrebs/sonar/sonar
En macOS también instala la aplicación de la barra de menú sonar-tray.
curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | bash
Descarga el binario más reciente en ~/.local/bin y lo agrega a tu PATH si es necesario. Reinicia tu terminal o ejecuta source ~/.zshrc.
En Windows (PowerShell):
irm https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.ps1 | iex
Ubicación de instalación personalizada:
curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | SONAR_INSTALL_DIR=/usr/local/bin bash
Instalar una versión específica:
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 install github.com/raskrebs/sonar@latest
Nota:
go installsolo instala la CLI. La aplicación de la barra de menú (sonar tray) es un binario nativo de Swift y debe compilarse por separado — consulta Aplicación de bandeja más abajo.
Completado de shell (autocompletar números de puerto):
sonar completion zsh > "${fpath[1]}/_sonar" # zsh
sonar completion bash > /etc/bash_completion.d/sonar # bash
sonar completion fish | source # fish
sonar list # mostrar todos los puertos
sonar list --stats # incluir CPU, memoria, estado, tiempo de actividad
sonar list --filter docker # solo puertos Docker
sonar list --sort name # ordenar por nombre de proceso
sonar list --json # salida JSON
sonar list -a # incluir aplicaciones de escritorio
sonar list -c port,cpu,mem,uptime,state # columnas personalizadas
sonar list --health # ejecutar comprobaciones de salud HTTP
sonar list --host user@server # escanear una máquina remota vía SSH
Por defecto, sonar oculta las aplicaciones de escritorio y servicios del sistema que escuchan en puertos TCP pero no son relevantes para el desarrollo — cosas como Figma, Discord, Spotify, ControlCenter, AirPlay y otros paquetes .app de macOS y demonios de /System/Library/. Usa -a para incluirlos.
Columnas disponibles: port, process, pid, type, url, cpu, mem, threads, uptime, state, connections, health, latency, container, image, containerport, , , , ,
sonar info 3000
Muestra todo sobre un puerto: comando completo, usuario, dirección de enlace, CPU/memoria/hilos, tiempo de actividad, resultado de la comprobación de salud y detalles de Docker si corresponde.
sonar kill 3000 # SIGTERM
sonar kill 3000 -f # SIGKILL
sonar kill-all --filter docker # detener todos los contenedores Docker
sonar kill-all --project my-app # detener un proyecto Compose
sonar kill-all --filter user -y # saltar confirmación
Los contenedores Docker se detienen con docker stop en lugar de enviar señales.
sonar logs 3000
Para contenedores Docker, ejecuta docker logs -f. Para procesos nativos, descubre archivos de registro mediante lsof y los sigue. Como alternativa, usa log stream en macOS o /proc/<pid>/fd en Linux.
sonar attach 3000 # acceder por shell al contenedor Docker, o conexión TCP
sonar attach 3000 --shell bash # shell específico
sonar watch # consultar cada 2s, mostrar diferencias
sonar watch --stats # estadísticas de recursos en vivo (como docker stats)
sonar watch -i 500ms # consulta más rápida
sonar watch --notify # notificaciones de escritorio cuando los puertos suben/bajan
sonar watch --host user@server # vigilar una máquina remota
sonar graph # mostrar qué servicios se comunican entre sí
sonar graph --json # salida estructurada
sonar graph --dot # formato Graphviz DOT
Muestra conexiones establecidas entre puertos en escucha (por ejemplo, tu backend conectándose a postgres).
Guarda un conjunto de puertos esperados para un proyecto, luego verifica si todos están activos o los detienes:
sonar profile create my-app # instantánea de los puertos actuales
sonar profile list # listar perfiles guardados
sonar profile show my-app # mostrar detalles del perfil
sonar up my-app # verificar qué puertos esperados están ejecutándose
sonar down my-app # detener todos los puertos del perfil
sonar wait 5432 # bloquear hasta que el puerto acepte conexiones
sonar wait 5432 3000 6379 # esperar múltiples puertos
sonar wait 5432 --timeout 30s # fallar después de 30 segundos
sonar wait 5432 --http # esperar HTTP 200, no solo TCP abierto
sonar wait 5432 --http=/health # verificar un endpoint específico
sonar wait 5432 -i 500ms # intervalo de consulta personalizado
sonar wait 5432 -q # sin salida, solo código de salida (para scripts)
Útil para secuencias de comandos alrededor de docker compose up -d o servicios en segundo plano. La bandera --http espera una respuesta HTTP real 200-399, no solo un socket TCP, lo que detecta servicios que aceptan conexiones antes de estar realmente listos. Usa --http=/health para verificar un endpoint específico. Códigos de salida: 0 (listo), 1 (tiempo de espera agotado), 2 (interrumpido).
docker compose up -d
sonar wait 5432 3000 --timeout 60s && npm run migrate && npm run test
sonar map 6873 3002
Proxy de tráfico para que el servicio en el puerto 6873 también esté disponible en el puerto 3002.
sonar next # primer puerto libre desde 3000
sonar next 8000 # primer puerto libre desde 8000
sonar next 3000-3100 # primer puerto libre en el rango
sonar next -n 3 # 3 puertos libres consecutivos
sonar next --json # salida JSON
sonar open 3000 # abrir en el navegador
sonar tray # aplicación de barra de menú con estadísticas en vivo (macOS)
sonar --no-color # deshabilitar colores (también respeta la variable de entorno NO_COLOR)
La bandera --stats obtiene el uso de recursos por proceso y por contenedor. Para contenedores Docker, utiliza la API del motor Docker para métricas precisas por contenedor. Sin --stats, sonar regresa instantáneamente.
sonar lee valores predeterminados opcionales de ~/.config/sonar/config.yaml. El archivo es opcional; sin él, se aplican los valores predeterminados integrados. Las banderas de línea de comandos siempre anulan el archivo de configuración.
Crear un archivo inicial:
sonar config init # escribir una plantilla comentada
sonar config path # imprimir la ubicación del archivo
sonar config edit # abrirlo en $EDITOR
Ejemplo de configuración:
list:
columns: [port, process, container, image, containerport, url]
sort: port # port | pid | name | type
filter: "" # docker | user | system | "" (all)
all: false # include desktop apps by default
color: true # set false to disable colored output
services: # label custom/unknown ports
9000: php-fpm
5050: my-dashboard
Los valores no válidos se ignoran con una advertencia; sonar continúa con los valores predeterminados.
La aplicación de la barra de menú (solo macOS) es un binario nativo de Swift que muestra estadísticas de puertos en vivo en la barra de menú. Si instalaste sonar mediante el script de instalación o un lanzamiento de GitHub, el binario de bandeja (sonar-tray) se incluye automáticamente.
Si instalaste mediante go install, constrúyelo manualmente:
swiftc -O -o sonar-tray tray/SonarTray.swift -target arm64-apple-macos13
Luego mueve sonar-tray a algún lugar en tu $PATH y ejecuta:
sonar tray
lsof)ss)netstat)¡Gracias a todos los que han contribuido a sonar!
composeprojectuserbindip