use std::{
mem::transmute,
ptr::{null, null_mut},
sync::Arc,
};
use crate::{parameter::Parameter, sys, to_cstring, Error};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u32)]
enum Format {
Prometheus = sys::tritonserver_metricformat_enum_TRITONSERVER_METRIC_PROMETHEUS,
}
#[derive(Debug, Clone)]
pub struct PrometheusMetrics(pub(crate) Arc<*mut sys::TRITONSERVER_Metrics>);
unsafe impl Send for PrometheusMetrics {}
unsafe impl Sync for PrometheusMetrics {}
impl PrometheusMetrics {
pub fn formatted(&self) -> Result<&[u8], Error> {
let format = Format::Prometheus;
#[cfg(target_arch = "x86_64")]
let mut ptr = null::<i8>();
#[cfg(target_arch = "aarch64")]
let mut ptr = null::<u8>();
let mut size: usize = 0;
triton_call!(sys::TRITONSERVER_MetricsFormatted(
*self.0,
format as _,
&mut ptr as *mut _,
&mut size as *mut _,
))?;
assert!(!ptr.is_null());
Ok(unsafe { std::slice::from_raw_parts(ptr as *const u8, size) })
}
}
impl Drop for PrometheusMetrics {
fn drop(&mut self) {
if !self.0.is_null() && Arc::strong_count(&self.0) == 1 {
unsafe { sys::TRITONSERVER_MetricsDelete(*self.0) };
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum MetricKind {
Counter = sys::TRITONSERVER_metrickind_enum_TRITONSERVER_METRIC_KIND_COUNTER,
Gauge = sys::TRITONSERVER_metrickind_enum_TRITONSERVER_METRIC_KIND_GAUGE,
Histogram = sys::TRITONSERVER_metrickind_enum_TRITONSERVER_METRIC_KIND_HISTOGRAM,
}
#[derive(Debug, Clone)]
pub struct MetricFamily(Arc<*mut sys::TRITONSERVER_MetricFamily>);
unsafe impl Send for MetricFamily {}
unsafe impl Sync for MetricFamily {}
impl MetricFamily {
pub fn new<N: AsRef<str>, D: AsRef<str>>(
kind: MetricKind,
name: N,
description: D,
) -> Result<Self, Error> {
let c_name = to_cstring(name)?;
let descr = to_cstring(description)?;
let mut res = null_mut::<sys::TRITONSERVER_MetricFamily>();
triton_call!(
sys::TRITONSERVER_MetricFamilyNew(
&mut res as *mut _,
kind as _,
c_name.as_ptr(),
descr.as_ptr()
),
Self(Arc::new(res))
)
}
pub fn kind(&self) -> Result<MetricKind, Error> {
let mut res = 0;
triton_call!(sys::TRITONSERVER_GetMetricFamilyKind(*self.0, &mut res))?;
Ok(unsafe { transmute::<u32, MetricKind>(res) })
}
}
impl Drop for MetricFamily {
fn drop(&mut self) {
if !self.0.is_null() && Arc::strong_count(&self.0) == 1 {
unsafe { sys::TRITONSERVER_MetricFamilyDelete(*self.0) };
}
}
}
#[derive(Debug, Clone)]
pub struct MetricArgs(Arc<*mut sys::TRITONSERVER_MetricArgs>);
unsafe impl Send for MetricArgs {}
unsafe impl Sync for MetricArgs {}
impl MetricArgs {
pub fn new() -> Result<Self, Error> {
let mut res = null_mut::<sys::TRITONSERVER_MetricArgs>();
triton_call!(
sys::TRITONSERVER_MetricArgsNew(&mut res),
Self(Arc::new(res))
)
}
pub fn set_histogram<B: AsRef<[f64]>>(&mut self, buckets: B) -> Result<&mut Self, Error> {
let buckets = buckets.as_ref();
triton_call!(
sys::TRITONSERVER_MetricArgsSetHistogram(*self.0, buckets.as_ptr(), buckets.len() as _),
self
)
}
}
impl Drop for MetricArgs {
fn drop(&mut self) {
if !self.0.is_null() && Arc::strong_count(&self.0) == 1 {
unsafe { sys::TRITONSERVER_MetricArgsDelete(*self.0) };
}
}
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct Metric(Arc<*mut sys::TRITONSERVER_Metric>, MetricFamily);
unsafe impl Send for Metric {}
unsafe impl Sync for Metric {}
impl Metric {
pub fn new<P: AsRef<[Parameter]>>(family: &MetricFamily, labels: P) -> Result<Self, Error> {
let mut res = null_mut::<sys::TRITONSERVER_Metric>();
let mut labels = labels
.as_ref()
.iter()
.map(|p| *p.ptr as *const _)
.collect::<Vec<_>>();
triton_call!(
sys::TRITONSERVER_MetricNew(
&mut res,
*family.0,
labels.as_mut_ptr(),
labels.len() as _
),
Self(Arc::new(res), family.clone())
)
}
pub fn new_with_args<P: AsRef<[Parameter]>>(
family: &MetricFamily,
labels: P,
args: &MetricArgs,
) -> Result<Self, Error> {
let mut res = null_mut::<sys::TRITONSERVER_Metric>();
let mut labels = labels
.as_ref()
.iter()
.map(|p| *p.ptr as *const _)
.collect::<Vec<_>>();
triton_call!(
sys::TRITONSERVER_MetricNewWithArgs(
&mut res,
*family.0,
labels.as_mut_ptr(),
labels.len() as _,
*args.0 as *const _
),
Self(Arc::new(res), family.clone())
)
}
pub fn kind(&self) -> Result<MetricKind, Error> {
let mut res = 0;
triton_call!(sys::TRITONSERVER_GetMetricKind(*self.0, &mut res))?;
Ok(unsafe { transmute::<u32, MetricKind>(res) })
}
pub fn value(&self) -> Result<f64, Error> {
let mut res = 0.;
triton_call!(sys::TRITONSERVER_MetricValue(*self.0, &mut res), res)
}
pub fn increment_by(&self, value: f64) -> Result<(), Error> {
triton_call!(sys::TRITONSERVER_MetricIncrement(*self.0, value))
}
pub fn set(&self, value: f64) -> Result<(), Error> {
triton_call!(sys::TRITONSERVER_MetricSet(*self.0, value))
}
pub fn observe(&self, value: f64) -> Result<(), Error> {
triton_call!(sys::TRITONSERVER_MetricObserve(*self.0, value))
}
}
impl Drop for Metric {
fn drop(&mut self) {
if !self.0.is_null() && Arc::strong_count(&self.0) == 1 {
unsafe { sys::TRITONSERVER_MetricDelete(*self.0) };
}
}
}