use std::any::Any;
use crate::export::WrapMetric;
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 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::metrics::{metrics, DynMetricsIter, Metrics, MetricsIter};
#[doc(inline)]
pub use metriken_core::{Metadata, MetadataIter};
pub use metriken_derive::metric;
pub type LazyCounter = Lazy<Counter>;
pub type LazyGauge = Lazy<Gauge>;
#[doc(hidden)]
pub mod export {
pub use metriken_core::declare_metric_v1;
use crate::Metric;
use std::ops::{Deref, DerefMut};
pub struct WrapMetric<T>(T);
impl<T> WrapMetric<T> {
pub const fn new(value: T) -> Self {
Self(value)
}
}
impl<T> Deref for WrapMetric<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for WrapMetric<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T: Metric> metriken_core::Metric for WrapMetric<T> {
fn is_enabled(&self) -> bool {
<Self as Metric>::is_enabled(self)
}
fn as_any(&self) -> Option<&dyn std::any::Any> {
<Self as Metric>::as_any(self)
}
fn value(&self) -> Option<metriken_core::Value> {
let value = <Self as Metric>::value(self)?;
Some(match value {
crate::Value::Counter(val) => metriken_core::Value::Counter(val),
crate::Value::Gauge(val) => metriken_core::Value::Gauge(val),
_ => metriken_core::Value::Other(self),
})
}
}
}
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,
}
#[repr(transparent)]
pub struct MetricEntry(metriken_core::MetricEntry);
impl MetricEntry {
pub fn metric(&self) -> &CoreMetric {
CoreMetric::from_core(self.0.metric())
}
pub fn name(&self) -> &str {
self.0.name()
}
pub fn description(&self) -> Option<&str> {
self.0.description()
}
pub fn metadata(&self) -> &Metadata {
self.0.metadata()
}
pub fn formatted(&self, format: Format) -> String {
self.0.formatted(format)
}
pub fn is(&self, metric: &dyn Metric) -> bool {
let a = self.metric() as *const _ as *const ();
let b = metric as *const _ as *const ();
a == b
}
#[doc(hidden)]
pub fn from_core(core: &metriken_core::MetricEntry) -> &Self {
unsafe { std::mem::transmute(core) }
}
#[doc(hidden)]
pub fn as_core(&self) -> &metriken_core::MetricEntry {
&self.0
}
}
unsafe impl Send for MetricEntry {}
unsafe impl Sync for MetricEntry {}
impl std::ops::Deref for MetricEntry {
type Target = CoreMetric;
#[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()
}
}
impl<T: metriken_core::Metric> Metric for T {
fn is_enabled(&self) -> bool {
<Self as metriken_core::Metric>::is_enabled(self)
}
fn as_any(&self) -> Option<&dyn Any> {
<Self as metriken_core::Metric>::as_any(self)
}
fn value(&self) -> Option<Value> {
use metriken_core::Value as CoreValue;
Some(match <Self as metriken_core::Metric>::value(self)? {
CoreValue::Counter(val) => Value::Counter(val),
CoreValue::Gauge(val) => Value::Gauge(val),
CoreValue::Other(val) => {
if let Some(histogram) = val.downcast_ref::<AtomicHistogram>() {
Value::AtomicHistogram(histogram)
} else if let Some(histogram) = val.downcast_ref::<RwLockHistogram>() {
Value::RwLockHistogram(histogram)
} else {
Value::Other
}
}
_ => Value::Other,
})
}
}
#[repr(transparent)]
pub struct CoreMetric(dyn metriken_core::Metric);
impl CoreMetric {
fn from_core(core: &dyn metriken_core::Metric) -> &Self {
unsafe { std::mem::transmute(core) }
}
pub fn is_enabled(&self) -> bool {
<Self as metriken_core::Metric>::is_enabled(self)
}
pub fn as_any(&self) -> Option<&dyn Any> {
<Self as metriken_core::Metric>::as_any(self)
}
pub fn value(&self) -> Option<Value> {
use metriken_core::Value as CoreValue;
Some(match <Self as metriken_core::Metric>::value(self)? {
CoreValue::Counter(val) => Value::Counter(val),
CoreValue::Gauge(val) => Value::Gauge(val),
CoreValue::Other(val) => {
if let Some(histogram) = val.downcast_ref::<AtomicHistogram>() {
Value::AtomicHistogram(histogram)
} else if let Some(histogram) = val.downcast_ref::<RwLockHistogram>() {
Value::RwLockHistogram(histogram)
} else {
Value::Other
}
}
_ => Value::Other,
})
}
}
impl metriken_core::Metric for CoreMetric {
fn is_enabled(&self) -> bool {
self.0.is_enabled()
}
fn as_any(&self) -> Option<&dyn Any> {
self.0.as_any()
}
fn value(&self) -> Option<metriken_core::Value> {
self.0.value()
}
}