mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-06 17:37:47 +08:00
219 lines
6.7 KiB
Rust
219 lines
6.7 KiB
Rust
use aether_runtime::{MetricKind, MetricSample};
|
|
|
|
pub(crate) fn gateway_allocator_metric_samples() -> Vec<MetricSample> {
|
|
match allocator_snapshot() {
|
|
Some(snapshot) => snapshot.to_metric_samples(),
|
|
None => unavailable_metric_samples(),
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, Default)]
|
|
struct AllocatorSnapshot {
|
|
allocated_bytes: u64,
|
|
active_bytes: u64,
|
|
resident_bytes: u64,
|
|
mapped_bytes: u64,
|
|
retained_bytes: u64,
|
|
metadata_bytes: u64,
|
|
}
|
|
|
|
impl AllocatorSnapshot {
|
|
fn to_metric_samples(self) -> Vec<MetricSample> {
|
|
vec![
|
|
gauge(
|
|
"gateway_allocator_observability_available",
|
|
"Whether gateway allocator heap metrics were available for this scrape.",
|
|
1,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_allocated_bytes",
|
|
"Bytes currently allocated by the gateway allocator.",
|
|
self.allocated_bytes,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_active_bytes",
|
|
"Bytes in active pages managed by the gateway allocator.",
|
|
self.active_bytes,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_resident_bytes",
|
|
"Bytes resident in physical memory for the gateway allocator.",
|
|
self.resident_bytes,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_mapped_bytes",
|
|
"Bytes mapped by the gateway allocator.",
|
|
self.mapped_bytes,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_retained_bytes",
|
|
"Bytes retained by the gateway allocator for future use.",
|
|
self.retained_bytes,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_metadata_bytes",
|
|
"Bytes used for allocator metadata.",
|
|
self.metadata_bytes,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_active_to_allocated_basis_points",
|
|
"Active allocator bytes divided by allocated bytes in basis points.",
|
|
ratio_basis_points(self.active_bytes, self.allocated_bytes),
|
|
),
|
|
gauge(
|
|
"gateway_allocator_resident_to_allocated_basis_points",
|
|
"Resident allocator bytes divided by allocated bytes in basis points.",
|
|
ratio_basis_points(self.resident_bytes, self.allocated_bytes),
|
|
),
|
|
]
|
|
}
|
|
}
|
|
|
|
fn unavailable_metric_samples() -> Vec<MetricSample> {
|
|
vec![
|
|
gauge(
|
|
"gateway_allocator_observability_available",
|
|
"Whether gateway allocator heap metrics were available for this scrape.",
|
|
0,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_allocated_bytes",
|
|
"Bytes currently allocated by the gateway allocator.",
|
|
0,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_active_bytes",
|
|
"Bytes in active pages managed by the gateway allocator.",
|
|
0,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_resident_bytes",
|
|
"Bytes resident in physical memory for the gateway allocator.",
|
|
0,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_mapped_bytes",
|
|
"Bytes mapped by the gateway allocator.",
|
|
0,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_retained_bytes",
|
|
"Bytes retained by the gateway allocator for future use.",
|
|
0,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_metadata_bytes",
|
|
"Bytes used for allocator metadata.",
|
|
0,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_active_to_allocated_basis_points",
|
|
"Active allocator bytes divided by allocated bytes in basis points.",
|
|
0,
|
|
),
|
|
gauge(
|
|
"gateway_allocator_resident_to_allocated_basis_points",
|
|
"Resident allocator bytes divided by allocated bytes in basis points.",
|
|
0,
|
|
),
|
|
]
|
|
}
|
|
|
|
#[cfg(all(feature = "jemalloc", not(target_env = "msvc")))]
|
|
fn allocator_snapshot() -> Option<AllocatorSnapshot> {
|
|
refresh_jemalloc_epoch()?;
|
|
Some(AllocatorSnapshot {
|
|
allocated_bytes: read_jemalloc_stat("stats.allocated\0")?,
|
|
active_bytes: read_jemalloc_stat("stats.active\0")?,
|
|
resident_bytes: read_jemalloc_stat("stats.resident\0")?,
|
|
mapped_bytes: read_jemalloc_stat("stats.mapped\0")?,
|
|
retained_bytes: read_jemalloc_stat("stats.retained\0")?,
|
|
metadata_bytes: read_jemalloc_stat("stats.metadata\0")?,
|
|
})
|
|
}
|
|
|
|
#[cfg(not(all(feature = "jemalloc", not(target_env = "msvc"))))]
|
|
fn allocator_snapshot() -> Option<AllocatorSnapshot> {
|
|
None
|
|
}
|
|
|
|
#[cfg(all(feature = "jemalloc", not(target_env = "msvc")))]
|
|
fn refresh_jemalloc_epoch() -> Option<()> {
|
|
let mut epoch = 1_u64;
|
|
let result = unsafe {
|
|
tikv_jemalloc_sys::mallctl(
|
|
c"epoch".as_ptr(),
|
|
std::ptr::null_mut(),
|
|
std::ptr::null_mut(),
|
|
(&mut epoch as *mut u64).cast(),
|
|
std::mem::size_of::<u64>(),
|
|
)
|
|
};
|
|
if result == 0 {
|
|
Some(())
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
#[cfg(all(feature = "jemalloc", not(target_env = "msvc")))]
|
|
fn read_jemalloc_stat(name: &str) -> Option<u64> {
|
|
let mut value = 0_usize;
|
|
let mut size = std::mem::size_of::<usize>();
|
|
let result = unsafe {
|
|
tikv_jemalloc_sys::mallctl(
|
|
name.as_ptr().cast(),
|
|
(&mut value as *mut usize).cast(),
|
|
&mut size,
|
|
std::ptr::null_mut(),
|
|
0,
|
|
)
|
|
};
|
|
if result == 0 {
|
|
Some(u64_from_usize(value))
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn gauge(name: &'static str, help: &'static str, value: u64) -> MetricSample {
|
|
MetricSample::new(name, help, MetricKind::Gauge, value)
|
|
}
|
|
|
|
fn ratio_basis_points(numerator: u64, denominator: u64) -> u64 {
|
|
if denominator == 0 {
|
|
return 0;
|
|
}
|
|
numerator.saturating_mul(10_000) / denominator
|
|
}
|
|
|
|
fn u64_from_usize(value: usize) -> u64 {
|
|
u64::try_from(value).unwrap_or(u64::MAX)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::{gateway_allocator_metric_samples, ratio_basis_points};
|
|
|
|
#[test]
|
|
fn renders_allocator_metric_samples() {
|
|
let samples = gateway_allocator_metric_samples();
|
|
|
|
assert!(samples
|
|
.iter()
|
|
.any(|sample| sample.name == "gateway_allocator_observability_available"));
|
|
assert!(samples
|
|
.iter()
|
|
.any(|sample| sample.name == "gateway_allocator_allocated_bytes"));
|
|
assert!(samples
|
|
.iter()
|
|
.any(|sample| sample.name == "gateway_allocator_active_to_allocated_basis_points"));
|
|
}
|
|
|
|
#[test]
|
|
fn computes_ratio_basis_points() {
|
|
assert_eq!(ratio_basis_points(150, 100), 15_000);
|
|
assert_eq!(ratio_basis_points(1, 0), 0);
|
|
}
|
|
}
|