use async_trait::async_trait;
use opentelemetry::metrics::Result;
use opentelemetry_sdk::metrics::{
data::{ResourceMetrics, Temporality},
exporter::PushMetricsExporter,
reader::{AggregationSelector, TemporalitySelector},
Aggregation, InstrumentKind,
};
use std::fmt::{Debug, Formatter};
#[async_trait]
pub trait MetricsClient: core::fmt::Debug + Send + Sync + 'static {
async fn export(&self, metrics: &mut ResourceMetrics) -> Result<()>;
}
pub struct MetricsExporter {
pub(crate) client: Box<dyn MetricsClient>,
pub(crate) temporality_selector: Box<dyn TemporalitySelector>,
pub(crate) aggregation_selector: Box<dyn AggregationSelector>,
}
impl Debug for MetricsExporter {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MetricsExporter").finish()
}
}
impl TemporalitySelector for MetricsExporter {
fn temporality(&self, kind: InstrumentKind) -> Temporality {
self.temporality_selector.temporality(kind)
}
}
impl AggregationSelector for MetricsExporter {
fn aggregation(&self, kind: InstrumentKind) -> Aggregation {
self.aggregation_selector.aggregation(kind)
}
}
#[async_trait]
impl PushMetricsExporter for MetricsExporter {
async fn export(&self, metrics: &mut ResourceMetrics) -> Result<()> {
self.client.export(metrics).await
}
async fn force_flush(&self) -> Result<()> {
Ok(())
}
fn shutdown(&self) -> Result<()> {
Ok(())
}
}
impl MetricsExporter {
pub fn new(
client: impl MetricsClient,
temporality_selector: Box<dyn TemporalitySelector>,
aggregation_selector: Box<dyn AggregationSelector>,
) -> MetricsExporter {
MetricsExporter {
client: Box::new(client),
temporality_selector,
aggregation_selector,
}
}
}