Skip to main content

Histogram

Struct Histogram 

Source
#[non_exhaustive]
pub struct Histogram { pub schema: i8, pub zero_threshold: f64, pub zero_count: f64, pub count: f64, pub sum: f64, pub positive: Vec<Bucket>, pub negative: Vec<Bucket>, pub custom_values: Vec<f64>, pub reset_hint: ResetHint, }
Expand description

A distribution captured as one sample.

See the module documentation for the model and the two representation decisions.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§schema: i8

Bucket resolution — see CUSTOM_BUCKETS_SCHEMA, MIN_SCHEMA, MAX_SCHEMA.

§zero_threshold: f64

Half-width of the zero bucket, which covers [-t, +t] inclusive.

§zero_count: f64

Observations in the zero bucket.

§count: f64

Total observations, including the zero bucket.

§sum: f64

Sum of all observations. May be NaN if any observation was.

§positive: Vec<Bucket>

Buckets for positive observations, ascending by index, none zero.

§negative: Vec<Bucket>

Buckets for negative observations, ascending by index, none zero.

Index i covers [-base^i, -base^(i-1)) — the mirror of the positive side, so larger indices are more negative.

§custom_values: Vec<f64>

Upper-inclusive boundaries, when schema == CUSTOM_BUCKETS_SCHEMA.

Ascending. Bucket i of positive covers (custom_values[i-1], custom_values[i]], with -Inf below the first and +Inf above the last.

§reset_hint: ResetHint

What is known about counter resets before this sample.

Implementations§

Source§

impl Histogram

Source

pub fn empty(schema: i8) -> Self

An empty histogram at the given schema.

Source

pub const fn has_custom_buckets(&self) -> bool

Whether the boundaries are listed rather than computed.

Source

pub fn base(schema: i8) -> f64

The growth factor between consecutive exponential bucket bounds.

2^(2^-schema). Meaningless for CUSTOM_BUCKETS_SCHEMA.

Source

pub fn index_for(schema: i8, value: f64) -> i32

The index of the bucket an observation falls in.

From the specification’s boundary rule — bucket i covers (base^(i-1), base^i] — inverted: i = ⌈log₂(v) · 2^schema⌉.

value must be finite and strictly positive; callers route zero and near-zero observations to the zero bucket first.

Source

pub fn bucket_bounds(&self, index: i32, negative: bool) -> (f64, f64)

The (lower, upper) bounds of a bucket, lower exclusive, upper inclusive.

For the negative side, pass negative = true: index i then covers [-base^i, -base^(i-1)).

Source

pub fn bound(schema: i8, index: i32) -> f64

The upper bound of bucket index: 2^(index / 2^schema).

Computed without a transcendental, which is the point. powf and powi are not correctly rounded and their last bit is not specified by IEEE 754 or by Rust, so the same stored histogram could report different boundaries on two machines — and a bucket boundary is a storage-format semantic, not a display detail. It showed up as bucket_bounds(0) returning 0.4999999999999999 instead of 0.5 at schema 0, where the answer is an exact power of two.

Instead, index is split as index = q · 2^schema + r, giving 2^q · 2^(r / 2^schema). The first factor is built straight from the IEEE exponent field, and the second from repeated sqrt — the one root operation IEEE 754 does require to be correctly rounded. Every step is exact or correctly rounded, so the result is identical on every platform.

Source

pub fn observe(&mut self, value: f64)

Record one observation.

Present so a histogram can be built in a test or by a connector that receives raw values; ingest from Prometheus or OTLP builds the buckets directly.

Source

pub fn canonicalise(&mut self)

Put the histogram in canonical form: sorted by index, no empty buckets.

Merges duplicate indices rather than dropping one, because a wire decoder that produced two entries for one bucket meant their sum.

Source

pub fn validate(&self) -> Result<(), HistogramError>

Check every invariant the rest of the engine relies on.

§Errors

See HistogramError. The checks are the ones whose violation would produce a plausible wrong number rather than a crash: an unsorted bucket list interpolates to the wrong quantile, and a count smaller than its buckets makes every rank fraction exceed one.

Source

pub fn avg(&self) -> f64

The mean observation, or NaN for an empty histogram.

Source

pub fn variance(&self) -> f64

Variance of the observations, estimated from bucket representatives.

Source

pub fn stddev(&self) -> f64

Standard deviation of the observations.

Source

pub fn quantile(&self, q: f64) -> f64

The φ-quantile of the observations.

Follows Prometheus’s histogramQuantile: q < 0 is -Inf, q > 1 is +Inf, and an empty histogram or a NaN φ is NaN. The value is found by walking buckets in ascending order until the cumulative count reaches q · count, then interpolating inside that bucket.

Source

pub fn fraction(&self, lower: f64, upper: f64) -> f64

The fraction of observations in [lower, upper).

NaN for an empty histogram or a NaN bound; 0 when the interval is empty or inverted.

Source

pub fn classic_buckets(&self) -> Vec<(f64, f64)>

The classic le-bucketed view of this histogram.

Returns (le, cumulative_count) pairs ascending, ending at +Inf. This is what makes a dashboard written against foo_bucket keep working once the storage holds a native histogram — the classic exposition is a view, not a second stored form, which is also upstream’s direction for composite samples.

Source

pub fn merge(&mut self, other: &Self) -> Result<(), HistogramError>

Add other into self.

Defined only for histograms that share a schema and zero threshold — two different resolutions cannot be added without re-bucketing, and re-bucketing to the coarser of the two is a decision rather than something to do silently inside +.

§Errors

HistogramError::CustomValues when the schemas or boundaries differ.

Trait Implementations§

Source§

impl Clone for Histogram

Source§

fn clone(&self) -> Histogram

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Histogram

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Histogram

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for Histogram

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for Histogram

Source§

fn eq(&self, other: &Histogram) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for Histogram

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Histogram

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more