From 3ff97a5222008c8fc5fe546bca927ce563d9e873 Mon Sep 17 00:00:00 2001 From: prplV Date: Wed, 19 Mar 2025 10:10:48 -0400 Subject: [PATCH 1/6] readme update --- .env.example | 4 +- README.md | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index c690720..d82e45f 100644 --- a/.env.example +++ b/.env.example @@ -1 +1,3 @@ -PROMETHEUS_EXPORTER_PORT = 9100 \ No newline at end of file +# port binding for prometheus-exporter +# default value = 9100 +PROMETHEUS_EXPORTER_PORT = 9100 diff --git a/README.md b/README.md index 6f02d83..d2cf754 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,115 @@ # Prometheus exporter -to handle updates of ZVKS metrics in local Registry and to share with Prometheus later \ No newline at end of file +Программный компонент проекта "Буревестник ВКС", предоставляющий функционал +"кастомного" `Prometheus` экспортера для обработки метрических данных + +### Функциональные особенности + +1) приемка метрических данных с "Интеграционного модуля" в особом формате +2) приведение принятых метрических данных к виду `Prometheus`-метрик +3) хранение и актуализация метрических данных формата `Prometheus`-метрик в локальном `Registry` +4) предоставления веб-интерфейса (аналогичного интерфейсу стандартного `Prometheus` экспортера) для получения + +### Прикладные ограничения локальной сборки пакета + +Для локальной сборки Rust-пакета `prometheus-exporter` необходимы: +1) `cargo` (>=1.85.0) +2) `rustc` (>=1.85.0) +3) `rustup` (>=1.28.1) для выбора `target` ОС и архитектуры сборки + +### Руководство по сборке пакета + +1) На первом этапе следует удостовериться в отсутствии багов и неточностей в работе модуля предвариетльно запустив юнит-тесты командой: +``` +cargo test +``` +> Пакетный менеджер `cargo` автоматически соберет проект в необходимой для тестирования конфигурации и запустит тесты, в терминале будут отображены результаты +>> ВАЖНО! При возникновении какой-либо ошибки в процессе тестирования убедительная просьба - оставить соответствующий `Issue` в данном репозитории и не использовать пакет до устранения проблемы + +2) Сама сборка Rust-пакета `prometheus-exporter` осуществляется введением команды + +* для сборки `Debug`-версии проекта + +``` bash +cargo build +``` + +* для сборки `Release`-версии проекта +``` bash +cargo build --release +``` + +### Запуск проекта + +Для запуска проекта необходимо воспользоваться одной из команд: + +* для запуска `Debug`-версии проекта + +``` bash +cargo run +``` + +* для запуска `Release`-версии проекта +``` bash +cargo run --release +``` + +> Если необходимо работать с бинарными файлами, их можно найти по пути `<путь_до_пакета/target//таргет_сборки/>` + +### Преднастройка запуска + +Преднастройка пакета `prometheus-exporter` осуществляется внутри `.env` файла по примеру, описанному в файле `.env.example` + +``` toml + +# port binding for prometheus-exporter +# default value = 9100 +PROMETHEUS_EXPORTER_PORT = 9100 + +``` + +### Проверка работоспособности + +С точки зрения специфики программного модуля `Prometehus exporter` существует **2 способа** проверки работоспособности + +#### Прикладные требования для проверки работоспособности `prometheus-exporter` + +* наличие утилиты `curl` или ближайшего аналога + +#### Способы + +1) Попытка получить данные + +``` bash +curl -X GET http://localhost:9100/metrics +``` + +2) Попытка загрузить тестовую метрику + +Вид тестовой метрики по формату который принимает пакет `prometheus-exporter`: + +``` json +{ + "service_name" : "test", + "endpoint_name" : "test", + "metrics" : [{ + "id" : "test", + "type" : "", + "addr" : "test", + "value" : 12, + "description" : "test help", + }] +} +``` + +Команда загрузки тестовой метрики в `prometheus-exporter`: + +``` bash +curl -X POST -H 'Content-Type: application/json' 'http://localhost:9100/update' -d '{ "service_name" : "test", "endpoint_name" : "test", "metrics" : [{ "id" : "test", "type" : "", "addr" : "test", "value" : 12, "description" : "test help" }]}' +``` + +Ответом от сервера если метрика загрузится будет: + +``` +Ok +``` \ No newline at end of file From ac218ea8459414e0effab001af1539d06196a911 Mon Sep 17 00:00:00 2001 From: prplV Date: Thu, 20 Mar 2025 05:27:07 -0400 Subject: [PATCH 2/6] tracing and logging added --- .env.example | 5 +++++ src/endpoints.rs | 21 ++++++++++++++++----- src/main.rs | 21 ++++++++++++++++----- src/metrics.rs | 10 ++++++++++ src/structs.rs | 1 + 5 files changed, 48 insertions(+), 10 deletions(-) diff --git a/.env.example b/.env.example index d82e45f..d6acc3c 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,8 @@ # port binding for prometheus-exporter # default value = 9100 PROMETHEUS_EXPORTER_PORT = 9100 + +# setting up max level of logging +# default - INFO +# values : WARN, ERROR, INFO, DEBUG, TRACE +PROMETHEUS_EXPORTER_LOG_LEVEL = "TRACE" \ No newline at end of file diff --git a/src/endpoints.rs b/src/endpoints.rs index d3d1525..fe2104f 100644 --- a/src/endpoints.rs +++ b/src/endpoints.rs @@ -3,11 +3,12 @@ use axum::{ response::IntoResponse, http }; +use tracing_subscriber::field::debug; use crate::structs::v3::PrometheusMetrics; use prometheus::{ Encoder, Gauge, Registry, TextEncoder}; use std::sync::{ Arc, MutexGuard }; use crate::AppState; -use tracing::{ debug, error, info, warn }; +use tracing::{ debug, error, info, warn, trace }; use crate::metrics::{MetricsProcesser, MetricsValueType}; /// An `Update` endpoint @@ -18,14 +19,14 @@ use crate::metrics::{MetricsProcesser, MetricsValueType}; /// # Usage /// /// ``` bash -/// curl -X POST -d '"id" : ...' 'http::/localhost:9100/update' +/// curl -X POST -d '...' 'http::/localhost:9100/update' /// ``` /// pub async fn update_metrics( State(state): State>, Json(request) : Json> ) -> impl IntoResponse { - info!("post on /update"); + trace!("post on /update"); let service = &request.service_name; let endpoint = &request.endpoint_name; @@ -35,9 +36,11 @@ pub async fn update_metrics( match MetricsProcesser::get_type_of_value(&i) { MetricsValueType::Array | MetricsValueType::TaggedArray => { - + trace!("processing an array of metrics"); + // ... }, MetricsValueType::Number => { + trace!("processing a number type of metric"); let gauge = MetricsProcesser::gauge_from_number( &i, &metric_name, @@ -60,9 +63,11 @@ pub async fn update_metrics( } }, MetricsValueType::ArrayOfStrings => { + trace!("processing an array of strings"); warn!("String arrays are unsupported, ignoring ..."); }, _ => { + trace!("processing unrecognized type of metric"); warn!("Unrecognized metric type was supplied, ignoring ..."); } } @@ -83,13 +88,18 @@ pub async fn update_metrics( /// ``` /// pub async fn metrics_handler(State(state): State>) -> String { + trace!("get on /metrics"); let registry = state.registry.lock(); + debug!("registry mutex lock is {}", registry.is_ok()); return match registry { Ok(registry) => { let encoder = TextEncoder::new(); let mut buffer = Vec::new(); let metric_families = registry.gather(); + + debug!("vec of metric families - {:?}", &metric_families); + encoder.encode(&metric_families, &mut buffer).unwrap(); String::from_utf8(buffer).unwrap() }, @@ -109,6 +119,7 @@ pub fn update_or_insert_metric<'a>( registry: MutexGuard<'a, Registry>, metric_name: &str ) -> anyhow::Result<()> { + trace!("fn update_or_insert_metric is running"); use prometheus::Error; // let mut counter = 0; match registry.register(Box::new(metric.clone())) { @@ -119,7 +130,7 @@ pub fn update_or_insert_metric<'a>( // update or throw away match er { Error::AlreadyReg => { - + trace!("processing already regged metric"); match registry.unregister(Box::new(metric.clone())) { Ok(_) => { if let Err(er) = registry.register(Box::new(metric)) { diff --git a/src/main.rs b/src/main.rs index e691d1f..a424e45 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ use axum::{ routing::{get, post}, Router}; use prometheus::Registry; -use std::sync::{Arc, Mutex}; +use std::{str::FromStr, sync::{Arc, Mutex}}; use endpoints::*; use tokio::net::TcpListener; use tracing::info; @@ -27,8 +27,17 @@ struct AppState { #[tokio::main] async fn main() -> anyhow::Result<()> { + let log_level = std::env::var("PROMETHEUS_EXPORTER_LOG_LEVEL") + .unwrap_or_else(|_| "INFO".to_owned()); + tracing_subscriber::fmt() - .with_max_level(tracing::Level::DEBUG) + .with_max_level(tracing::Level::from_str(&log_level).unwrap_or_else(|_| tracing::Level::INFO)) + .with_writer(std::io::stdout) + .with_span_events(tracing_subscriber::fmt::format::FmtSpan::NEW) + .with_line_number(false) + .with_target(false) + .with_file(false) + .compact() .init(); info!("Loading env vars from .env if exists ..."); @@ -49,10 +58,12 @@ async fn main() -> anyhow::Result<()> { .route("/update", post(update_metrics)) .with_state(state.clone()); - 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(); + let port = std::env::var("PROMETHEUS_EXPORTER_PORT") + .unwrap_or_else(|_| "9100".to_owned()); + let bind_address = format!("0.0.0.0:{}", &port); + let listener = TcpListener::bind(bind_address).await?; - info!("Serving on ...:9100"); + info!("Serving on ...:{}", &port); axum::serve(listener, app).await?; Ok(()) } \ No newline at end of file diff --git a/src/metrics.rs b/src/metrics.rs index 87aa996..bc53f63 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -1,9 +1,11 @@ use crate::structs::v3::MetricOutput; +use serde::de; use serde_json::{Map, Value}; use prometheus::Gauge; use tracing::error; use prometheus::Opts; use prometheus::GaugeVec; +use tracing::{debug, trace}; #[derive(Debug)] pub enum MetricsValueType { @@ -20,18 +22,24 @@ pub struct MetricsProcesser; impl MetricsProcesser { pub fn get_type_of_value(metrics: &MetricOutput) -> MetricsValueType { + trace!("defining metric type"); if Self::is_number(metrics) { + debug!("processing Number"); return MetricsValueType::Number; } else if Self::is_array(metrics) { if Self::is_tagged_array(metrics) { + debug!("processing TaggedArray"); return MetricsValueType::TaggedArray; } if Self::is_array_of_string_values(metrics) { + debug!("processing ArrayOfStrings"); return MetricsValueType::ArrayOfStrings; } + debug!("processing Array"); return MetricsValueType::Array; } + debug!("processing undefined type"); MetricsValueType::None } @@ -41,6 +49,7 @@ impl MetricsProcesser { metric_name: &str, metric_desc: &str ) -> Option { + trace!("fn gauge_from_number is running"); let gauge = Gauge::new( metric_name, metric_desc @@ -64,6 +73,7 @@ impl MetricsProcesser { }, }; gauge.set(val); + debug!("processed metric: {:?}", &gauge); return Some(gauge); }, Err(er) => error!("Cannot create Gauge metric {} due to {}", &metric_name, er), diff --git a/src/structs.rs b/src/structs.rs index b480f3a..a15eee7 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -17,6 +17,7 @@ pub mod v3 { pub value : Value, #[serde(rename = "description")] pub desc : Option>, + pub status: Option } #[derive(Serialize, Deserialize, Debug)] From ab1ed5a57c271132a75e0e63bfad6649e9b01b98 Mon Sep 17 00:00:00 2001 From: prplV Date: Fri, 28 Mar 2025 05:13:16 -0400 Subject: [PATCH 3/6] US changes --- src/endpoints.rs | 31 ++++++++++++++++++++++++------- src/main.rs | 3 ++- src/metrics.rs | 20 +++++++++++--------- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/endpoints.rs b/src/endpoints.rs index fe2104f..0268cf3 100644 --- a/src/endpoints.rs +++ b/src/endpoints.rs @@ -3,14 +3,28 @@ use axum::{ response::IntoResponse, http }; -use tracing_subscriber::field::debug; use crate::structs::v3::PrometheusMetrics; -use prometheus::{ Encoder, Gauge, Registry, TextEncoder}; -use std::sync::{ Arc, MutexGuard }; +use prometheus::{ core::Collector, Encoder, Gauge, Registry, TextEncoder}; +use std::{cell::RefCell, rc::Rc, sync::{ Arc, MutexGuard }}; use crate::AppState; use tracing::{ debug, error, info, warn, trace }; use crate::metrics::{MetricsProcesser, MetricsValueType}; +struct BoxCollectorProducer { + inner : *mut dyn Collector, +} + +impl BoxCollectorProducer { + pub fn new(target: Box) -> Self { + Self { + inner : Box::into_raw(target) + } + } + pub fn new_box(&self) -> Box { + unsafe { Box::from_raw(self.inner) } + } +} + /// An `Update` endpoint /// /// Used to registrate new metrics and to update already @@ -115,14 +129,17 @@ pub async fn metrics_handler(State(state): State>) -> String { /// `Registry` /// pub fn update_or_insert_metric<'a>( - metric: Gauge, + metric: Box, registry: MutexGuard<'a, Registry>, metric_name: &str ) -> anyhow::Result<()> { trace!("fn update_or_insert_metric is running"); use prometheus::Error; // let mut counter = 0; - match registry.register(Box::new(metric.clone())) { + // let ptr = Box::into_raw(metric); + let prod = BoxCollectorProducer::new(metric); + + match registry.register(prod.new_box()) { Ok(_) => { info!("Metric `{}` was registered!", metric_name); }, @@ -131,9 +148,9 @@ pub fn update_or_insert_metric<'a>( match er { Error::AlreadyReg => { trace!("processing already regged metric"); - match registry.unregister(Box::new(metric.clone())) { + match registry.unregister(prod.new_box()) { Ok(_) => { - if let Err(er) = registry.register(Box::new(metric)) { + if let Err(er) = registry.register(prod.new_box()) { warn!("Cannot update metric `{}`", metric_name); return Err(anyhow::Error::msg( format!("Cannot update metric `{}` due to {}", metric_name, er) diff --git a/src/main.rs b/src/main.rs index a424e45..02b6fb1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,8 @@ struct AppState { #[tokio::main] async fn main() -> anyhow::Result<()> { + dotenv().ok(); + let log_level = std::env::var("PROMETHEUS_EXPORTER_LOG_LEVEL") .unwrap_or_else(|_| "INFO".to_owned()); @@ -41,7 +43,6 @@ async fn main() -> anyhow::Result<()> { .init(); info!("Loading env vars from .env if exists ..."); - dotenv().ok(); info!("Initializing local Prometehus metrics registry ..."); let registry = Registry::new(); diff --git a/src/metrics.rs b/src/metrics.rs index bc53f63..d561a6f 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -1,10 +1,11 @@ +use std::sync::Arc; + use crate::structs::v3::MetricOutput; -use serde::de; use serde_json::{Map, Value}; use prometheus::Gauge; use tracing::error; use prometheus::Opts; -use prometheus::GaugeVec; +use prometheus::{opts, GaugeVec, core::Collector}; use tracing::{debug, trace}; #[derive(Debug)] @@ -20,7 +21,6 @@ pub struct MetricsProcesser; impl MetricsProcesser { - pub fn get_type_of_value(metrics: &MetricOutput) -> MetricsValueType { trace!("defining metric type"); if Self::is_number(metrics) { @@ -48,8 +48,14 @@ impl MetricsProcesser { metric: &MetricOutput, metric_name: &str, metric_desc: &str - ) -> Option { + ) -> Option> { trace!("fn gauge_from_number is running"); + if let Some(status) = metric.status { + let vec = GaugeVec::new(opts!(metric_name, metric_desc), &["status"]).unwrap(); + vec.with_label_values(&[&status.to_string()]).set(metric.value.as_f64().unwrap_or_else(|| 0.0)); + return Some(Box::new(vec)); + } + let gauge = Gauge::new( metric_name, metric_desc @@ -57,10 +63,6 @@ impl MetricsProcesser { match gauge { Ok(gauge) => { - // let value = metric.value.as_number().unwrap_or({ - // error!("Cannot convert {} metric value to f64 type. Value was set to 0.0", &metric_name); - // }); - // let value = value.as_f64() let val = match metric.value.as_number() { Some(val) => { val.as_f64().unwrap_or_else(|| @@ -74,7 +76,7 @@ impl MetricsProcesser { }; gauge.set(val); debug!("processed metric: {:?}", &gauge); - return Some(gauge); + return Some(Box::new(gauge)); }, Err(er) => error!("Cannot create Gauge metric {} due to {}", &metric_name, er), } From c558d8bcc7ad84f21901de4a6767aa03ec1d13e0 Mon Sep 17 00:00:00 2001 From: prplV Date: Tue, 8 Apr 2025 03:54:52 -0400 Subject: [PATCH 4/6] - comments --- src/metrics.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/metrics.rs b/src/metrics.rs index d561a6f..3376aab 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -53,6 +53,7 @@ impl MetricsProcesser { if let Some(status) = metric.status { let vec = GaugeVec::new(opts!(metric_name, metric_desc), &["status"]).unwrap(); vec.with_label_values(&[&status.to_string()]).set(metric.value.as_f64().unwrap_or_else(|| 0.0)); + debug!("processed metric: {:?}", &vec); return Some(Box::new(vec)); } @@ -80,7 +81,6 @@ impl MetricsProcesser { }, Err(er) => error!("Cannot create Gauge metric {} due to {}", &metric_name, er), } - None } pub fn gauge_from_map_metrics( @@ -123,11 +123,10 @@ impl MetricsProcesser { let gauge_vec = GaugeVec::new(opts, &[&label_name]); match gauge_vec { Ok(vec) => { - // vec.get_metric_with_label_values(vals) match vec.get_metric_with_label_values(&[&label_value]) { Ok(metric) => { - metric.set(metric_value); // Устанавливаем значение метрики - return Some(metric.clone()); // Возвращаем `Gauge` + metric.set(metric_value); + return Some(metric.clone()); }, Err(er) => { error!("Cannot create Gauge {} due to {}", &name, er); From 90551420735a69c835a58d4b24cd8c3d36823e78 Mon Sep 17 00:00:00 2001 From: prplV Date: Tue, 8 Apr 2025 03:55:25 -0400 Subject: [PATCH 5/6] SIGSEGV (Address boundary error) bug fixed! --- src/endpoints.rs | 72 ++++++++++++++++-------------------------------- 1 file changed, 24 insertions(+), 48 deletions(-) diff --git a/src/endpoints.rs b/src/endpoints.rs index 0268cf3..7369452 100644 --- a/src/endpoints.rs +++ b/src/endpoints.rs @@ -4,24 +4,29 @@ use axum::{ http }; use crate::structs::v3::PrometheusMetrics; -use prometheus::{ core::Collector, Encoder, Gauge, Registry, TextEncoder}; -use std::{cell::RefCell, rc::Rc, sync::{ Arc, MutexGuard }}; +use prometheus::{ core::Collector, Encoder, Registry, TextEncoder}; +use std::sync::{ Arc, MutexGuard }; use crate::AppState; use tracing::{ debug, error, info, warn, trace }; use crate::metrics::{MetricsProcesser, MetricsValueType}; -struct BoxCollectorProducer { - inner : *mut dyn Collector, -} - -impl BoxCollectorProducer { - pub fn new(target: Box) -> Self { - Self { - inner : Box::into_raw(target) - } +#[derive(Clone)] +struct CloneableCollector(Arc); +impl CloneableCollector { + fn from_boxed(collector: Box) -> Self { + CloneableCollector(Arc::from(collector)) } - pub fn new_box(&self) -> Box { - unsafe { Box::from_raw(self.inner) } + fn get_collector(&self) -> Box { + Box::new(self.clone()) + } +} +impl Collector for CloneableCollector { + fn desc(&self) -> Vec<&prometheus::core::Desc> { + self.0.desc() + } + + fn collect(&self) -> Vec { + self.0.collect() } } @@ -33,7 +38,7 @@ impl BoxCollectorProducer { /// # Usage /// /// ``` bash -/// curl -X POST -d '...' 'http::/localhost:9100/update' +/// curl -X POST -d '...' 'http://127.0.0.1:9100/update' -d ... /// ``` /// pub async fn update_metrics( @@ -98,7 +103,7 @@ pub async fn update_metrics( /// # Usage /// /// ``` bash -/// curl -X GET 'http::/localhost:9100/metrics' +/// curl -X GET 'http://127.0.0.1:9100/metrics' /// ``` /// pub async fn metrics_handler(State(state): State>) -> String { @@ -135,11 +140,9 @@ pub fn update_or_insert_metric<'a>( ) -> anyhow::Result<()> { trace!("fn update_or_insert_metric is running"); use prometheus::Error; - // let mut counter = 0; - // let ptr = Box::into_raw(metric); - let prod = BoxCollectorProducer::new(metric); + let prod = CloneableCollector::from_boxed(metric); - match registry.register(prod.new_box()) { + match registry.register(prod.get_collector()) { Ok(_) => { info!("Metric `{}` was registered!", metric_name); }, @@ -148,9 +151,9 @@ pub fn update_or_insert_metric<'a>( match er { Error::AlreadyReg => { trace!("processing already regged metric"); - match registry.unregister(prod.new_box()) { + match registry.unregister(prod.get_collector()) { Ok(_) => { - if let Err(er) = registry.register(prod.new_box()) { + if let Err(er) = registry.register(prod.get_collector()) { warn!("Cannot update metric `{}`", metric_name); return Err(anyhow::Error::msg( format!("Cannot update metric `{}` due to {}", metric_name, er) @@ -166,29 +169,6 @@ pub fn update_or_insert_metric<'a>( )) }, } - // use prometheus::opts; - // use prometheus::GaugeVec; - - // let vec = GaugeVec::new(opts!("test", "test_help"), &["label"]).unwrap(); - // // vec.with_label_values(&["default"]).set(42.0); - // if registry.unregister(Box::new(vec)).is_err() { - // debug!("unregister failed"); - // }; - - // let vec = GaugeVec::new(opts!("test1", "test_help1"), &["label"]).unwrap(); - // vec.with_label_values(&["goood!"]).set(412.0); - // let _ = registry.register(Box::new(vec)); - // registry - // .gather() - // .iter_mut() - // .filter(|target| target.get_name() == metric_name.trim()) - // .for_each(|family| { - // // let prev: &mut GaugeVec = family.mut_metric()[0].mut_gauge(); - - // // GaugeVec:: - - // // info!("Metric `{}` was updated, new value - {}", metric_name, new); - // }); }, _ => { error!("Cannot register new metric `{}` due to {}", metric_name, er); @@ -200,8 +180,4 @@ pub fn update_or_insert_metric<'a>( }, } Ok(()) - // registry.gather() - // .iter() - // .filter(|fam| fam.get_name().) - } From 5842c93ecf03d0cf60d9ed3fd19a924aa8fd6a33 Mon Sep 17 00:00:00 2001 From: prplV Date: Tue, 8 Apr 2025 04:44:41 -0400 Subject: [PATCH 6/6] main log logic rework --- src/main.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index 02b6fb1..8a237c5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,18 +31,17 @@ async fn main() -> anyhow::Result<()> { let log_level = std::env::var("PROMETHEUS_EXPORTER_LOG_LEVEL") .unwrap_or_else(|_| "INFO".to_owned()); - + tracing_subscriber::fmt() - .with_max_level(tracing::Level::from_str(&log_level).unwrap_or_else(|_| tracing::Level::INFO)) - .with_writer(std::io::stdout) - .with_span_events(tracing_subscriber::fmt::format::FmtSpan::NEW) - .with_line_number(false) - .with_target(false) - .with_file(false) - .compact() - .init(); - - info!("Loading env vars from .env if exists ..."); + .with_max_level(tracing::Level::from_str(&log_level).unwrap_or_else(|_| tracing::Level::INFO)) + .with_writer(std::io::stdout) + .with_span_events(tracing_subscriber::fmt::format::FmtSpan::NEW) + .with_line_number(false) + .with_target(false) + .with_file(false) + .compact() + .init(); + info!("Logger was created and configurated, dotenv vars were loaded (if exist)"); info!("Initializing local Prometehus metrics registry ..."); let registry = Registry::new();