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)
#include "webserver.h"
#include "falco_metrics.h"
#endif
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)
+ ssl_option + "\n");
falco_metrics metrics(state);
state.webserver.start(
state.offline_inspector,
webserver_config,
metrics);
state,
webserver_config);
}
#endif
return run_result::ok();
@@ -73,4 +69,3 @@ falco::app::run_result falco::app::actions::stop_webserver(falco::app::state& st
#endif
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";
/*!
\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.
*/
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[] = {
BPF_ENGINE, KMOD_ENGINE, MODERN_BPF_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;
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++)
{
@@ -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();
auto metrics_snapshot = metrics_collector.get_metrics();

View File

@@ -28,13 +28,5 @@ class falco_metrics
{
public:
static const std::string content_type;
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;
static std::string to_text(const falco::app::state& state);
};

View File

@@ -18,6 +18,7 @@ limitations under the License.
#include "webserver.h"
#include "falco_utils.h"
#include "falco_metrics.h"
#include "app/state.h"
#include "versions_info.h"
#include <atomic>
@@ -27,9 +28,8 @@ falco_webserver::~falco_webserver()
}
void falco_webserver::start(
const std::shared_ptr<sinsp>& inspector,
const falco_configuration::webserver_config& webserver_config,
const falco_metrics& metrics)
const falco::app::state& state,
const falco_configuration::webserver_config& webserver_config)
{
if (m_running)
{
@@ -59,17 +59,17 @@ void falco_webserver::start(
});
// 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",
[versions_json_str](const httplib::Request &, httplib::Response &res) {
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",
[metrics](const httplib::Request &, httplib::Response &res) {
res.set_content(metrics.to_text(), falco_metrics::content_type);
[&state](const httplib::Request &, httplib::Response &res) {
res.set_content(falco_metrics::to_text(state), falco_metrics::content_type);
});
}
// run server in a separate thread

View File

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