From cd1845948468f68a537d84ae3a33da01e5cafa69 Mon Sep 17 00:00:00 2001 From: mohandasspat Date: Wed, 17 Aug 2022 17:14:55 +0530 Subject: [PATCH] Changed prometheus metrics feature as optional --- meilisearch-http/src/lib.rs | 48 ++++++----------- meilisearch-http/src/option.rs | 6 ++- meilisearch-http/src/route_metrics.rs | 75 +++++++++++++++++++++++++++ meilisearch-http/src/routes/mod.rs | 1 - 4 files changed, 95 insertions(+), 35 deletions(-) create mode 100644 meilisearch-http/src/route_metrics.rs diff --git a/meilisearch-http/src/lib.rs b/meilisearch-http/src/lib.rs index f0ce0396c..edffb6afc 100644 --- a/meilisearch-http/src/lib.rs +++ b/meilisearch-http/src/lib.rs @@ -6,6 +6,7 @@ pub mod task; #[macro_use] pub mod extractors; pub mod option; +pub mod route_metrics; pub mod routes; use std::sync::{atomic::AtomicBool, Arc}; @@ -140,56 +141,33 @@ pub fn dashboard(config: &mut web::ServiceConfig, _enable_frontend: bool) { config.service(web::resource("/").route(web::get().to(routes::running))); } +pub fn configure_metrics_route(config: &mut web::ServiceConfig, enable_metrics_route: bool) { + if enable_metrics_route { + config.service(web::resource("/metrics").route(web::get().to(routes::get_metrics))); + } +} + #[macro_export] macro_rules! create_app { ($data:expr, $auth:expr, $enable_frontend:expr, $opt:expr, $analytics:expr) => {{ use actix_cors::Cors; use actix_web::dev::Service; + use actix_web::middleware::Condition; use actix_web::middleware::TrailingSlash; use actix_web::App; use actix_web::{middleware, web}; use meilisearch_http::error::MeilisearchHttpError; use meilisearch_http::metrics; + use meilisearch_http::route_metrics; use meilisearch_http::routes; - use meilisearch_http::{configure_data, dashboard}; + use meilisearch_http::{configure_data, configure_metrics_route, dashboard}; use meilisearch_types::error::ResponseError; - use lazy_static::lazy_static; - use prometheus::{ - opts, register_histogram_vec, register_int_counter_vec, register_int_gauge, - }; - use prometheus::{HistogramTimer, HistogramVec, IntCounterVec, IntGauge}; - App::new() .configure(|s| configure_data(s, $data.clone(), $auth.clone(), &$opt, $analytics)) .configure(routes::configure) .configure(|s| dashboard(s, $enable_frontend)) - .wrap_fn(|req, srv| { - let mut histogram_timer: Option = None; - let request_path = req.path(); - let is_registered_resource = req.resource_map().has_resource(request_path); - if is_registered_resource { - let request_method = req.method().to_string(); - histogram_timer = Some( - metrics::HTTP_RESPONSE_TIME_SECONDS - .with_label_values(&[&request_method, request_path]) - .start_timer(), - ); - metrics::HTTP_REQUESTS_TOTAL - .with_label_values(&[&request_method, request_path]) - .inc(); - } - - let fut = srv.call(req); - - async { - let res = fut.await?; - if let Some(histogram_timer) = histogram_timer { - histogram_timer.observe_duration(); - }; - Ok(res) - } - }) + .configure(|s| configure_metrics_route(s, $opt.enable_metrics_route)) .wrap( Cors::default() .send_wildcard() @@ -203,5 +181,9 @@ macro_rules! create_app { .wrap(middleware::NormalizePath::new( middleware::TrailingSlash::Trim, )) + .wrap(Condition::new( + $opt.enable_metrics_route, + route_metrics::RouteMetrics, + )) }}; } diff --git a/meilisearch-http/src/option.rs b/meilisearch-http/src/option.rs index 04b61f74e..0f1e356e7 100644 --- a/meilisearch-http/src/option.rs +++ b/meilisearch-http/src/option.rs @@ -146,6 +146,10 @@ pub struct Opt { #[clap(long, env = "MEILI_LOG_LEVEL", default_value = "info")] pub log_level: String, + // Enables Prometheus metrics and /metrics route. + #[clap(long, requires = "enable-metrics-route")] + pub enable_metrics_route: bool, + #[serde(flatten)] #[clap(flatten)] pub indexer_options: IndexerOpts, @@ -161,7 +165,7 @@ impl Opt { pub fn analytics(&self) -> bool { !self.no_analytics } - + pub fn get_ssl_config(&self) -> anyhow::Result> { if let (Some(cert_path), Some(key_path)) = (&self.ssl_cert_path, &self.ssl_key_path) { let config = rustls::ServerConfig::builder().with_safe_defaults(); diff --git a/meilisearch-http/src/route_metrics.rs b/meilisearch-http/src/route_metrics.rs new file mode 100644 index 000000000..b1b85f9c8 --- /dev/null +++ b/meilisearch-http/src/route_metrics.rs @@ -0,0 +1,75 @@ +use std::future::{ready, Ready}; + +use actix_web::{ + dev::{self, Service, ServiceRequest, ServiceResponse, Transform}, + Error, +}; +use futures_util::future::LocalBoxFuture; +use prometheus::HistogramTimer; + +pub struct RouteMetrics; + +// Middleware factory is `Transform` trait from actix-service crate +// `S` - type of the next service +// `B` - type of response's body +impl Transform for RouteMetrics +where + S: Service, Error = Error>, + S::Future: 'static, + B: 'static, +{ + type Response = ServiceResponse; + type Error = Error; + type InitError = (); + type Transform = RouteMetricsMiddleware; + type Future = Ready>; + + fn new_transform(&self, service: S) -> Self::Future { + ready(Ok(RouteMetricsMiddleware { service })) + } +} + +pub struct RouteMetricsMiddleware { + service: S, +} + +impl Service for RouteMetricsMiddleware +where + S: Service, Error = Error>, + S::Future: 'static, + B: 'static, +{ + type Response = ServiceResponse; + type Error = Error; + type Future = LocalBoxFuture<'static, Result>; + + dev::forward_ready!(service); + + fn call(&self, req: ServiceRequest) -> Self::Future { + let mut histogram_timer: Option = None; + let request_path = req.path(); + let is_registered_resource = req.resource_map().has_resource(request_path); + if is_registered_resource { + let request_method = req.method().to_string(); + histogram_timer = Some( + crate::metrics::HTTP_RESPONSE_TIME_SECONDS + .with_label_values(&[&request_method, request_path]) + .start_timer(), + ); + crate::metrics::HTTP_REQUESTS_TOTAL + .with_label_values(&[&request_method, request_path]) + .inc(); + } + + let fut = self.service.call(req); + + Box::pin(async move { + let res = fut.await?; + + if let Some(histogram_timer) = histogram_timer { + histogram_timer.observe_duration(); + }; + Ok(res) + }) + } +} diff --git a/meilisearch-http/src/routes/mod.rs b/meilisearch-http/src/routes/mod.rs index 8f5c9f3d4..9412dece2 100644 --- a/meilisearch-http/src/routes/mod.rs +++ b/meilisearch-http/src/routes/mod.rs @@ -21,7 +21,6 @@ mod tasks; pub fn configure(cfg: &mut web::ServiceConfig) { cfg.service(web::scope("/tasks").configure(tasks::configure)) .service(web::resource("/health").route(web::get().to(get_health))) - .service(web::resource("/metrics").route(web::get().to(get_metrics))) .service(web::scope("/keys").configure(api_key::configure)) .service(web::scope("/dumps").configure(dump::configure)) .service(web::resource("/stats").route(web::get().to(get_stats)))