mirror of
https://codeberg.org/icewind/palantir.git
synced 2026-06-03 10:14:09 +02:00
arc stats
This commit is contained in:
parent
91bea1d70b
commit
78893bdaed
3 changed files with 90 additions and 3 deletions
|
|
@ -5,6 +5,7 @@ use futures_util::StreamExt;
|
||||||
use palantir::docker::{get_docker, stat, Container};
|
use palantir::docker::{get_docker, stat, Container};
|
||||||
use palantir::get_metrics;
|
use palantir::get_metrics;
|
||||||
use palantir::power::power_usage;
|
use palantir::power::power_usage;
|
||||||
|
use palantir::zfs::arcstats;
|
||||||
use warp::reject::Reject;
|
use warp::reject::Reject;
|
||||||
use warp::{Filter, Rejection};
|
use warp::{Filter, Rejection};
|
||||||
|
|
||||||
|
|
@ -34,6 +35,9 @@ async fn serve_inner(docker: Option<Docker>) -> Result<String> {
|
||||||
if let Some(power) = power_usage()? {
|
if let Some(power) = power_usage()? {
|
||||||
power.write(&mut metrics, &hostname);
|
power.write(&mut metrics, &hostname);
|
||||||
}
|
}
|
||||||
|
if let Some(arc) = arcstats()? {
|
||||||
|
arc.write(&mut metrics, &hostname);
|
||||||
|
}
|
||||||
Ok(metrics)
|
Ok(metrics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ impl PowerUsage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn power_usage() -> Result<Option<PowerUsage>> {
|
pub fn power_usage() -> Result<Option<PowerUsage>> {
|
||||||
if !CAN_READ.load(Ordering::Relaxed) {
|
if !CAN_READ.load(Ordering::Relaxed) {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
|
|
||||||
88
src/zfs.rs
88
src/zfs.rs
|
|
@ -1,9 +1,12 @@
|
||||||
use crate::sensors::DiskUsage;
|
use crate::sensors::DiskUsage;
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
|
use std::fmt::Write;
|
||||||
|
use std::fs::read_to_string;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
pub fn pools() -> impl Iterator<Item = DiskUsage> {
|
pub fn pools() -> impl Iterator<Item = DiskUsage> {
|
||||||
OutputParser {
|
ZPoolOutputParser {
|
||||||
str: zpool_command().unwrap_or_default(),
|
str: zpool_command().unwrap_or_default(),
|
||||||
pos: 0,
|
pos: 0,
|
||||||
}
|
}
|
||||||
|
|
@ -28,12 +31,12 @@ fn parse_line(line: &str) -> Option<DiskUsage> {
|
||||||
Some(DiskUsage { name, size, free })
|
Some(DiskUsage { name, size, free })
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OutputParser {
|
struct ZPoolOutputParser {
|
||||||
str: String,
|
str: String,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for OutputParser {
|
impl Iterator for ZPoolOutputParser {
|
||||||
type Item = DiskUsage;
|
type Item = DiskUsage;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
|
@ -54,3 +57,82 @@ impl Iterator for OutputParser {
|
||||||
line.and_then(parse_line)
|
line.and_then(parse_line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct ArcStats {
|
||||||
|
hits: u64,
|
||||||
|
misses: u64,
|
||||||
|
prefetch: u64,
|
||||||
|
size: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ArcStats {
|
||||||
|
pub fn write<W: Write>(&self, mut w: W, hostname: &str) {
|
||||||
|
writeln!(
|
||||||
|
&mut w,
|
||||||
|
"zfs_arc_hits{{host=\"{}\"}} {}",
|
||||||
|
hostname, self.hits
|
||||||
|
)
|
||||||
|
.ok();
|
||||||
|
writeln!(
|
||||||
|
&mut w,
|
||||||
|
"zfs_arc_misses{{host=\"{}\"}} {}",
|
||||||
|
hostname, self.misses
|
||||||
|
)
|
||||||
|
.ok();
|
||||||
|
writeln!(
|
||||||
|
&mut w,
|
||||||
|
"zfs_arc_size{{host=\"{}\"}} {}",
|
||||||
|
hostname, self.size
|
||||||
|
)
|
||||||
|
.ok();
|
||||||
|
writeln!(
|
||||||
|
&mut w,
|
||||||
|
"zfs_arc_prefetch{{host=\"{}\"}} {}",
|
||||||
|
hostname, self.prefetch
|
||||||
|
)
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arcstats() -> Result<Option<ArcStats>> {
|
||||||
|
let content = match read_to_string("/proc/spl/kstat/zfs/arcstats") {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(_) => return Ok(None),
|
||||||
|
};
|
||||||
|
let mut stats = ArcStats::default();
|
||||||
|
|
||||||
|
for line in content.lines().skip(2) {
|
||||||
|
let mut parts = line.split_ascii_whitespace();
|
||||||
|
if let (Some(name), _, Some(Ok(value))) =
|
||||||
|
(parts.next(), parts.next(), parts.next().map(u64::from_str))
|
||||||
|
{
|
||||||
|
match name {
|
||||||
|
"demand_data_hits" => stats.hits += value,
|
||||||
|
"demand_metadata_hits" => stats.hits += value,
|
||||||
|
"prefetch_data_hits" => {
|
||||||
|
stats.hits += value;
|
||||||
|
stats.prefetch += value;
|
||||||
|
}
|
||||||
|
"prefetch_metadata_hits" => {
|
||||||
|
stats.hits += value;
|
||||||
|
stats.prefetch += value;
|
||||||
|
}
|
||||||
|
"demand_data_misses" => stats.misses += value,
|
||||||
|
"demand_metadata_misses" => stats.misses += value,
|
||||||
|
"prefetch_data_misses" => {
|
||||||
|
stats.misses += value;
|
||||||
|
stats.prefetch += value;
|
||||||
|
}
|
||||||
|
"prefetch_metadata_misses" => {
|
||||||
|
stats.misses += value;
|
||||||
|
stats.prefetch += value;
|
||||||
|
}
|
||||||
|
"size" => stats.size = value,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Some(stats))
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue