Real-time SQL query monitor for Go applications. Wraps database/sql drivers to capture every query, then streams them
to an interactive terminal UI over gRPC.
┌──────────────────────────────────────────────────────────────────────────────┐
│ Your Go app (database/sql) │
│ │ │
│ ▼ │
│ sql-scope driver wrapper ──► gRPC server (:9091) │
│ │ │ │
│ ▼ ▼ │
│ Real DB driver sql-scope monitor (TUI) │
│ (pgx / mysql) │
└──────────────────────────────────────────────────────────────────────────────┘
Supports PostgreSQL (pgx) and MySQL (go-sql-driver/mysql).
go install github.com/mickamy/sql-scope@latestOr build from source:
git clone https://github.com/mickamy/sql-scope.git
cd sql-scope
make installimport (
"database/sql"
_ "github.com/jackc/pgx/v5/stdlib" // or _ "github.com/go-sql-driver/mysql"
"github.com/mickamy/sql-scope/scope"
"github.com/mickamy/sql-scope/scope/driver"
)
func main() {
ctx := context.Background()
// Start the scope server (default port 9091)
s, err := scope.New(ctx)
// s, err := scope.New(ctx, scope.WithPort(9092)) // custom port
if err != nil { log.Fatal(err) }
defer s.Close()
// Wrap your database driver
name := driver.Wrap("pgx", s) // PostgreSQL
// name := driver.Wrap("mysql", s) // MySQL
// Use database/sql as usual
db, err := sql.Open(name, dsn)
// All queries are now captured and streamed.
}sql-scope monitor localhost:9091To enable EXPLAIN support, set the database DSN:
DATABASE_URL="postgres://user:pass@localhost/db" sql-scope monitor localhost:9091The default view shows all captured queries in real time.
- Transactions are automatically grouped and color-coded
- New events are followed automatically (disable by scrolling up)
- A preview panel below the list shows details of the selected item
| Key | Action |
|---|---|
j / k |
Navigate up / down |
enter |
Open inspector |
space |
Collapse / expand transaction |
c |
Copy raw query to clipboard |
C |
Copy query with args interpolated |
x / X |
EXPLAIN / EXPLAIN ANALYZE |
e / E |
Edit query in $EDITOR, then EXPLAIN / ANALYZE |
q |
Quit |
A detailed view of a single query or transaction summary.
Shows: operation type, full query with syntax highlighting, arguments, duration, timestamp, rows affected, error, caller stack trace, and transaction ID.
| Key | Action |
|---|---|
j / k |
Scroll |
c |
Copy raw query |
C |
Copy query with args interpolated |
x / X |
EXPLAIN / EXPLAIN ANALYZE |
e / E |
Edit query in $EDITOR, then EXPLAIN / ANALYZE |
q |
Back to list |
Shows the output of EXPLAIN or EXPLAIN ANALYZE with syntax highlighting and horizontal scrolling.
| Key | Action |
|---|---|
j / k |
Scroll vertically |
h / l |
Scroll horizontally |
c |
Copy plan text |
e / E |
Edit query in $EDITOR, then re-run |
q |
Back to list |
c copies the raw parameterized query (e.g. SELECT * FROM users WHERE id = $1).
C interpolates arguments into the query before copying (e.g. SELECT * FROM users WHERE id = 42). String arguments are automatically single-quoted; numbers, booleans, and NULL are left unquoted.
Both PostgreSQL-style ($1, $2) and MySQL-style (?) placeholders are supported.
| OS | Command used |
|---|---|
| macOS | pbcopy |
| Linux | xclip (fallback: xsel) |
| Windows | clip.exe |
Pressing x runs EXPLAIN on the selected query against your database. X runs EXPLAIN ANALYZE (actually executes the query).
Pressing e or E opens the query in your $EDITOR (default: vi) before running EXPLAIN, so you can tweak it first.
Requires DATABASE_URL (or a custom env var via --dsn-env):
sql-scope monitor localhost:9091 --dsn-env=MY_DSNEvery database/sql operation is captured:
| Operation | Description |
|---|---|
| Query | db.Query, db.QueryRow |
| Exec | db.Exec |
| Prepare | db.Prepare |
| Begin | db.BeginTx |
| Commit | tx.Commit |
| Rollback | tx.Rollback |
Each event includes:
- SQL query text and arguments
- Execution duration
- Timestamp
- Rows affected
- Error (if any)
- Caller stack trace (filtered to application frames)
- Transaction ID (for grouping)
Complete working examples are in the example/ directory:
docker compose up -d # Start PostgreSQL and MySQL
# PostgreSQL
DATABASE_URL="postgres://postgres:postgres@localhost:5432/db?sslmode=disable" \
go run ./example/postgres
# MySQL
DATABASE_URL="root:root@tcp(localhost:3306)/db" \
go run ./example/mysqlThen in another terminal:
DATABASE_URL="postgres://postgres:postgres@localhost:5432/db?sslmode=disable" \
sql-scope monitor localhost:9091sql-scope monitor <scope-addr> [--dsn-env=ENV]
sql-scope version
sql-scope help
| Flag | Default | Description |
|---|---|---|
--dsn-env |
DATABASE_URL |
Environment variable holding the database DSN |
