Skip to content

raskrebs/sonar

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

███████╗ ██████╗ ███╗   ██╗ █████╗ ██████╗
██╔════╝██╔═══██╗████╗  ██║██╔══██╗██╔══██╗
███████╗██║   ██║██╔██╗ ██║███████║██████╔╝
╚════██║██║   ██║██║╚██╗██║██╔══██║██╔══██╗
███████║╚██████╔╝██║ ╚████║██║  ██║██║  ██║
╚══════╝ ╚═════╝ ╚═╝  ╚═══╝╚═╝  ╚═╝╚═╝  ╚═╝

Know what's running on your machine.

I got tired of running lsof -iTCP -sTCP:LISTEN | grep ... every time a port was already taken, then spending another minute figuring out if it was a Docker container or some orphaned dev server from another worktree. So I built sonar.

It shows everything listening on localhost, with Docker container names, Compose projects, resource usage, and clickable URLs. You can kill processes, tail logs, shell into containers, and more — all by port number.

$ 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)

Install

curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | bash

Downloads the latest binary to ~/.local/bin and adds it to your PATH if needed. Restart your terminal or source ~/.zshrc.

On Windows (PowerShell):

irm https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.ps1 | iex

Custom install location:

curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | SONAR_INSTALL_DIR=/usr/local/bin bash

Install a specific version:

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

Using Go

go install github.com/raskrebs/sonar@latest

Note: go install only installs the CLI. The menu bar tray app (sonar tray) is a native Swift binary and must be built separately — see Tray app below.

Shell completions (tab-complete port numbers):

sonar completion zsh > "${fpath[1]}/_sonar"   # zsh
sonar completion bash > /etc/bash_completion.d/sonar  # bash
sonar completion fish | source                 # fish

Usage

List ports

sonar list                     # show all ports
sonar list --stats             # include CPU, memory, state, uptime
sonar list --filter docker     # only Docker ports
sonar list --sort name         # sort by process name
sonar list --json              # JSON output
sonar list -a                  # include desktop apps
sonar list -c port,cpu,mem,uptime,state  # custom columns
sonar list --health            # run HTTP health checks
sonar list --host user@server  # scan a remote machine via SSH

By default, sonar hides desktop apps and system services that listen on TCP ports but aren't relevant to development — things like Figma, Discord, Spotify, ControlCenter, AirPlay, and other macOS .app bundles and /System/Library/ daemons. Use -a to include them.

Available columns: port, process, pid, type, url, cpu, mem, threads, uptime, state, connections, health, latency, container, image, containerport, compose, project, user, bind, ip

Inspect a port

sonar info 3000

Shows everything about a port: full command, user, bind address, CPU/memory/threads, uptime, health check result, and Docker details if applicable.

Kill processes

sonar kill 3000                            # SIGTERM
sonar kill 3000 -f                         # SIGKILL
sonar kill-all --filter docker             # stop all Docker containers
sonar kill-all --project my-app            # stop a Compose project
sonar kill-all --filter user -y            # skip confirmation

Docker containers are stopped with docker stop instead of sending signals.

View logs

sonar logs 3000

For Docker containers, runs docker logs -f. For native processes, discovers log files via lsof and tails them. Falls back to macOS log stream or Linux /proc/<pid>/fd.

Attach to a service

sonar attach 3000                          # shell into Docker container, or TCP connect
sonar attach 3000 --shell bash             # specific shell

Watch for changes

sonar watch                                # poll every 2s, show diffs
sonar watch --stats                        # live resource stats (like docker stats)
sonar watch -i 500ms                       # faster polling
sonar watch --notify                       # desktop notifications when ports go up/down
sonar watch --host user@server             # watch a remote machine

Dependency graph

sonar graph                                # show which services talk to each other
sonar graph --json                         # structured output
sonar graph --dot                          # Graphviz DOT format

Shows established connections between listening ports (e.g. your backend connecting to postgres).

Profiles

Save a set of expected ports for a project, then check if they're all up or tear them down:

sonar profile create my-app                # snapshot current ports
sonar profile list                         # list saved profiles
sonar profile show my-app                  # show profile details
sonar up my-app                            # check which expected ports are running
sonar down my-app                          # stop all ports in the profile

Wait for ports

sonar wait 5432                        # block until port is accepting connections
sonar wait 5432 3000 6379              # wait for multiple ports
sonar wait 5432 --timeout 30s         # fail after 30 seconds
sonar wait 5432 --http                # wait for HTTP 200, not just TCP open
sonar wait 5432 --http=/health        # check a specific endpoint
sonar wait 5432 -i 500ms              # custom polling interval
sonar wait 5432 -q                    # no output, just exit code (for scripts)

Useful for scripting around docker compose up -d or background services. The --http flag waits for an actual HTTP 200-399 response, not just a TCP socket, which catches services that accept connections before they're truly ready. Use --http=/health to check a specific endpoint. Exit codes: 0 (ready), 1 (timeout), 2 (interrupted).

docker compose up -d
sonar wait 5432 3000 --timeout 60s && npm run migrate && npm run test

Port mapping

sonar map 6873 3002

Proxies traffic so the service on port 6873 is also available on port 3002.

Find free ports

sonar next                                 # first next free port from 3000
sonar next 8000                            # first next free port from 8000
sonar next 3000-3100                       # first next free port in range
sonar next -n 3                            # 3 consecutive free ports
sonar next --json                          # JSON output

Other

sonar open 3000                            # open in browser
sonar tray                                 # menu bar app with live stats (macOS)
sonar --no-color                           # disable colors (also respects NO_COLOR env)

The --stats flag fetches per-process and per-container resource usage. For Docker containers, it uses the Docker Engine API for accurate per-container metrics. Without --stats, sonar returns instantly.

Tray app

The menu bar tray app (macOS only) is a native Swift binary that shows live port stats in your menu bar. If you installed sonar via the install script or a GitHub release, the tray binary (sonar-tray) is included automatically.

If you installed via go install, build it manually:

swiftc -O -o sonar-tray tray/SonarTray.swift -target arm64-apple-macos13

Then move sonar-tray somewhere on your $PATH and run:

sonar tray

Supported platforms

  • macOS (uses lsof)
  • Linux (uses ss)
  • Windows (uses netstat)

Contributors

Thanks to everyone who has contributed to sonar!

About

CLI tool for inspecting and managing services listening on localhost ports

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors