mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-08 22:12:56 +00:00
## Problem We have two places that use a helper (`ser_rfc3339_millis`) to get serde to stringify SystemTimes into the desired format. ## Summary of changes Created a new module `utils::serde_system_time` and inside it a wrapper type `SystemTime` for `std::time::SystemTime` that serializes/deserializes to the RFC3339 format. This new type is then used in the two places that were previously using the helper for serialization, thereby eliminating the need to decorate structs. Closes #7151.
51 lines
1.7 KiB
Rust
51 lines
1.7 KiB
Rust
//! An utilization metric which is used to decide on which pageserver to put next tenant.
|
|
//!
|
|
//! The metric is exposed via `GET /v1/utilization`. Refer and maintain it's openapi spec as the
|
|
//! truth.
|
|
|
|
use anyhow::Context;
|
|
use std::path::Path;
|
|
|
|
use pageserver_api::models::PageserverUtilization;
|
|
|
|
pub(crate) fn regenerate(tenants_path: &Path) -> anyhow::Result<PageserverUtilization> {
|
|
// TODO: currently the http api ratelimits this to 1Hz at most, which is probably good enough
|
|
|
|
let statvfs = nix::sys::statvfs::statvfs(tenants_path)
|
|
.map_err(std::io::Error::from)
|
|
.context("statvfs tenants directory")?;
|
|
|
|
// https://unix.stackexchange.com/a/703650
|
|
let blocksz = if statvfs.fragment_size() > 0 {
|
|
statvfs.fragment_size()
|
|
} else {
|
|
statvfs.block_size()
|
|
};
|
|
|
|
#[cfg_attr(not(target_os = "macos"), allow(clippy::unnecessary_cast))]
|
|
let free = statvfs.blocks_available() as u64 * blocksz;
|
|
|
|
#[cfg_attr(not(target_os = "macos"), allow(clippy::unnecessary_cast))]
|
|
let used = statvfs
|
|
.blocks()
|
|
// use blocks_free instead of available here to match df in case someone compares
|
|
.saturating_sub(statvfs.blocks_free()) as u64
|
|
* blocksz;
|
|
|
|
let captured_at = std::time::SystemTime::now();
|
|
|
|
let doc = PageserverUtilization {
|
|
disk_usage_bytes: used,
|
|
free_space_bytes: free,
|
|
// lower is better; start with a constant
|
|
//
|
|
// note that u64::MAX will be output as i64::MAX as u64, but that should not matter
|
|
utilization_score: u64::MAX,
|
|
captured_at: utils::serde_system_time::SystemTime(captured_at),
|
|
};
|
|
|
|
// TODO: make utilization_score into a metric
|
|
|
|
Ok(doc)
|
|
}
|