Expand description
§tailtriage-core
tailtriage-core is the framework-agnostic capture foundation for tailtriage.
Use it when you want explicit request lifecycle instrumentation and bounded JSON artifacts without controller, Axum, or Tokio runtime-sampler APIs unless you add them separately.
§What this crate does
tailtriage-core owns capture-side lifecycle semantics:
- request admission
- queue/stage/inflight instrumentation
- explicit request completion
- bounded in-memory retention
- JSON run artifact writing
For in-process analysis/report generation, use tailtriage-analyzer.
For command-line analysis of saved artifacts, use tailtriage-cli.
§Crate selection
Use tailtriage-core when you want the smallest framework-agnostic capture surface.
Use tailtriage when you want the recommended default entry point: an aggregator/re-export crate with optional integrations behind features.
§Installation
cargo add tailtriage-core§Quick start
use tailtriage_core::Tailtriage;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let run = Tailtriage::builder("checkout-service")
.output("tailtriage-run.json")
.build()?;
let started = run.begin_request("/checkout");
started.completion.finish_ok();
run.shutdown()?;
Ok(())
}§Request lifecycle
begin_request(...) / begin_request_with(...) returns StartedRequest with:
started.handlefor queue/stage/inflight instrumentationstarted.completionfor explicit finish
For Arc<Tailtriage> flows that move request handles across spawned tasks or helper layers, use begin_request_owned(...) / begin_request_with_owned(...). Owned handles keep the same lifecycle rule: instrumentation does not finish the request, and the completion token must be finished exactly once.
use tailtriage_core::{RequestOptions, Tailtriage};
async fn demo() -> Result<(), Box<dyn std::error::Error>> {
let run = Tailtriage::builder("checkout-service")
.output("tailtriage-run.json")
.build()?;
let started = run.begin_request_with(
"/checkout",
RequestOptions::new().request_id("req-1").kind("http"),
);
let req = started.handle.clone();
req.queue("ingress").await_on(async {}).await;
req.stage("db")
.await_on(async { Ok::<(), std::io::Error>(()) })
.await?;
started.completion.finish_ok();
run.shutdown()?;
Ok(())
}§Output sinks
tailtriage-core captures run data and finalizes through a sink. It does not perform analysis/report generation.
LocalJsonSink(or builder.output(...)) writes Run artifact JSON to disk.MemorySinkstores finalized typedRunvalues in memory.DiscardSinkfinalizes lifecycle and drops the finalizedRunwithout persisting output.
MemorySink stores only the last finalized Run; each new finalized run replaces the previous stored value.
Use MemorySink when you want in-process analysis. DiscardSink drops finalized runs; use MemorySink instead when the finalized Run should be analyzed in process.
use tailtriage_core::{MemorySink, Tailtriage};
let sink = MemorySink::new();
let run = Tailtriage::builder("checkout-service")
.sink(sink.clone())
.build()?;
let started = run.begin_request("/checkout");
started.completion.finish_ok();
run.shutdown()?;
let finalized = sink.last_run();§Two easy-to-miss helpers
For infallible async work, StageTimer::await_value(...) avoids a dummy Result:
let value = req.stage("cache").await_value(async { 42 }).await;When queue depth is known at enqueue time, QueueTimer::with_depth_at_start(...) records it directly:
req.queue("ingress")
.with_depth_at_start(12)
.await_on(async {})
.await;§Lifecycle contract
queue(...),stage(...), andinflight(...)do not finish requests.- Every admitted request must be finished exactly once.
- Dropping a completion token does not auto-finish.
- Non-strict lifecycle:
shutdown()writes the artifact and records unfinished-request warnings/metadata. strict_lifecycle(true): unfinished requests causeshutdown()to return an error and no artifact is written.
Finalization timestamps:
- Active
snapshot()output is not finalized (metadata.finalized_at_unix_ms == None). shutdown()writes final artifacts with both:metadata.finished_at_unix_msset to shutdown timemetadata.finalized_at_unix_msset to that same timestamp
- Older artifacts may deserialize with
metadata.finalized_at_unix_ms == None. - When
finalized_at_unix_msis present, prefer that field as the finalization signal;finished_at_unix_msremains for backward compatibility.
§Capture modes
Modes change retention defaults only. They do not change lifecycle semantics and do not auto-start runtime sampling.
CaptureMode::LightCaptureMode::Investigation
Override limits with:
capture_limits(...)(full override)capture_limits_override(...)(field-level override)
§What this crate does not do
This crate does not provide:
- repeated arm/disarm controller windows
- Tokio runtime sampling
- Axum middleware/extractors
- analysis/report generation
Use sibling crates for those surfaces: tailtriage-controller, tailtriage-tokio, tailtriage-axum, tailtriage-analyzer, and tailtriage-cli.
Structs§
- Capture
Limits - Limits that bound in-memory capture growth for one run.
- Capture
Limits Override - Field-level capture limit overrides applied on top of mode defaults.
- Discard
Sink - Sink that finalizes capture lifecycle without writing a run artifact.
- Effective
Core Config - Stable, resolved core configuration used by one capture run.
- Effective
Tokio Sampler Config - Stable, resolved Tokio runtime sampler configuration used by one run.
- InFlight
Snapshot - Point-in-time in-flight gauge reading.
- Inflight
Guard - RAII guard tracking one in-flight unit for a named gauge.
- Local
Json Sink - Local file sink that writes one JSON document per run at shutdown.
- Memory
Sink - In-memory sink that stores only the last finalized run.
- Owned
Request Completion - Completion-facing request token backed by
Arc<Tailtriage>. - Owned
Request Handle - Instrumentation-facing request handle backed by
Arc<Tailtriage>. - Owned
Started Request - Split request lifecycle start result backed by
Arc<Tailtriage>. - Queue
Event - Queue wait measurement for a request waiting on a queue/permit.
- Queue
Timer - Thin wrapper for recording queue-wait latency around one await point.
- Request
Completion - Completion-facing request token.
- Request
Event - Per-request timing and status.
- Request
Handle - Instrumentation-facing request handle.
- Request
Options - Optional request start settings used by
crate::Tailtriage::begin_request_with. - Run
- A full output artifact for one tailtriage capture run.
- RunMetadata
- Top-level metadata for one capture run.
- Runtime
Snapshot - Point-in-time runtime metrics sample.
- Stage
Event - Timing record for one named stage.
- Stage
Timer - Thin wrapper for recording stage latency around one await point.
- Started
Request - Split request lifecycle start result.
- Tailtriage
- Per-run collector that records request events and writes the final artifact.
- Tailtriage
Builder - Builder for constructing a
crate::Tailtriagerun. - Truncation
Summary - Per-section counters indicating dropped samples due to capture limits.
- Unfinished
Request Sample - One unfinished request sample captured for lifecycle warnings.
- Unfinished
Requests - Summary of unfinished requests detected at shutdown.
Enums§
- Build
Error - Errors emitted while building one tailtriage capture instance.
- Capture
Mode - Capture mode used during a run.
- Outcome
- Logical request outcome categories used by the public API.
- RunEnd
Reason - Run lifecycle end reason recorded in artifact metadata.
- Runtime
Sampler Registration Error - Error returned when registering Tokio runtime sampler metadata.
- Sink
Error - Errors emitted while writing run artifacts.
Constants§
- SCHEMA_
VERSION - Current schema version for
RunJSON artifacts.
Traits§
- RunSink
- A sink that persists the final run artifact produced at shutdown.
Functions§
- system_
time_ to_ unix_ ms - Converts a
SystemTimeto unix epoch milliseconds. - unix_
time_ ms - Returns the current unix epoch timestamp in milliseconds.