A logger for Go SQL database drivers with log/slog without modifying existing *sql.DB
stdlib usage.
- Keep using (or re-use existing)
*sql.DB
as is. - No logger adapters. Just use log/slog
- No dependencies
- Leveled, detailed, and configurable logging.
- Duration tracking
- Trackable log output
- 100% test coverage
See godoc for more details.
To install sql-slog, use the following command:
go get -u github.com/akm/sql-slog
To use sql-slog, you can open a database connection with logging enabled as follows:
db, logger, err := sqlslog.Open(ctx, "mysql", dsn)
This is the easiest way to use sqlslog. It's similar to the usage of Open
from database/sql
like this:
db, err := sql.Open("mysql", dsn)
The differences are:
- Pass
context.Context
as the first argument. *slog.Logger
is returned as the second argument.sqlslog.Open
can take a lot of Option s.
See godoc examples for more details.
An example showing how sql-slog works with sqlc. This example is almost same as Getting started with SQLite but uses sqlslog.Open instead of sql.Open.
Stdout with sqlslog package
$ make -C examples/with-sqlc run
go build ./...
go run .
time=2025-03-19T21:23:36.992+09:00 level=INFO msg=Open driver=sqlite dsn=:memory: duration=22083
time=2025-03-19T21:23:36.992+09:00 level=INFO msg=Driver.Open dsn=:memory: duration=274042 conn_id=_hMZDi7TQfEgBKN_
time=2025-03-19T21:23:36.992+09:00 level=INFO msg=Connector.Connect duration=294292
time=2025-03-19T21:23:36.993+09:00 level=INFO msg=Conn.ExecContext conn_id=_hMZDi7TQfEgBKN_ query="CREATE TABLE authors (\n id INTEGER PRIMARY KEY,\n name text NOT NULL,\n bio text\n);\n" args=[] duration=537125
time=2025-03-19T21:23:36.993+09:00 level=INFO msg=Conn.QueryContext conn_id=_hMZDi7TQfEgBKN_ query="-- name: ListAuthors :many\nSELECT id, name, bio FROM authors\nORDER BY name\n" args=[] duration=23250
2025/03/19 21:23:36 []
time=2025-03-19T21:23:36.993+09:00 level=INFO msg=Conn.QueryContext conn_id=_hMZDi7TQfEgBKN_ query="-- name: CreateAuthor :one\nINSERT INTO authors (\n name, bio\n) VALUES (\n ?, ?\n)\nRETURNING id, name, bio\n" args="[{Name: Ordinal:1 Value:Brian Kernighan} {Name: Ordinal:2 Value:Co-author of The C Programming Language and The Go Programming Language}]" duration=20375
2025/03/19 21:23:36 {1 Brian Kernighan {Co-author of The C Programming Language and The Go Programming Language true}}
time=2025-03-19T21:23:36.993+09:00 level=INFO msg=Conn.QueryContext conn_id=_hMZDi7TQfEgBKN_ query="-- name: GetAuthor :one\nSELECT id, name, bio FROM authors\nWHERE id = ? LIMIT 1\n" args="[{Name: Ordinal:1 Value:1}]" duration=8083
2025/03/19 21:23:36 true
Stdout without sqlslog package
$ SKIP_SQLSLOG=1 make -C examples/with-sqlc run
go build ./...
go run .
2025/03/19 21:23:19 []
2025/03/19 21:23:19 {1 Brian Kernighan {Co-author of The C Programming Language and The Go Programming Language true}}
2025/03/19 21:23:19 true
An example showing how sql-slog works with go-requestid. You can see DB query logs with request IDs in the same log like the following:
time=2025-02-27T23:53:48.982+09:00 level=DEBUG msg=Conn.QueryContext conn_id=L1snTUaknlmsin8b query="SELECT id, title, status FROM todos" args=[] req_id=0JKGwDLjw77BjBnf
conn_id
is a tracking ID for DB connection by sql-slog, and req_id
is a tracking ID for HTTP request by go-requestid.
See server-logs.txt and main.go for more details.
- For MySQL for more details.
- For PostgreSQL for more details.
- For SQLite3 for more details.
I want to:
- Keep using
*sql.DB
.- To work with thin ORM
- Use log/slog
- Leverage structured logging
- Fetch and log
context.Context
values if needed
If you find a bug, typo, incorrect test, have an idea, or want to help with an existing issue, please create an issue or pull request.