pub trait Supervisor:
Send
+ Sync
+ 'static {
// Required methods
fn name(&self) -> Name;
fn child(&self, label: &'static str) -> Self;
fn with_attribute(self, key: &'static str, value: impl Display) -> Self;
}Expand description
Interface to track task hierarchy and identity.
Required Methods§
Sourcefn child(&self, label: &'static str) -> Self
fn child(&self, label: &'static str) -> Self
Create a named child context with a new supervision-tree node.
This appends label to the current metric prefix and creates a
child in the supervision tree. Use static role names like
"engine", "worker", or "resolver". Dynamic values belong in
Supervisor::with_attribute so metric names remain bounded.
Labels must start with [a-zA-Z] and contain only
[a-zA-Z0-9_]. Runtime-reserved metric prefixes must not be used.
Sourcefn with_attribute(self, key: &'static str, value: impl Display) -> Self
fn with_attribute(self, key: &'static str, value: impl Display) -> Self
Add a key-value attribute to this context’s identity.
Attributes are attached to metrics registered in this context and
any child contexts. Unlike Supervisor::child, attributes do not
affect metric names and do not create a supervision-tree edge. This
makes them the right place for dynamic values like epochs, rounds,
shards, or peer identifiers.
Keys must start with [a-zA-Z] and contain only [a-zA-Z0-9_].
Values can be any string. If the key already exists, its value is
replaced.
context
|-- child("orchestrator")
|-- with_attribute("epoch", "5")
|-- counter: votes -> orchestrator_votes{epoch="5"}
|-- counter: proposals -> orchestrator_proposals{epoch="5"}
|-- child("engine")
|-- gauge: height -> orchestrator_engine_height{epoch="5"}This pattern avoids wrapping every metric in a Family and avoids
putting dynamic values in metric names like
orchestrator_epoch_5_votes.
Attributes do not reduce cardinality. N epochs still means N time series. They just make metrics easier to query, filter, and aggregate.
§Family Label Conflicts
When using Family metrics, avoid attribute keys that match the
family’s label field names. A conflict produces duplicate labels in
the encoded output, which is invalid Prometheus format.
#[derive(EncodeLabelSet)]
struct Labels { env: String }
// Bad: attribute "env" conflicts with Family field "env".
let ctx = context.child("api").with_attribute("env", "prod");
let family: Family<Labels, Counter> = Family::default();
ctx.register("requests", "help", family);
// Good: use distinct names.
let ctx = context.child("api").with_attribute("region", "us_east");§Querying The Latest Attribute
To query the latest attribute value dynamically, create a gauge to track the current value:
let latest_epoch = context
.child("orchestrator")
.register("latest_epoch", "current epoch", Gauge::default());
latest_epoch.set(current_epoch);A dashboard can then query max(orchestrator_latest_epoch) and use
the result as a variable in queries such as
consensus_engine_votes_total{epoch="$latest_epoch"}.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".