~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

Each sync of a mirror is logged, with its time reading records

Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:serve/mirror-sync-line
crates/knotless/src/telemetry.rs+3−0
@@ -56,6 +56,8 @@ pub struct Fields<'a> {
pub max_ms: Option<u64>,
pub lag_ms: Option<u64>,
pub duration_ms: Option<u64>,
/// Of a mirror's sync, the part spent reading its records.
pub records_ms: Option<u64>,
pub exit_code: Option<i64>,
pub connected: Option<bool>,
pub rebuilt: Option<bool>,
@@ -95,6 +97,7 @@ macro_rules! event {
max_ms = $f.max_ms,
lag_ms = $f.lag_ms,
duration_ms = $f.duration_ms,
records_ms = $f.records_ms,
exit_code = $f.exit_code,
connected = $f.connected,
rebuilt = $f.rebuilt,
crates/knotless-serve/src/lib.rs+14−0
@@ -58,6 +58,7 @@ use knotless::mirror::Mirror;
use knotless::records::RepoRecord;
use knotless::records::nsid::PROFILES;
use knotless::remote::Remote;
use knotless::telemetry::{Fields, Level, millis, note, slow};
use knotless::url::RepoUrl;
use std::collections::HashMap;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
@@ -568,8 +569,10 @@ impl App {
url: &RepoUrl,
entry: &mut Entry,
) -> Result<(), AppError> {
let started = Instant::now();
let snap = remote.snapshot(ctx).await.map_err(AppError::upstream)?;
let (remote, snap) = remote.follow(ctx, snap).await.map_err(AppError::upstream)?;
let records = started.elapsed();
let Some(repo) = &snap.repo else {
// Not there, as of now.
entry.git = None;
@@ -594,6 +597,17 @@ impl App {
entry.storage = knotless::storage::of_snapshot(&snap);
entry.git = Some(mirror.git);
entry.synced = Some(Instant::now());
// Every read of the repository waits on its sync: how long each
// takes, and how much of that is its records, at warn when slow.
let took = started.elapsed();
let f = Fields {
repo: Some(&url.to_string()),
duration_ms: Some(millis(took)),
records_ms: Some(millis(records)),
..Fields::default()
};
let level = [Level::INFO, Level::WARN][usize::from(slow(took))];
note(level, "mirror sync", &f);
Ok(())
}
deploy/README.md+5−0
@@ -706,6 +706,11 @@ What serve logs:
- `mcp tool failed` at warn, one a tool call that failed: `gen_ai.tool.name`,
`did`, `error` (what the tool answered, as the client saw it),
`duration_ms` and `trace_id`.
- `mirror sync`, one each sync of a repository's mirror: `repo`,
`duration_ms`, and `records_ms`, the part spent reading its records. At
info, or warn when slow. Reads of the repository wait on a sync under
way, so it explains a burst of slow requests for one repository that
end together.
- `cache fill failed` at warn, with why: an avatar, claim or picture that
could not be read.
- `knotless-serve starting` (`version`, `commit`), `index opened`
docs/observability.md+7−0
@@ -28,6 +28,13 @@ to read it is in [deploy/README.md](../deploy/README.md#logs).
with why. The MCP server calls each tool in a task of its own, so the
request's trace is handed to it: the call's line, and its calls and
slow statements, are in the trace of the `/mcp` request that made it.
- **A line for each sync of a mirror**: `mirror sync`, with the
repository, `duration_ms` and `records_ms`, the part of it spent reading
the repository's records. At info, or at warn when slow. Each read of a
repository waits for a sync it finds under way, so a burst of slow
requests for one repository that all end together is explained by the
sync before it. A sync started by a write the feed brought is in no
request's trace.
- **A line for each call made**, to a PDS, the PLC directory, Bluesky or
a handle's host, from the one place every call goes through
(`knotless::telemetry::send`): host, path, XRPC method, status, error,
lexicons/dev/knotless/getLogs.json+1−0
@@ -22,6 +22,7 @@
"git",
"mcp tool",
"mcp tool failed",
"mirror sync",
"logs read"
]
},