refactor(metrics): make to_text get the application state

As falco may update its state at any time and thus its inspectors objects,
keeping pointers to them may end up in using dangling values.

Therefore, use the state of the application when requesting metrics.

Optimizations such as caching of mostly static values will be done in
a follow up patch.

Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
This commit is contained in:
Samuel Gaist
2024-04-16 09:02:55 +02:00
committed by poiana
parent a0c109fcff
commit 5c237a07dc
5 changed files with 31 additions and 56 deletions

View File

@@ -19,7 +19,6 @@ limitations under the License.
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD) #if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
#include "webserver.h" #include "webserver.h"
#include "falco_metrics.h"
#endif #endif
using namespace falco::app; using namespace falco::app;
@@ -46,12 +45,9 @@ falco::app::run_result falco::app::actions::start_webserver(falco::app::state& s
+ std::to_string(webserver_config.m_listen_port) + std::to_string(webserver_config.m_listen_port)
+ ssl_option + "\n"); + ssl_option + "\n");
falco_metrics metrics(state);
state.webserver.start( state.webserver.start(
state.offline_inspector, state,
webserver_config, webserver_config);
metrics);
} }
#endif #endif
return run_result::ok(); return run_result::ok();
@@ -73,4 +69,3 @@ falco::app::run_result falco::app::actions::stop_webserver(falco::app::state& st
#endif #endif
return run_result::ok(); return run_result::ok();
} }

View File

@@ -36,46 +36,33 @@ limitations under the License.
*/ */
const std::string falco_metrics::content_type = "text/plain; version=0.0.4"; const std::string falco_metrics::content_type = "text/plain; version=0.0.4";
/*!
\brief Constructor that takes a \c state object to build its internal state
*/
falco_metrics::falco_metrics(falco::app::state& state)
{
falco_configuration::webserver_config webserver_config = state.config->m_webserver_config;
m_metrics_enabled = state.config->m_metrics_enabled && webserver_config.m_metrics_enabled;
if (m_metrics_enabled)
{
for (const auto& source_info: state.source_infos)
{
sinsp *source_inspector = source_info.inspector.get();
m_inspectors.push_back(source_inspector);
m_metrics_collectors.push_back(libs::metrics::libs_metrics_collector(source_inspector, state.config->m_metrics_flags));
}
}
}
/*! /*!
\brief This method returns a textual representation of the metrics configured. \brief this method takes an application \c state and returns a textual representation of
its configured metrics.
The current implementation returns a Prometheus exposition formatted string. The current implementation returns a Prometheus exposition formatted string.
*/ */
std::string falco_metrics::to_text() const std::string falco_metrics::to_text(const falco::app::state& state)
{ {
if (!m_metrics_enabled)
{
return "";
}
static const char* all_driver_engines[] = { static const char* all_driver_engines[] = {
BPF_ENGINE, KMOD_ENGINE, MODERN_BPF_ENGINE, BPF_ENGINE, KMOD_ENGINE, MODERN_BPF_ENGINE,
SOURCE_PLUGIN_ENGINE, NODRIVER_ENGINE, GVISOR_ENGINE }; SOURCE_PLUGIN_ENGINE, NODRIVER_ENGINE, GVISOR_ENGINE };
std::vector<sinsp*> inspectors;
std::vector<libs::metrics::libs_metrics_collector> metrics_collectors;
for (const auto& source_info: state.source_infos)
{
sinsp *source_inspector = source_info.inspector.get();
inspectors.push_back(source_inspector);
metrics_collectors.push_back(libs::metrics::libs_metrics_collector(source_inspector, state.config->m_metrics_flags));
}
libs::metrics::prometheus_metrics_converter prometheus_metrics_converter; libs::metrics::prometheus_metrics_converter prometheus_metrics_converter;
std::string prometheus_text; std::string prometheus_text;
for (auto* inspector: m_inspectors) for (auto* inspector: inspectors)
{ {
for (size_t i = 0; i < sizeof(all_driver_engines) / sizeof(const char*); i++) for (size_t i = 0; i < sizeof(all_driver_engines) / sizeof(const char*); i++)
{ {
@@ -122,7 +109,7 @@ std::string falco_metrics::to_text() const
} }
} }
for (auto metrics_collector: m_metrics_collectors) for (auto metrics_collector: metrics_collectors)
{ {
metrics_collector.snapshot(); metrics_collector.snapshot();
auto metrics_snapshot = metrics_collector.get_metrics(); auto metrics_snapshot = metrics_collector.get_metrics();

View File

@@ -28,13 +28,5 @@ class falco_metrics
{ {
public: public:
static const std::string content_type; static const std::string content_type;
static std::string to_text(const falco::app::state& state);
falco_metrics(falco::app::state& state);
bool is_enabled() const { return m_metrics_enabled; };
std::string to_text() const;
private:
bool m_metrics_enabled = false;
std::vector<sinsp*> m_inspectors;
std::vector<libs::metrics::libs_metrics_collector> m_metrics_collectors;
}; };

View File

@@ -18,6 +18,7 @@ limitations under the License.
#include "webserver.h" #include "webserver.h"
#include "falco_utils.h" #include "falco_utils.h"
#include "falco_metrics.h" #include "falco_metrics.h"
#include "app/state.h"
#include "versions_info.h" #include "versions_info.h"
#include <atomic> #include <atomic>
@@ -27,9 +28,8 @@ falco_webserver::~falco_webserver()
} }
void falco_webserver::start( void falco_webserver::start(
const std::shared_ptr<sinsp>& inspector, const falco::app::state& state,
const falco_configuration::webserver_config& webserver_config, const falco_configuration::webserver_config& webserver_config)
const falco_metrics& metrics)
{ {
if (m_running) if (m_running)
{ {
@@ -59,17 +59,17 @@ void falco_webserver::start(
}); });
// setup versions endpoint // setup versions endpoint
const auto versions_json_str = falco::versions_info(inspector).as_json().dump(); const auto versions_json_str = falco::versions_info(state.offline_inspector).as_json().dump();
m_server->Get("/versions", m_server->Get("/versions",
[versions_json_str](const httplib::Request &, httplib::Response &res) { [versions_json_str](const httplib::Request &, httplib::Response &res) {
res.set_content(versions_json_str, "application/json"); res.set_content(versions_json_str, "application/json");
}); });
if (metrics.is_enabled()) if (state.config->m_metrics_enabled && webserver_config.m_metrics_enabled)
{ {
m_server->Get("/metrics", m_server->Get("/metrics",
[metrics](const httplib::Request &, httplib::Response &res) { [&state](const httplib::Request &, httplib::Response &res) {
res.set_content(metrics.to_text(), falco_metrics::content_type); res.set_content(falco_metrics::to_text(state), falco_metrics::content_type);
}); });
} }
// run server in a separate thread // run server in a separate thread

View File

@@ -25,7 +25,9 @@ limitations under the License.
#include <memory> #include <memory>
#include <thread> #include <thread>
class falco_metrics; namespace falco::app {
struct state;
}
class falco_webserver class falco_webserver
{ {
@@ -37,9 +39,8 @@ public:
falco_webserver(const falco_webserver&) = delete; falco_webserver(const falco_webserver&) = delete;
falco_webserver& operator = (const falco_webserver&) = delete; falco_webserver& operator = (const falco_webserver&) = delete;
virtual void start( virtual void start(
const std::shared_ptr<sinsp>& inspector, const falco::app::state& state,
const falco_configuration::webserver_config& webserver_config, const falco_configuration::webserver_config& webserver_config);
const falco_metrics& metrics);
virtual void stop(); virtual void stop();
private: private: