
Ferramenta CLI para inspecionar e gerenciar serviços escutando em portas localhost
███████╗ ██████╗ ███╗ ██╗ █████╗ ██████╗
██╔════╝██╔═══██╗████╗ ██║██╔══██╗██╔══██╗
███████╗██║ ██║██╔██╗ ██║███████║██████╔╝
╚════██║██║ ██║██║╚██╗██║██╔══██║██╔══██╗
███████║╚██████╔╝██║ ╚████║██║ ██║██║ ██║
╚══════╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝
Saiba o que está rodando na sua máquina.
Cansado de executar lsof -iTCP -sTCP:LISTEN | grep ... toda vez que uma porta já estava ocupada, e depois perder mais um minuto tentando descobrir se era um contêiner Docker ou algum servidor de desenvolvimento órfão de outra worktree. Então eu construí o sonar.
Ele mostra tudo que está escutando no localhost, com nomes de contêineres Docker, projetos Compose, uso de recursos e URLs clicáveis. Você pode encerrar processos, acompanhar logs, abrir shell em contêineres e muito mais — tudo pelo número da porta.
$ 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 portas (4 docker, 1 usuário)
brew install raskrebs/sonar/sonar
No macOS, isso também instala o aplicativo de barra de menus sonar-tray.
curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | bash
Faz o download do binário mais recente para ~/.local/bin e o adiciona ao seu PATH se necessário. Reinicie o terminal ou execute source ~/.zshrc.
No Windows (PowerShell):
irm https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.ps1 | iex
Local de instalação personalizado:
curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | SONAR_INSTALL_DIR=/usr/local/bin bash
Instalar uma versão 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 installinstala apenas a CLI. O aplicativo de barra de menus (sonar tray) é um binário nativo em Swift e deve ser compilado separadamente — veja Aplicativo de bandeja abaixo.
Completions para shell (auto-completar números de porta):
sonar completion zsh > "${fpath[1]}/_sonar" # zsh
sonar completion bash > /etc/bash_completion.d/sonar # bash
sonar completion fish | source # fish
sonar list # mostrar todas as portas
sonar list --stats # incluir CPU, memória, estado, tempo de atividade
sonar list --filter docker # apenas portas Docker
sonar list --sort name # ordenar por nome do processo
sonar list --json # saída JSON
sonar list -a # incluir aplicativos de desktop
sonar list -c port,cpu,mem,uptime,state # colunas personalizadas
sonar list --health # executar verificações de saúde HTTP
sonar list --host user@server # escanear uma máquina remota via SSH
Por padrão, o sonar oculta aplicativos de desktop e serviços do sistema que escutam em portas TCP, mas não são relevantes para desenvolvimento — coisas como Figma, Discord, Spotify, ControlCenter, AirPlay e outros pacotes .app do macOS e daemons do /System/Library/. Use -a para incluí-los.
Colunas disponíveis: port, process, pid, type, url, cpu, mem, threads, uptime, state, connections, health, latency, container, image, containerport, , , , ,
sonar info 3000
Mostra tudo sobre uma porta: comando completo, usuário, endereço de bind, CPU/memória/threads, tempo de atividade, resultado de verificação de saúde e detalhes do Docker, se aplicável.
sonar kill 3000 # SIGTERM
sonar kill 3000 -f # SIGKILL
sonar kill-all --filter docker # parar todos os contêineres Docker
sonar kill-all --project my-app # parar um projeto Compose
sonar kill-all --filter user -y # pular confirmação
Contêineres Docker são parados com docker stop em vez de enviar sinais.
sonar logs 3000
Para contêineres Docker, executa docker logs -f. Para processos nativos, descobre arquivos de log via lsof e os monitora em tempo real. Cai no log stream do macOS ou no /proc/<pid>/fd do Linux.
sonar attach 3000 # abrir shell no contêiner Docker, ou conectar TCP
sonar attach 3000 --shell bash # shell específico
sonar watch # consultar a cada 2s, mostrar diferenças
sonar watch --stats # estatísticas de recursos ao vivo (como docker stats)
sonar watch -i 500ms # consulta mais rápida
sonar watch --notify # notificações de desktop quando portas sobem/descem
sonar watch --host user@server # observar uma máquina remota
sonar graph # mostrar quais serviços se comunicam entre si
sonar graph --json # saída estruturada
sonar graph --dot # formato Graphviz DOT
Mostra conexões estabelecidas entre portas escutando (ex.: seu backend conectando ao postgres).
Salve um conjunto de portas esperadas para um projeto e verifique se todas estão ativas ou as encerre:
sonar profile create my-app # capturar portas atuais
sonar profile list # listar perfis salvos
sonar profile show my-app # mostrar detalhes do perfil
sonar up my-app # verificar quais portas esperadas estão funcionando
sonar down my-app # parar todas as portas no perfil
sonar wait 5432 # bloquear até que a porta aceite conexões
sonar wait 5432 3000 6379 # aguardar múltiplas portas
sonar wait 5432 --timeout 30s # falhar após 30 segundos
sonar wait 5432 --http # aguardar HTTP 200, não apenas TCP aberto
sonar wait 5432 --http=/health # verificar um endpoint específico
sonar wait 5432 -i 500ms # intervalo de consulta personalizado
sonar wait 5432 -q # sem saída, apenas código de saída (para scripts)
Útil para scripts em torno de docker compose up -d ou serviços em segundo plano. A flag --http aguarda uma resposta HTTP real 200-399, não apenas um socket TCP, o que captura serviços que aceitam conexões antes de estarem realmente prontos. Use --http=/health para verificar um endpoint específico. Códigos de saída: 0 (pronto), 1 (timeout), 2 (interrompido).
docker compose up -d
sonar wait 5432 3000 --timeout 60s && npm run migrate && npm run test
sonar map 6873 3002
Faz proxy do tráfego para que o serviço na porta 6873 também esteja disponível na porta 3002.
sonar next # primeira porta livre a partir de 3000
sonar next 8000 # primeira porta livre a partir de 8000
sonar next 3000-3100 # primeira porta livre no intervalo
sonar next -n 3 # 3 portas livres consecutivas
sonar next --json # saída JSON
sonar open 3000 # abrir no navegador
sonar tray # aplicativo de barra de menus com estatísticas ao vivo (macOS)
sonar --no-color # desabilitar cores (também respeita a variável de ambiente NO_COLOR)
A flag --stats obtém uso de recursos por processo e por contêiner. Para contêineres Docker, usa a API do Docker Engine para métricas precisas por contêiner. Sem --stats, o sonar retorna instantaneamente.
O sonar lê opções padrão opcionais de ~/.config/sonar/config.yaml. O arquivo é
opcional — sem ele, os padrões embutidos são aplicados. As flags da linha de comando sempre
substituem o arquivo de configuração.
Crie um arquivo inicial:
sonar config init # escrever um template comentado
sonar config path # imprimir o local do arquivo
sonar config edit # abrir no $EDITOR
Exemplo de configuração:
list:
columns: [port, process, container, image, containerport, url]
sort: port # port | pid | name | type
filter: "" # docker | user | system | "" (all)
all: false # incluir aplicativos de desktop por padrão
color: true # defina false para desabilitar saída colorida
services: # rotular portas personalizadas/desconhecidas
9000: php-fpm
5050: my-dashboard
Valores inválidos são ignorados com um aviso; o sonar continua com os padrões.
O aplicativo de barra de menus (apenas macOS) é um binário nativo em Swift que mostra estatísticas de portas ao vivo na sua barra de menus. Se você instalou o sonar via script de instalação ou release do GitHub, o binário da bandeja (sonar-tray) é incluído automaticamente.
Se você instalou via go install, compile manualmente:
swiftc -O -o sonar-tray tray/SonarTray.swift -target arm64-apple-macos13
Depois mova o sonar-tray para algum lugar no seu $PATH e execute:
sonar tray
lsof)ss)netstat)Agradecimentos a todos que contribuíram para o sonar!
composeprojectuserbindip