1
0
Fork 0
nixos-exporter/src/main.rs

84 lines
2.0 KiB
Rust

use axum::{
routing::get,
Router,
response::{
IntoResponse,
Response,
},
http::StatusCode,
};
use std::net::SocketAddr;
use std::str::FromStr;
#[tokio::main]
async fn main() {
let mut listen = String::from("[::]:9152");
let mut args = std::env::args();
args.next();
loop {
let arg = if let Some(arg) = args.next() {
arg
} else {
break
};
match arg.as_str() {
"--help" | "-h" => {
println!("Prometheus exporter for NixOS systems");
println!("Use --listen <addr:port> bind the web service.");
println!("Output will be on /metrics endpoint. HTTP 500 if something broke while scraping.");
std::process::exit(0);
},
"--listen" => {
listen = args.next().unwrap();
},
unknown => {
println!("unknown option: {}", unknown);
std::process::exit(1)
}
}
}
let app = Router::new().route("/metrics", get(metrics));
let addr = SocketAddr::from_str(&listen).unwrap();
println!("listening on http://{}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
fn get_current_system() -> Result<(String, String), String> {
let symlink = match std::fs::read_link("/run/current-system") {
Ok(symlink) => symlink,
Err(err) => return Err(err.to_string())
};
let (hash, name) = symlink.file_name()
.ok_or_else(String::default)?
.to_str()
.ok_or_else(String::default)?
.split_once("-")
.ok_or_else(String::default)?;
Ok((String::from(hash), String::from(name)))
}
async fn metrics() -> Response {
let current_system = get_current_system();
let (hash, name) = match current_system {
Ok((hash, name)) => (hash, name),
Err(err) => {
println!("failed: {}", err);
return (StatusCode::INTERNAL_SERVER_ERROR, "").into_response()
}
};
(
StatusCode::OK,
format!("nixos_nixos_current_system_hash{{hash=\"{}\"}}\nnixos_current_system_name{{name=\"{}\"}}", hash, name)
).into_response()
}