pub struct Exposition { /* private fields */ }telemetry only.Expand description
One or more configurations’ ConfigStatus, as
Prometheus text.
Built per scrape and thrown away: every sample comes from
status, which is atomic loads and no I/O,
so there is no state here worth keeping between scrapes and nothing to
go stale.
§What it emits
| Name | Type | Extra label | Value |
|---|---|---|---|
dynamic_config_installs_total | counter | installs since the process started | |
dynamic_config_last_success_seconds | gauge | seconds since the serving snapshot landed | |
dynamic_config_consecutive_failures | gauge | failures since the last install; zero is healthy | |
dynamic_config_last_failure_seconds | gauge | seconds since the last failure | |
dynamic_config_last_reload_info | gauge | reason | 1 |
dynamic_config_last_failure_info | gauge | kind | 1 |
The two _seconds families and the two failure families are absent
rather than zero where the fact does not exist yet: a configuration that
has never been installed has no staleness, and zero would read as
“installed just now”, which is the opposite. last_success_seconds is
the one an alert is written against — this service’s configuration has
been stale for an hour is the page that matters, and nothing else here
implies it.
A RemoteStatus added through add_remote renders
as six more families, and the labels are the caller’s in exactly the same
way:
| Name | Type | Extra label | Value |
|---|---|---|---|
dynamic_config_remote_up | gauge | 1 if the store answered last time, 0 if not | |
dynamic_config_remote_fetches_total | counter | documents the store has handed over | |
dynamic_config_remote_last_fetch_seconds | gauge | seconds since it last handed one over | |
dynamic_config_remote_last_fetch_duration_seconds | gauge | how long the last pull took | |
dynamic_config_remote_consecutive_failures | gauge | fetches that returned nothing since one did | |
dynamic_config_remote_last_failure_info | gauge | kind | 1 |
remote_up is absent before the first fetch, on the same principle
as the two _seconds families: a source that has been installed and
never asked is not down, and a 0 that means “not yet” is a page nobody
should be woken by.
§Cardinality
Bounded by the caller, and stated so it can be checked. For C
configurations and R remote sources added — R ≤ C, because a
configuration type has one Remote:
| per scrape | over a process’s life | |
|---|---|---|
a ConfigStatus | 6 × C | (4 + 5 + 10) × C = 19 × C |
a RemoteStatus | 6 × R | (5 + 10) × R = 15 × R |
so at most 6 × C + 6 × R ≤ 12 × C series in a scrape and 34 × C
distinct series in total. The label sets come from fixed enums — five
reload reasons and ten
error kinds — and C is the number of
configurations a process has, which is a handful.
A per-store series multiplies by a bounded number, which is why it exists; a per-key one would not, which is why there is no method here that could make one.
No key path, file name, store key or configured value is ever a label, and there is no method here that could make one: labels are the caller’s own, and everything derived from a status is a count, a duration or a fixed enum’s name.
§Example
use dynamic_config::{telemetry::Exposition, ConfigCell};
static PORT: ConfigCell<u16> = ConfigCell::new();
PORT.store(8080);
let mut exposition = Exposition::new();
exposition.add("listener", &PORT.status());
let rendered = exposition.render();
assert!(rendered.contains(r#"dynamic_config_installs_total{config="listener"} 1"#));Implementations§
Source§impl Exposition
impl Exposition
Sourcepub fn add(&mut self, config: &str, status: &ConfigStatus)
pub fn add(&mut self, config: &str, status: &ConfigStatus)
Adds one configuration, labelled config="…".
The name is the caller’s: a section key, a service name, whatever distinguishes this configuration from the others in the process. Not a path or anything derived from the document.
Sourcepub fn add_with(&mut self, labels: &[(&str, &str)], status: &ConfigStatus)
pub fn add_with(&mut self, labels: &[(&str, &str)], status: &ConfigStatus)
add, with labels of the caller’s choosing.
For a process whose configurations need two dimensions rather than
one — a config server’s application and profile, say. Label names
are sanitised to Prometheus’s [a-zA-Z_][a-zA-Z0-9_]* and values are
escaped, so no caller can break out of the exposition; the
cardinality of what is passed stays the caller’s own decision, and
the type’s documentation says what a safe one looks like.
Sourcepub fn add_remote(&mut self, config: &str, status: &RemoteStatus)
pub fn add_remote(&mut self, config: &str, status: &RemoteStatus)
Adds one remote source, labelled config="…".
The same name the configuration’s own add was given,
so the two halves join in a query: dynamic_config_remote_up and
dynamic_config_last_success_seconds for one config are the store
answered and the document installed, which is the pair an
operator is comparing.
Not the store’s URL, and there is no overload that takes one: a
store URL routinely embeds user:password@host, so the name a series
carries is the caller’s own — the same rule, and the same reason, as
for a key path.
Sourcepub fn add_remote_with(
&mut self,
labels: &[(&str, &str)],
status: &RemoteStatus,
)
pub fn add_remote_with( &mut self, labels: &[(&str, &str)], status: &RemoteStatus, )
add_remote, with labels of the caller’s
choosing — as add_with is to add.
Trait Implementations§
Source§impl Clone for Exposition
impl Clone for Exposition
Source§fn clone(&self) -> Exposition
fn clone(&self) -> Exposition
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for Exposition
impl Debug for Exposition
Source§impl Default for Exposition
impl Default for Exposition
Source§fn default() -> Exposition
fn default() -> Exposition
Auto Trait Implementations§
impl Freeze for Exposition
impl RefUnwindSafe for Exposition
impl Send for Exposition
impl Sync for Exposition
impl Unpin for Exposition
impl UnsafeUnpin for Exposition
impl UnwindSafe for Exposition
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);