Break Server-Timing into sess, db and tpl metrics

`app` alone said how long the origin took; it could not say where. The
header now also carries `sess` (the session/auth layers around the
routed stack), `db` (SQLite statement time, statement count in `desc`)
and `tpl` (askama rendering), each only where it was measured.

`db` needs a tracing layer: sqlx-sqlite runs statements on a worker
thread and only reports elapsed time there, inside the span the caller
handed it. The new `web::timing` module hangs the request's metrics on a
per-request span and reads them back off sqlx's `sqlx::query` event.
The layer's filter admits every span up to DEBUG, which is what lets it
see the request span past the middleware spans below it; the module docs
spell out the process-wide cost of that.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Va5eMEmWEnjMXBsBob5FDW
This commit is contained in:
2026-09-05 03:12:02 +00:00
co-authored by Claude Fable 5.1
parent 9c4964ae27
commit 17a88043ff
5 changed files with 471 additions and 23 deletions
+18 -4
View File
@@ -511,13 +511,27 @@ fn read_password_hidden(prompt: &str) -> Result<String> {
}
/// `RUST_LOG`-driven tracing, defaulting to `info` (crate table "logging").
///
/// Two layers over one registry rather than a bare `fmt()`: the statement
/// timings behind the `db` metric of `Server-Timing` ride in on sqlx's own
/// `DEBUG` events, and [`daily_epub::web::timing`] needs those enabled without
/// any of them reaching the log. Each layer carries its own filter, so the
/// `RUST_LOG` above still says exactly what gets printed.
fn init_tracing() {
use tracing_subscriber::Layer as _;
use tracing_subscriber::layer::SubscriberExt as _;
use tracing_subscriber::util::SubscriberInitExt as _;
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("info,sqlx=warn,hyper=warn,reqwest=warn"));
tracing_subscriber::fmt()
.with_env_filter(filter)
.with_target(false)
.with_writer(std::io::stderr)
tracing_subscriber::registry()
.with(
tracing_subscriber::fmt::layer()
.with_target(false)
.with_writer(std::io::stderr)
.with_filter(filter),
)
.with(daily_epub::web::timing::sqlx_timing_layer())
.init();
}