diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c690720 --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +PROMETHEUS_EXPORTER_PORT = 9100 \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index bd08195..e64fef2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,5 @@ tracing = "0.1.41" tracing-subscriber = "0.3.19" serde = { version = "1.0.217", features = ["derive"] } serde_json = "1.0.138" +dotenv = "0.15.0" diff --git a/src/endpoints.rs b/src/endpoints.rs index f1538eb..d3d1525 100644 --- a/src/endpoints.rs +++ b/src/endpoints.rs @@ -7,9 +7,20 @@ use crate::structs::v3::PrometheusMetrics; use prometheus::{ Encoder, Gauge, Registry, TextEncoder}; use std::sync::{ Arc, MutexGuard }; use crate::AppState; -use tracing::{ error, info, warn }; +use tracing::{ debug, error, info, warn }; use crate::metrics::{MetricsProcesser, MetricsValueType}; +/// An `Update` endpoint +/// +/// Used to registrate new metrics and to update already +/// existing in local metrics `Registry` +/// +/// # Usage +/// +/// ``` bash +/// curl -X POST -d '"id" : ...' 'http::/localhost:9100/update' +/// ``` +/// pub async fn update_metrics( State(state): State>, Json(request) : Json> @@ -19,6 +30,7 @@ pub async fn update_metrics( let endpoint = &request.endpoint_name; for i in request.metrics { + debug!("Processing metric: {:?}", &i); let metric_name = format!("{}_{}_{}", service, endpoint, &i.id); match MetricsProcesser::get_type_of_value(&i) { MetricsValueType::Array | @@ -59,6 +71,17 @@ pub async fn update_metrics( (http::StatusCode::ACCEPTED, "Ok") } +/// An `Metrics` endpoint +/// +/// Needed in sharing current local metrics `Registry` state +/// and all stored metrics +/// +/// # Usage +/// +/// ``` bash +/// curl -X GET 'http::/localhost:9100/metrics' +/// ``` +/// pub async fn metrics_handler(State(state): State>) -> String { let registry = state.registry.lock(); @@ -76,6 +99,11 @@ pub async fn metrics_handler(State(state): State>) -> String { } } +/// A function-registrator +/// +/// Registrates or updates metrics state in local +/// `Registry` +/// pub fn update_or_insert_metric<'a>( metric: Gauge, registry: MutexGuard<'a, Registry>, diff --git a/src/main.rs b/src/main.rs index f7ee7bb..e691d1f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,12 @@ +/// Prometheus-exporter - a Rust binary crate to provide functional +/// of the metrics Exporter. +/// +/// It handles metrics list in it's own local `Registry` + mod endpoints; -// mod logger; mod metrics; mod structs; -// use logger::setup_logger; use axum::{ routing::{get, post}, Router}; @@ -11,72 +14,44 @@ use prometheus::Registry; use std::sync::{Arc, Mutex}; use endpoints::*; use tokio::net::TcpListener; -// use log::{warn, info, error}; use tracing::info; +use dotenv::dotenv; +/// Shared state of the Web-server +/// +/// Used to store and share state of the metrics `Registry` +/// struct AppState { registry: Mutex, - // counter: Mutex, - // sum : Mutex, } #[tokio::main] async fn main() -> anyhow::Result<()> { - // let _ = setup_logger().await; - tracing_subscriber::fmt() .with_max_level(tracing::Level::DEBUG) .init(); + info!("Loading env vars from .env if exists ..."); + dotenv().ok(); + info!("Initializing local Prometehus metrics registry ..."); - let registry = Registry::new(); - // let counter_opts = Opts::new("example_counter", "Пример счётчика"); - // let histogram_opts = Opts::new("example_histogram", "Пример histogram"); - - // use prometheus::proto::{Summary, Quantile}; - // use prometheus::proto:: - - // let guage = prometheus::ProtobufEncoder::new(); - - - - // let mut sunops = Summary::new(); - // let mut q1 = Quantile::new(); - // let mut q2 = Quantile::new(); - - // q1.set_quantile(25.0); - // q2.set_quantile(75.0); - // // prometheus::proto::Metric:: - - // let vq = vec![q1, q2]; - // sunops.set_quantile(vq.into()); - - // let counter = Counter::with_opts(counter_opts).unwrap(); - // // counter.desc() - // registry.register(Box::new(counter.clone())).unwrap(); - // registry.register(Box::new(prometheus::proto::MetricFamily::)); - // registry.register(Box::new(sunops.clone())).unwrap(); - info!("Initializing shared state for Prometheus Exporter web-server ..."); - let state = Arc::new(AppState { registry: Mutex::new(registry), - // counter: Mutex::new(counter), - // sum : Mutex::new(sunops) }); - // info!("Configurating Web-Server..."); info!("Configurating internals of Prometheus Exporter web-server..."); - let app = Router::new() .route("/metrics", get(metrics_handler)) .route("/update", post(update_metrics)) .with_state(state.clone()); - let listener = TcpListener::bind("0.0.0.0:9100").await.unwrap(); + let bind_address = format!("0.0.0.0:{}", std::env::var("PROMETHEUS_EXPORTER_PORT").unwrap_or_else(|_| "9100".to_owned())); + let listener = TcpListener::bind(bind_address).await.unwrap(); + info!("Serving on ...:9100"); axum::serve(listener, app).await?; Ok(())