use std::any::Any;
use std::borrow::Cow;
use crate::export::MetricWrapper;
macro_rules! used_in_docs {
($($item:ident),* $(,)?) => {
const _: () = {
#[allow(unused_imports)]
mod _docs {
$( use super::$item; )*
}
};
};
}
mod counter;
mod formatter;
mod gauge;
pub mod histogram;
mod lazy;
mod metadata;
mod metrics;
mod null;
extern crate self as metriken;
pub mod dynmetrics;
pub use crate::counter::Counter;
pub use crate::dynmetrics::{DynBoxedMetric, DynPinnedMetric, MetricBuilder};
pub use crate::formatter::{default_formatter, Format};
pub use crate::gauge::Gauge;
pub use crate::histogram::{AtomicHistogram, RwLockHistogram};
pub use crate::lazy::Lazy;
pub use crate::metadata::{Metadata, MetadataIter};
pub use crate::metrics::{metrics, DynMetricsIter, Metrics, MetricsIter};
pub use metriken_derive::metric;
pub type LazyCounter = Lazy<Counter>;
pub type LazyGauge = Lazy<Gauge>;
#[doc(hidden)]
pub mod export {
pub extern crate linkme;
pub extern crate phf;
use crate::{Metadata, Metric};
pub struct MetricWrapper(pub *const dyn Metric);
#[linkme::distributed_slice]
pub static METRICS: [crate::MetricEntry] = [..];
pub const fn entry(
metric: &'static dyn crate::Metric,
name: &'static str,
description: Option<&'static str>,
metadata: &'static phf::Map<&'static str, &'static str>,
formatter: fn(&crate::MetricEntry, crate::Format) -> String,
) -> crate::MetricEntry {
use std::borrow::Cow;
crate::MetricEntry {
metric: MetricWrapper(metric),
name: Cow::Borrowed(name),
description: match description {
Some(desc) => Some(Cow::Borrowed(desc)),
None => None,
},
metadata: Metadata::new_static(metadata),
formatter,
}
}
}
pub trait Metric: Send + Sync + 'static {
fn is_enabled(&self) -> bool {
self.as_any().is_some()
}
fn as_any(&self) -> Option<&dyn Any>;
fn value(&self) -> Option<Value>;
}
#[non_exhaustive]
#[derive(Clone)]
pub enum Value<'a> {
Counter(u64),
Gauge(i64),
AtomicHistogram(&'a AtomicHistogram),
RwLockHistogram(&'a RwLockHistogram),
Other,
}
pub struct MetricEntry {
metric: MetricWrapper,
name: Cow<'static, str>,
description: Option<Cow<'static, str>>,
metadata: Metadata,
formatter: fn(&Self, Format) -> String,
}
impl MetricEntry {
pub fn metric(&self) -> &dyn Metric {
unsafe { &*self.metric.0 }
}
pub fn name(&self) -> &str {
&self.name
}
pub fn description(&self) -> Option<&str> {
self.description.as_deref()
}
pub fn metadata(&self) -> &Metadata {
&self.metadata
}
pub fn formatted(&self, format: Format) -> String {
(self.formatter)(self, format)
}
pub fn is(&self, metric: &dyn Metric) -> bool {
if self.metric().type_id() != metric.type_id() {
return false;
}
let a = self.metric() as *const _ as *const ();
let b = metric as *const _ as *const ();
a == b
}
}
unsafe impl Send for MetricEntry {}
unsafe impl Sync for MetricEntry {}
impl std::ops::Deref for MetricEntry {
type Target = dyn Metric;
#[inline]
fn deref(&self) -> &Self::Target {
self.metric()
}
}
impl std::fmt::Debug for MetricEntry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MetricEntry")
.field("name", &self.name())
.field("metric", &"<dyn Metric>")
.finish()
}
}