Skip to content
You are viewing the corvid 0.3.2 release snapshot — frozen at the 0.3.2 engine release.Current documentation

Observability

corvid observability has three layers, none requiring a server:

  1. Query introspectionexplain() / plan_shape() / plan() (always on).
  2. Structured events — the tracing cargo feature (see feature flags).
  3. Counters via subscribers — aggregate the events; no metrics-export subsystem (deliberate non-goal).
# use corvid::{Db, field};
# let db = Db::open_in_memory()?; let docs = db.collection("docs");
let mut q = docs.query().filter(field("a").exists());
let plan = q.explain()?; // human-readable, pinned to the real decision
let shape = q.plan_shape()?; // PlanShape enum
# let _ = (plan, shape);
# Ok::<(), corvid::Error>(())

PlanShape labels what drove the candidate set: AnnIndex, TextIndex, IndexedWindow, SortIndex, StreamingTopK, Scan. QueryPlan (via plan()) is identity-hashable — key a PlanCache on it to cache prepared per-shape work (never results).

With features = ["tracing"], these events fire (target corvid):

EventCarries
Index backfill spanscollection, index family (scalar/compound/text/geo/vector), page size, cursor progress; completion event with page count
Compactions (in-memory + on-disk)dead/live trigger math on the actual crossing, rebuild outcome
Lazy index-build resume / adjacency rebuildincluding whether the marker was absent or stale-shaped
Plan-shape selection (one per query)which arm drove candidates + candidate count
Order-index walk tail scanthe on-exhaustion fallback
Edge-cascade rebuild fallbackcorrupt adjacency row recovery
Semantic cachehit/miss with the deciding distance

Two deliberate label divergences from PlanShape: indexed_window events carry no family discriminator (the scalar/compound/geo/or kind is plan_shape()’s to report), and stream_scan is finer than PlanShape::Scan (it splits the bounded streaming filter pass from the materializing fallback).

A subscriber aggregating plan_shape per shape is the index-probe counter per shape; semantic_cache_hit/semantic_cache_miss subscribers are the cache-hit-rate counters. Deferred (with triggers): plan-cache hit counters (PlanCache is host-side state — the engine sees no traffic to count) and any metrics-export subsystem.

No .profile() (the events above carry what a profiler would; reopens only if a need outgrows them), no metrics export, no server to poll. The engine is a library — your process’s observability stack is the stack.

Next: the MCP sidecar.