211 lines
6.2 KiB
Rust
211 lines
6.2 KiB
Rust
use super::prelude::LOG_TARGET;
|
|
use futures::channel::oneshot;
|
|
pub use hidden::*;
|
|
use hyper::{
|
|
header::CONTENT_TYPE,
|
|
service::{make_service_fn, service_fn},
|
|
Body, Method, Request, Response,
|
|
};
|
|
use prometheus::{Encoder, TextEncoder};
|
|
|
|
async fn serve_req(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
|
|
let response = match (req.method(), req.uri().path()) {
|
|
(&Method::GET, "/metrics") => {
|
|
let mut buffer = vec![];
|
|
let encoder = TextEncoder::new();
|
|
let metric_families = prometheus::gather();
|
|
encoder.encode(&metric_families, &mut buffer).unwrap();
|
|
|
|
Response::builder()
|
|
.status(200)
|
|
.header(CONTENT_TYPE, encoder.format_type())
|
|
.body(Body::from(buffer))
|
|
.unwrap()
|
|
},
|
|
(&Method::GET, "/") => Response::builder().status(200).body(Body::from("")).unwrap(),
|
|
_ => Response::builder().status(404).body(Body::from("")).unwrap(),
|
|
};
|
|
|
|
Ok(response)
|
|
}
|
|
|
|
pub struct GracefulShutdown(Option<oneshot::Sender<()>>);
|
|
|
|
impl Drop for GracefulShutdown {
|
|
fn drop(&self) {
|
|
if let Some(handle) = self.0.take() {
|
|
let _ = handle.send(());
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn run(port: u16) -> Result<GracefulShutdown, String> {
|
|
let (tx, rx) = oneshot::channel();
|
|
|
|
let make_svc = make_service_fn(move |_conn| async move {
|
|
Ok::<_, std::convert::Infallible>(service_fn(serve_req))
|
|
});
|
|
|
|
let addr = ([0, 0, 0, 0], port).into();
|
|
let server = hyper::Server::try_bind(&addr)
|
|
.map_err(|e| format!("Failed bind socket on port {} {:?}", port, e))?
|
|
.serve(make_svc);
|
|
|
|
log::info!(target: LOG_TARGET, "Started prometheus endpoint on http://{}", addr);
|
|
|
|
let graceful = server.with_graceful_shutdown(async {
|
|
rx.await.ok();
|
|
});
|
|
|
|
tokio::spawn(async move {
|
|
if let Err(e) = graceful.await {
|
|
log::warn!("Server error: {}", e);
|
|
}
|
|
});
|
|
|
|
Ok(GracefulShutdown(Some(tx)))
|
|
}
|
|
|
|
mod hidden {
|
|
use frame_election_provider_support::Weight;
|
|
use once_cell::sync::Lazy;
|
|
use prometheus::{opts, register_counter, register_gauge, Counter, Gauge};
|
|
|
|
static TRIMMED_SOLUTION_STARTED: Lazy<Counter> = Lazy::new(|| {
|
|
register_counter!(opts!(
|
|
"staking_miner_trim_started",
|
|
"Number of started trimmed solutions",
|
|
)).unwrap()
|
|
});
|
|
|
|
static TRIMMED_SOLUTION_SUCCESS: Lazy<Counter> = Lazy::new(|| {
|
|
register_counter!(opts!(
|
|
"staking_miner_trim_success",
|
|
"Number of successful trimmed solutions",
|
|
)).unwrap()
|
|
});
|
|
|
|
static SUBMISSIONS_STARTED: Lazy<Counter> = Lazy::new(|| {
|
|
register_counter!(opts!(
|
|
"staking_miner_submissions_started",
|
|
"Number of submissions started",
|
|
)).unwrap()
|
|
});
|
|
|
|
static SUBMISSIONS_SUCCESS: Lazy<Counter> = Lazy::new(|| {
|
|
register_counter!(opts!(
|
|
"staking_miner_submissions_success",
|
|
"Number of submissions finished successfully",
|
|
)).unwrap()
|
|
});
|
|
|
|
static MINED_SOLUTION_DURATION: Lazy<Gauge> = Lazy::new(|| {
|
|
register_counter!(opts!(
|
|
"staking_miner_mining_duration_ms",
|
|
"The mined solution time in milliseconds.",
|
|
)).unwrap()
|
|
});
|
|
|
|
static SUBMIT_SOLUTION_AND_WATCH_DURATION: Lazy<Gauge> = Lazy::new(|| {
|
|
register_counter!(opts!(
|
|
"staking_miner_submit_and_watch_duration_ms",
|
|
"The time in milliseconds it took to submit the solution to chain and to be included in block.",
|
|
)).unwrap()
|
|
});
|
|
|
|
static BALANCE: Lazy<Gauge> = Lazy::new(|| {
|
|
register_counter!(opts!(
|
|
"staking_miner_balance",
|
|
"The balance of the staking miner account",
|
|
)).unwrap()
|
|
});
|
|
|
|
static SCORE_MINIMAL_STAKE: Lazy<Gauge> = Lazy::new(|| {
|
|
register_counter!(opts!(
|
|
"staking_miner_score_minimal_stake",
|
|
"The minimal winner, in terms of total backing stake",
|
|
)).unwrap()
|
|
});
|
|
|
|
static SCORE_SUM_STAKE: Lazy<Gauge> = Lazy::new(|| {
|
|
register_counter!(opts!(
|
|
"staking_miner_score_sum_stake",
|
|
"The sum of the total backing of all winners",
|
|
)).unwrap()
|
|
});
|
|
|
|
static SCORE_SUM_STAKE_SQUARED: Lazy<Gauge> = Lazy::new(|| {
|
|
register_counter!(opts!(
|
|
"staking_miner_score_sum_stake_squared",
|
|
"The sum of the total backing of all winners, aka. the variance.",
|
|
)).unwrap()
|
|
});
|
|
|
|
static RUNTIME_UPGRADES: Lazy<Counter> = Lazy::new(|| {
|
|
register_counter!(opts!(
|
|
"staking_miner_runtime",
|
|
"Number of runtime upgrades performed",
|
|
)).unwrap()
|
|
});
|
|
|
|
static SUBMISSION_LENGTH: Lazy<Gauge> = Lazy::new(|| {
|
|
register_counter!(opts!(
|
|
"staking_miner_solution_length_bytes",
|
|
"Number of bytes in the solution submitted",
|
|
)).unwrap()
|
|
});
|
|
|
|
static SUBMISSION_WEIGHT: Lazy<Gauge> = Lazy::new(|| {
|
|
register_counter!(opts!(
|
|
"staking_miner_solution_weight",
|
|
"Weight of the solution submitted",
|
|
)).unwrap()
|
|
});
|
|
|
|
pub fn on_runtime_upgrade() {
|
|
RUNTIME_UPGRADES.inc();
|
|
}
|
|
|
|
pub fn on_submission_attempts() {
|
|
SUBMISSIONS_STARTED.inc();
|
|
}
|
|
|
|
pub fn on_submission_success() {
|
|
SUBMISSIONS_SUCCESS.inc();
|
|
}
|
|
|
|
pub fn on_trim_attempt() {
|
|
TRIMMED_SOLUTION_STARTED.inc();
|
|
}
|
|
|
|
pub fn on_trim_success() {
|
|
TRIMMED_SOLUTION_SUCCESS.inc();
|
|
}
|
|
|
|
pub fn set_balance(balance: u64) {
|
|
BALANCE.set(balance);
|
|
}
|
|
|
|
pub fn set_length(len: usize) {
|
|
SUBMISSION_LENGTH.set(len as f64);
|
|
}
|
|
|
|
pub fn set_weight(weight: Weight) {
|
|
SUBMISSION_WEIGHT.set(weight.ref_time() as f64);
|
|
}
|
|
|
|
pub fn set_score(score: sp_npos_elections::ElectionScore) {
|
|
SCORE_MINIMAL_STAKE.set(score.minimal_stake as f64);
|
|
SCORE_SUM_STAKE.set(score.sum_stake as f64);
|
|
SCORE_SUM_STAKE_SQUARED.set(score.sum_stake_squared as f64);
|
|
}
|
|
|
|
pub fn observe_submit_and_watch_duration(time: f64) {
|
|
SUBMIT_SOLUTION_AND_WATCH_DURATION.set(time);
|
|
}
|
|
|
|
pub fn observe_mined_solution_duration(time: f64) {
|
|
MINED_SOLUTION_DURATION.set(time);
|
|
}
|
|
}
|