#![doc = include_str!("../README.md")]
mod collector;
use std::sync::Arc;
use metrics::{describe_gauge, gauge, Unit};
#[cfg(not(feature = "use-gauge-on-cpu-seconds-total"))]
use metrics::{counter, describe_counter};
#[derive(Debug, PartialEq, Eq)]
struct Metrics {
cpu_seconds_total: Arc<str>,
open_fds: Arc<str>,
max_fds: Arc<str>,
virtual_memory_bytes: Arc<str>,
virtual_memory_max_bytes: Arc<str>,
resident_memory_bytes: Arc<str>,
start_time_seconds: Arc<str>,
threads: Arc<str>,
}
impl Metrics {
fn new(prefix: impl AsRef<str>) -> Self {
let prefix = prefix.as_ref();
Self {
cpu_seconds_total: format!("{prefix}process_cpu_seconds_total").into(),
open_fds: format!("{prefix}process_open_fds").into(),
max_fds: format!("{prefix}process_max_fds").into(),
virtual_memory_bytes: format!("{prefix}process_virtual_memory_bytes").into(),
virtual_memory_max_bytes: format!("{prefix}process_virtual_memory_max_bytes").into(),
resident_memory_bytes: format!("{prefix}process_resident_memory_bytes").into(),
start_time_seconds: format!("{prefix}process_start_time_seconds").into(),
threads: format!("{prefix}process_threads").into(),
}
}
}
impl Default for Metrics {
fn default() -> Self {
Self::new("")
}
}
#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct Collector {
metrics: Arc<Metrics>,
}
impl Collector {
#[deprecated(since = "1.1.0", note = "Use `Collector::new(prefix)`.")]
pub fn prefix(self, prefix: impl Into<String>) -> Self {
let _ = self;
Self::new(prefix.into())
}
pub fn new(prefix: impl AsRef<str>) -> Self {
Self {
metrics: Arc::new(Metrics::new(prefix)),
}
}
pub fn describe(&self) {
let metrics = self.metrics.as_ref();
#[cfg(not(feature = "use-gauge-on-cpu-seconds-total"))]
describe_counter!(
Arc::clone(&metrics.cpu_seconds_total),
Unit::Seconds,
"Total user and system CPU time spent in seconds."
);
#[cfg(feature = "use-gauge-on-cpu-seconds-total")]
describe_gauge!(
Arc::clone(&metrics.cpu_seconds_total),
Unit::Seconds,
"Total user and system CPU time spent in seconds."
);
describe_gauge!(
Arc::clone(&metrics.open_fds),
Unit::Count,
"Number of open file descriptors."
);
describe_gauge!(
Arc::clone(&metrics.max_fds),
Unit::Count,
"Maximum number of open file descriptors."
);
describe_gauge!(
Arc::clone(&metrics.virtual_memory_bytes),
Unit::Bytes,
"Virtual memory size in bytes."
);
#[cfg(not(target_os = "windows"))]
describe_gauge!(
Arc::clone(&metrics.virtual_memory_max_bytes),
Unit::Bytes,
"Maximum amount of virtual memory available in bytes."
);
describe_gauge!(
Arc::clone(&metrics.resident_memory_bytes),
Unit::Bytes,
"Resident memory size in bytes."
);
describe_gauge!(
Arc::clone(&metrics.start_time_seconds),
Unit::Seconds,
"Start time of the process since unix epoch in seconds."
);
#[cfg(not(target_os = "windows"))]
describe_gauge!(
Arc::clone(&metrics.threads),
Unit::Count,
"Number of OS threads in the process."
);
}
pub fn collect(&self) {
let metrics = self.metrics.as_ref();
let mut m = collector::collect();
if let Some(v) = m.cpu_seconds_total.take() {
#[cfg(not(feature = "use-gauge-on-cpu-seconds-total"))]
counter!(Arc::clone(&metrics.cpu_seconds_total)).absolute(v as u64);
#[cfg(feature = "use-gauge-on-cpu-seconds-total")]
gauge!(Arc::clone(&metrics.cpu_seconds_total)).set(v);
}
if let Some(v) = m.open_fds.take() {
gauge!(Arc::clone(&metrics.open_fds)).set(v as f64);
}
if let Some(v) = m.max_fds.take() {
gauge!(Arc::clone(&metrics.max_fds)).set(v as f64);
}
if let Some(v) = m.virtual_memory_bytes.take() {
gauge!(Arc::clone(&metrics.virtual_memory_bytes)).set(v as f64);
}
#[cfg(not(target_os = "windows"))]
if let Some(v) = m.virtual_memory_max_bytes.take() {
gauge!(Arc::clone(&metrics.virtual_memory_max_bytes)).set(v as f64);
}
if let Some(v) = m.resident_memory_bytes.take() {
gauge!(Arc::clone(&metrics.resident_memory_bytes)).set(v as f64);
}
if let Some(v) = m.start_time_seconds.take() {
gauge!(Arc::clone(&metrics.start_time_seconds)).set(v as f64);
}
#[cfg(not(target_os = "windows"))]
if let Some(v) = m.threads.take() {
gauge!(Arc::clone(&metrics.threads)).set(v as f64);
}
}
}