///|
/// Metric family kinds supported by the P0 data model.
pub(all) enum MetricKind {
CounterKind
GaugeKind
HistogramKind
} derive(Debug, Eq, Hash)
///|
/// Canonical identity used to compare descriptor registration intent.
///
/// Const-label order does not affect this value. Variable-label order does:
/// values supplied to a vector are positional in that declared order.
pub(all) struct DescriptorIdentity {
name : String
kind : MetricKind
const_labels : Array[Label]
variable_label_names : Array[String]
} derive(Debug, Eq)
///|
/// Immutable identity and exposition metadata for one metric family.
pub struct Descriptor {
name : String
help : String
unit : String?
kind : MetricKind
const_labels : Array[Label]
variable_label_names : Array[String]
}
///|
pub fn Descriptor::new(
name : String,
kind : MetricKind,
help? : String = "",
unit? : String,
const_labels? : Array[Label] = [],
variable_label_names? : Array[String] = [],
) -> Descriptor raise MetricError {
validate_metric_name(name)
validate_help(help)
match unit {
Some(value) => validate_unit(value)
None => ()
}
let canonical_labels = canonical_const_labels(const_labels)
validate_variable_label_names(variable_label_names)
for label_name in variable_label_names {
for label in const_labels {
if label.name == label_name {
raise DuplicateLabelName(label_name)
}
}
}
{
name,
help,
unit,
kind,
const_labels: canonical_labels,
variable_label_names: variable_label_names.copy(),
}
}
///|
pub fn Descriptor::name(self : Descriptor) -> String {
self.name
}
///|
pub fn Descriptor::help(self : Descriptor) -> String {
self.help
}
///|
pub fn Descriptor::unit(self : Descriptor) -> String? {
self.unit
}
///|
pub fn Descriptor::kind(self : Descriptor) -> MetricKind {
self.kind
}
///|
pub fn Descriptor::const_labels(self : Descriptor) -> Array[Label] {
self.const_labels.copy()
}
///|
pub fn Descriptor::variable_label_names(self : Descriptor) -> Array[String] {
self.variable_label_names.copy()
}
///|
pub fn Descriptor::identity(self : Descriptor) -> DescriptorIdentity {
{
name: self.name,
kind: self.kind,
const_labels: self.const_labels.copy(),
variable_label_names: self.variable_label_names.copy(),
}
}
///|
/// Build a descriptor for a concrete metric without variable labels.
///
/// MoonBit optional arguments accept their contained type at call sites, so
/// this helper is the single place that unwraps a public `String?` unit.
fn make_metric_descriptor(
name : String,
kind : MetricKind,
help : String,
unit : String?,
const_labels : Array[Label],
) -> Descriptor raise MetricError {
match unit {
Some(value) => Descriptor::new(name, kind, help~, unit=value, const_labels~)
None => Descriptor::new(name, kind, help~, const_labels~)
}
}