Init
This commit is contained in:
commit
9cc3781230
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
62
Cargo.lock
generated
Normal file
62
Cargo.lock
generated
Normal file
@ -0,0 +1,62 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
||||
|
||||
[[package]]
|
||||
name = "ascii"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chunked_transfer"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cca491388666e04d7248af3f60f0c40cfb0991c72205595d7c396e3510207d1a"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prometheus_gbl_exporter"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"tiny_http",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny_http"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82"
|
||||
dependencies = [
|
||||
"ascii",
|
||||
"chunked_transfer",
|
||||
"httpdate",
|
||||
"log",
|
||||
]
|
18
Cargo.toml
Normal file
18
Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "prometheus_gbl_exporter"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
tiny_http = "0.12"
|
||||
anyhow = "1.0.71"
|
||||
|
||||
# minimalize size
|
||||
[profile.release]
|
||||
strip = true
|
||||
opt-level = "z"
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
panic = "abort"
|
1
src/collectors/mod.rs
Normal file
1
src/collectors/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod time;
|
12
src/collectors/time.rs
Normal file
12
src/collectors/time.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::metric::{Metrics, Metric, MType};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub fn scrape() -> Metrics {
|
||||
let mut met = Metrics::new();
|
||||
let start = SystemTime::now();
|
||||
let since_the_epoch = start
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("Time went backwards");
|
||||
met.metrics.push(Metric::new_val("node_time_seconds", MType::Gauge, since_the_epoch.as_secs() as f64));
|
||||
return met
|
||||
}
|
7
src/collectors/uname.rs
Normal file
7
src/collectors/uname.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::metric::{Metrics, Metric, MType};
|
||||
|
||||
pub fn scrape() -> Metrics {
|
||||
let mut met = Metrics::new();
|
||||
met.metrics.push(Metric::new_val("node_time_seconds", MType::Gauge, since_the_epoch.as_secs() as f64));
|
||||
return met
|
||||
}
|
0
src/collectors/wifi.rs
Normal file
0
src/collectors/wifi.rs
Normal file
32
src/main.rs
Normal file
32
src/main.rs
Normal file
@ -0,0 +1,32 @@
|
||||
mod metric;
|
||||
mod collectors;
|
||||
use tiny_http::{Server, Response, Method};
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use collectors::time;
|
||||
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let server = Server::http("0.0.0.0:9100").unwrap();
|
||||
|
||||
for request in server.incoming_requests() {
|
||||
if request.method() != &Method::Get || request.url() != "/metrics" {
|
||||
let response = Response::from_string("Not Found").with_status_code(404);
|
||||
request.respond(response)?;
|
||||
continue;
|
||||
}
|
||||
println!("request! method: {:?}, url: {:?}, headers: {:?}",
|
||||
request.method(),
|
||||
request.url(),
|
||||
request.headers()
|
||||
);
|
||||
|
||||
let mut output = String::new();
|
||||
|
||||
output.push_str(&time::scrape().prometheus());
|
||||
|
||||
let response = Response::from_string(output);
|
||||
request.respond(response)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
110
src/metric.rs
Normal file
110
src/metric.rs
Normal file
@ -0,0 +1,110 @@
|
||||
|
||||
pub enum MType {
|
||||
Gauge,
|
||||
Counter,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for MType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
MType::Gauge => write!(f, "gauge"),
|
||||
MType::Counter => write!(f, "counter")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MetricLabel {
|
||||
label: String,
|
||||
value: String,
|
||||
}
|
||||
|
||||
impl MetricLabel {
|
||||
fn prometheus(&self) -> String {
|
||||
return format!("{}=\"{}\"", self.label, self.value)
|
||||
}
|
||||
}
|
||||
|
||||
struct MetricData {
|
||||
labels: Vec<MetricLabel>,
|
||||
value: f64
|
||||
}
|
||||
|
||||
impl MetricData {
|
||||
fn new(value: f64) -> MetricData {
|
||||
return MetricData {
|
||||
labels: Vec::new(),
|
||||
value: value,
|
||||
};
|
||||
}
|
||||
fn add_label(&mut self, label: String, value: String) {
|
||||
self.labels.push(MetricLabel{label: label, value: value})
|
||||
}
|
||||
fn rounded_val(&self) -> String {
|
||||
if self.value.fract() == 0.0 {
|
||||
return (self.value.trunc() as i64).to_string();
|
||||
}
|
||||
return self.value.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Metric {
|
||||
name: String,
|
||||
mtype: MType,
|
||||
data: Vec<MetricData>
|
||||
}
|
||||
|
||||
impl Metric {
|
||||
pub fn new(name: &str, mtype: MType) -> Metric {
|
||||
return Metric {
|
||||
name: String::from(name),
|
||||
mtype: mtype,
|
||||
data: Vec::new()
|
||||
};
|
||||
}
|
||||
pub fn new_val(name: &str, mtype: MType, value: f64) -> Metric {
|
||||
return Metric {
|
||||
name: String::from(name),
|
||||
mtype: mtype,
|
||||
data: vec![MetricData::new(value)]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Metrics {
|
||||
pub metrics: Vec<Metric>,
|
||||
pub processtime: f64
|
||||
}
|
||||
|
||||
impl Metrics {
|
||||
pub fn prometheus(&self) -> String {
|
||||
let mut type_section = String::new();
|
||||
let mut metric_section = String::new();
|
||||
|
||||
for m in &self.metrics {
|
||||
type_section.push_str(&format!("# TYPE {} {}\n", m.name, m.mtype));
|
||||
for d in &m.data {
|
||||
let mut labels = String::new();
|
||||
for (i, l) in d.labels.iter().enumerate() {
|
||||
labels.push_str(&l.prometheus());
|
||||
if i != d.labels.len()-1 {
|
||||
labels.push(',')
|
||||
}
|
||||
}
|
||||
if labels.is_empty() {
|
||||
metric_section.push_str(&format!("{} {}\n", m.name, d.rounded_val()));
|
||||
} else {
|
||||
metric_section.push_str(&format!("{}{{{}}} {}\n", m.name, labels, d.rounded_val()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return type_section+&metric_section;
|
||||
}
|
||||
|
||||
pub fn new() -> Metrics {
|
||||
return Metrics {
|
||||
metrics: Vec::new(),
|
||||
processtime: 0.0
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user