From 8f1b2dc9096406e7b90f4622f182cfb0f8d60aa6 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Fri, 15 Mar 2024 22:18:00 +0100 Subject: [PATCH] feat(webserver): implement metrics endpoint This endpoint currently returns only prometheus metrics. Signed-off-by: Samuel Gaist --- falco.yaml | 1 + .../falco/app/actions/start_webserver.cpp | 10 +++++++ userspace/falco/configuration.cpp | 4 ++- userspace/falco/configuration.h | 1 + userspace/falco/webserver.cpp | 28 ++++++++++++++++--- userspace/falco/webserver.h | 1 + 6 files changed, 40 insertions(+), 5 deletions(-) diff --git a/falco.yaml b/falco.yaml index 2586c297..5e793ddd 100644 --- a/falco.yaml +++ b/falco.yaml @@ -1003,6 +1003,7 @@ metrics: libbpf_stats_enabled: true convert_memory_to_mb: true include_empty_values: false + prometheus_enabled: false ####################################### # Falco performance tuning (advanced) # diff --git a/userspace/falco/app/actions/start_webserver.cpp b/userspace/falco/app/actions/start_webserver.cpp index 48a46fe2..c8cb6ee8 100644 --- a/userspace/falco/app/actions/start_webserver.cpp +++ b/userspace/falco/app/actions/start_webserver.cpp @@ -44,8 +44,18 @@ falco::app::run_result falco::app::actions::start_webserver(falco::app::state& s + std::to_string(s.config->m_webserver_listen_port) + ssl_option + "\n"); + std::vector metrics_collectors; + if (s.config->m_metrics_prometheus_enabled && s.config->m_metrics_prometheus_enabled) + { + for (const auto& source_info: s.source_infos) + { + metrics_collectors.push_back(libs::metrics::libs_metrics_collector(source_info.inspector.get(), s.config->m_metrics_flags)); + } + } + s.webserver.start( s.offline_inspector, + metrics_collectors, s.config->m_webserver_threadiness, s.config->m_webserver_listen_port, s.config->m_webserver_listen_address, diff --git a/userspace/falco/configuration.cpp b/userspace/falco/configuration.cpp index 6a0b7e1e..593b8a3f 100644 --- a/userspace/falco/configuration.cpp +++ b/userspace/falco/configuration.cpp @@ -79,7 +79,8 @@ falco_configuration::falco_configuration(): m_metrics_output_file(""), m_metrics_flags((METRICS_V2_KERNEL_COUNTERS | METRICS_V2_LIBBPF_STATS | METRICS_V2_RESOURCE_UTILIZATION | METRICS_V2_STATE_COUNTERS)), m_metrics_convert_memory_to_mb(true), - m_metrics_include_empty_values(false) + m_metrics_include_empty_values(false), + m_metrics_prometheus_enabled(false) { } @@ -553,6 +554,7 @@ void falco_configuration::load_yaml(const std::string& config_name) m_metrics_convert_memory_to_mb = config.get_scalar("metrics.convert_memory_to_mb", true); m_metrics_include_empty_values = config.get_scalar("metrics.include_empty_values", false); + m_metrics_prometheus_enabled = config.get_scalar("metrics.prometheus_enabled", false); std::vector load_plugins; diff --git a/userspace/falco/configuration.h b/userspace/falco/configuration.h index 29564e14..00d5b9e2 100644 --- a/userspace/falco/configuration.h +++ b/userspace/falco/configuration.h @@ -158,6 +158,7 @@ public: uint32_t m_metrics_flags; bool m_metrics_convert_memory_to_mb; bool m_metrics_include_empty_values; + bool m_metrics_prometheus_enabled; std::vector m_plugins; // Falco engine diff --git a/userspace/falco/webserver.cpp b/userspace/falco/webserver.cpp index f33fcf93..de9d1d6f 100644 --- a/userspace/falco/webserver.cpp +++ b/userspace/falco/webserver.cpp @@ -27,6 +27,7 @@ falco_webserver::~falco_webserver() void falco_webserver::start( const std::shared_ptr& inspector, + const std::vector& metrics_collectors, uint32_t threadiness, uint32_t listen_port, std::string& listen_address, @@ -68,6 +69,28 @@ void falco_webserver::start( res.set_content(versions_json_str, "application/json"); }); + if (!metrics_collectors.empty()) + { + libs::metrics::prometheus_metrics_converter prometheus_metrics_converter; + + m_server->Get("/metrics", + [metrics_collectors, prometheus_metrics_converter](const httplib::Request &, httplib::Response &res) { + std::string prometheus_text; + + for (auto metrics_collector: metrics_collectors) { + metrics_collector.snapshot(); + auto metrics_snapshot = metrics_collector.get_metrics(); + + for (auto& metric: metrics_snapshot) + { + prometheus_metrics_converter.convert_metric_to_unit_convention(metric); + prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus(metric, "namespace", "falco") + "\n"; + } + } + + res.set_content(prometheus_text, "text/plain; version=0.0.4"); + }); + } // run server in a separate thread if (!m_server->is_valid()) { @@ -118,10 +141,7 @@ void falco_webserver::stop() { m_server_thread.join(); } - if (m_server != nullptr) - { - m_server = nullptr; - } + m_server = nullptr; m_running = false; } } diff --git a/userspace/falco/webserver.h b/userspace/falco/webserver.h index 62f2e610..81f446d5 100644 --- a/userspace/falco/webserver.h +++ b/userspace/falco/webserver.h @@ -36,6 +36,7 @@ public: falco_webserver& operator = (const falco_webserver&) = delete; virtual void start( const std::shared_ptr& inspector, + const std::vector& metrics_collectors, uint32_t threadiness, uint32_t listen_port, std::string& list_address,