>
dbwarden
/ tool scope / observability

Database Migration
Observability.

The workflow is observable: Prometheus metrics from migrate and seed commands, newline-delimited JSON for log pipelines, and trace-level SQL when you need to see every statement.

Prometheus counters, gauges, histograms.

Set DBWARDEN_METRICS=true and migrate and seed apply record counters, gauges, and histograms: migrations applied and migration errors as counters, migration duration as a histogram, and schema version, seed version, and pending migrations as gauges, all labeled by database. The metric types match what each question needs: a counter for how many times a migration ran, a gauge for the current schema version, a histogram for how long applies take.

The FastAPI plugin exposes them at /metrics via the MetricsRouter and MetricsMiddleware, so one scrape target covers both the application and the migration commands it runs. The dependency is optional: uv add "dbwarden[metrics]" installs prometheus-client, and without it every metric function is a safe no-op.

enable metrics
$ DBWARDEN_METRICS=true dbwarden migrate
Is the metrics dependency optional?

Yes: uv add "dbwarden[metrics]" installs prometheus-client. When it is not installed or DBWARDEN_METRICS is unset, all metric functions are safe no-ops.

Which metrics does migrate record?

Counters for migrations applied and migration errors, a histogram for migration duration, and gauges for schema version, seed version, and pending migrations, all labeled by database.

Why does /metrics return 404?

The FastAPI endpoint is only active when prometheus-client is installed and DBWARDEN_METRICS=true is set. Disabled otherwise by design.

JSON lines, or trace-level SQL.

DBWARDEN_LOG_JSON switches to newline-delimited JSON for ELK, Loki, or Datadog, one object per line, ready for structured parsing instead of text scraping. The global --json flag does the same for a single run and also switches display commands to JSON output, while the environment variable makes JSON the default for the whole environment.

When you need to see exactly what ran against the database, --debug-level trace logs every SQL statement as it executes during migrate, rollback, and downgrade, and --perf adds per-statement timing. Trace is below debug in the level ordering, so it is explicitly opt-in: normal runs stay quiet, and the full statement log is there when an incident needs it.

json or trace
$ DBWARDEN_LOG_JSON=true dbwarden migrate --debug-level trace
Is --json the same as DBWARDEN_LOG_JSON?

The global --json flag switches log output to JSON for that run and also switches display commands to JSON output. DBWARDEN_LOG_JSON makes JSON the default for the environment.

What does trace level add over debug?

Trace (level 5, below debug) logs every SQL statement as it executes during migrate, rollback, and downgrade. --perf adds each statement’s duration.