A list's trace says which list it was (#287)
The prod check of 2026-10-19 found /api/entries requests of 0.5-0.8 s overnight beside others of 80-100 ms on an idle host, the time all in entries_in, and nothing in the trace said which filter, sort or page they were. The step now carries them, and whether a search, not its words. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -185,7 +185,7 @@ a count says something happened, the lines and traces say why.
|
|||||||
`feed` or `fetch` span holding most of it (`$Q spans '{... && name="feed" && duration > 10s}'`),
|
`feed` or `fetch` span holding most of it (`$Q spans '{... && name="feed" && duration > 10s}'`),
|
||||||
or a `download` far slower than its size explains.
|
or a `download` far slower than its size explains.
|
||||||
|
|
||||||
Steps are `step` spans named by `of` (#187): an item list's `entries_in`, `sanitize`,
|
Steps are `step` spans named by `of` (#187): an item list's `entries_in` (with the list asked for: `filter`, `sort`, `dir`, `offset`, `limit`, `search`), `sanitize`,
|
||||||
`deadair`, `count_in`; the feed list's `catalogue`, `feed_list` and its queries; a `reap`'s
|
`deadair`, `count_in`; the feed list's `catalogue`, `feed_list` and its queries; a `reap`'s
|
||||||
`missing_files`, `prune_abandoned_failures`, `reap_candidates`, `clean_directory` (once a day
|
`missing_files`, `prune_abandoned_failures`, `reap_candidates`, `clean_directory` (once a day
|
||||||
since #193, so a reap is about a second), `trim_artwork`, with what it removed on the `reap`
|
since #193, so a reap is about a second), `trim_artwork`, with what it removed on the `reap`
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- A show from an OPML subscription or a Patreon creator can be kept: `kept` on `PATCH /api/feeds/{id}` and in the feed list. When the OPML drops a kept show, or you leave the OPML, it stays on your list as a feed of its own (#280).
|
- A show from an OPML subscription or a Patreon creator can be kept: `kept` on `PATCH /api/feeds/{id}` and in the feed list. When the OPML drops a kept show, or you leave the OPML, it stays on your list as a feed of its own (#280).
|
||||||
- `/metrics` counts Signals: items judged and fitting, calls to Jev by how they ended, the time they took and the tokens TypeSafe counted, time since the judge's last pass, and keys refused; a failed call to Jev shows as a failed trace (#270, #275).
|
- `/metrics` counts Signals: items judged and fitting, calls to Jev by how they ended, the time they took and the tokens TypeSafe counted, time since the judge's last pass, and keys refused; a failed call to Jev shows as a failed trace (#270, #275).
|
||||||
- An admin setting for how many days back a new Signal reads (#276).
|
- An admin setting for how many days back a new Signal reads (#276).
|
||||||
|
- A list's trace says which filter, sort and page it was asked for, and whether a search, so a slow list can be told from the others (#287).
|
||||||
- `/metrics` breaks Signals' items, fits and TypeSafe tokens out by person and by whose key paid, so the server's bill can be split (#278).
|
- `/metrics` breaks Signals' items, fits and TypeSafe tokens out by person and by whose key paid, so the server's bill can be split (#278).
|
||||||
- An admin setting, Signals for everyone on the server's TypeSafe key, so the server pays for Jev instead of each person (#271).
|
- An admin setting, Signals for everyone on the server's TypeSafe key, so the server pays for Jev instead of each person (#271).
|
||||||
|
|
||||||
|
|||||||
@@ -1502,17 +1502,23 @@ async fn entry_page(
|
|||||||
let order =
|
let order =
|
||||||
crate::db::order_sql(page.sort.as_deref().unwrap_or("published"), page.dir.as_deref().unwrap_or("desc"));
|
crate::db::order_sql(page.sort.as_deref().unwrap_or("published"), page.dir.as_deref().unwrap_or("desc"));
|
||||||
let limit = page.limit.clamp(1, 200);
|
let limit = page.limit.clamp(1, 200);
|
||||||
|
// Which list, so a slow one's trace says what was asked of it (#287). The search's words stay
|
||||||
|
// out: they are the reader's own.
|
||||||
|
let in_list = tracing::info_span!(
|
||||||
|
"step",
|
||||||
|
of = "entries_in",
|
||||||
|
filter = page.filter.as_deref().unwrap_or("all"),
|
||||||
|
sort = page.sort.as_deref().unwrap_or("published"),
|
||||||
|
dir = page.dir.as_deref().unwrap_or("desc"),
|
||||||
|
offset = page.offset,
|
||||||
|
limit,
|
||||||
|
search = search.is_some(),
|
||||||
|
);
|
||||||
let mut rows = match signal {
|
let mut rows = match signal {
|
||||||
Some(id) => {
|
Some(id) => {
|
||||||
db.signal_entries(user_id, id, filter, search, page.offset, limit, &order)
|
db.signal_entries(user_id, id, filter, search, page.offset, limit, &order).instrument(in_list).await?
|
||||||
.instrument(step("entries_in"))
|
|
||||||
.await?
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
db.entries_of(user_id, feeds, filter, search, page.offset, limit, &order)
|
|
||||||
.instrument(step("entries_in"))
|
|
||||||
.await?
|
|
||||||
}
|
}
|
||||||
|
None => db.entries_of(user_id, feeds, filter, search, page.offset, limit, &order).instrument(in_list).await?,
|
||||||
};
|
};
|
||||||
step("sanitize").in_scope(|| {
|
step("sanitize").in_scope(|| {
|
||||||
let mut sanitizer = feed_sanitizer();
|
let mut sanitizer = feed_sanitizer();
|
||||||
|
|||||||
Reference in New Issue
Block a user