mirror of
https://github.com/falcosecurity/falco.git
synced 2025-08-01 06:29:47 +00:00
refactor(metrics): move metrics handling to its own class
This will keep the details out of the webserver itself and make it easier to manage metrics. Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
This commit is contained in:
parent
e50d647dc9
commit
daf7efde67
@ -93,6 +93,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT MINIMAL_BUILD)
|
||||
PRIVATE
|
||||
outputs_grpc.cpp
|
||||
outputs_http.cpp
|
||||
falco_metrics.cpp
|
||||
webserver.cpp
|
||||
grpc_context.cpp
|
||||
grpc_request_context.cpp
|
||||
|
@ -19,6 +19,7 @@ limitations under the License.
|
||||
|
||||
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||
#include "webserver.h"
|
||||
#include "falco_metrics.h"
|
||||
#endif
|
||||
|
||||
using namespace falco::app;
|
||||
@ -45,19 +46,12 @@ falco::app::run_result falco::app::actions::start_webserver(falco::app::state& s
|
||||
+ std::to_string(webserver_config.m_listen_port)
|
||||
+ ssl_option + "\n");
|
||||
|
||||
std::vector<libs::metrics::libs_metrics_collector> metrics_collectors;
|
||||
if (state.config->m_metrics_enabled && webserver_config.m_metrics_enabled)
|
||||
{
|
||||
for (const auto& source_info: state.source_infos)
|
||||
{
|
||||
metrics_collectors.push_back(libs::metrics::libs_metrics_collector(source_info.inspector.get(), state.config->m_metrics_flags));
|
||||
}
|
||||
}
|
||||
falco_metrics metrics(state);
|
||||
|
||||
state.webserver.start(
|
||||
state.offline_inspector,
|
||||
metrics_collectors,
|
||||
webserver_config);
|
||||
webserver_config,
|
||||
metrics);
|
||||
}
|
||||
#endif
|
||||
return run_result::ok();
|
||||
|
114
userspace/falco/falco_metrics.cpp
Normal file
114
userspace/falco/falco_metrics.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
Copyright (C) 2024 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "falco_metrics.h"
|
||||
|
||||
#include "app/state.h"
|
||||
|
||||
#include <libsinsp/sinsp.h>
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string falco_metrics::to_text() const
|
||||
{
|
||||
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 };
|
||||
|
||||
|
||||
libs::metrics::prometheus_metrics_converter prometheus_metrics_converter;
|
||||
std::string prometheus_text;
|
||||
|
||||
for (auto* inspector: m_inspectors)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(all_driver_engines) / sizeof(const char*); i++)
|
||||
{
|
||||
if (inspector->check_current_engine(all_driver_engines[i]))
|
||||
{
|
||||
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus("engine_name", "falcosecurity", "scap", {{"engine_name", all_driver_engines[i]}});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const scap_agent_info* agent_info = inspector->get_agent_info();
|
||||
const scap_machine_info* machine_info = inspector->get_machine_info();
|
||||
|
||||
libs::metrics::libs_metrics_collector libs_metrics_collector(inspector, 0);
|
||||
|
||||
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus("falco_version", "falcosecurity", "falco", {{"falco_version", FALCO_VERSION}});
|
||||
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus("kernel_release", "falcosecurity", "falco", {{"kernel_release", agent_info->uname_r}});
|
||||
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus("evt_hostname", "falcosecurity", "falco", {{"evt_hostname", machine_info->hostname}});
|
||||
|
||||
std::vector<metrics_v2> static_metrics;
|
||||
static_metrics.push_back(libs_metrics_collector.new_metric("start_ts",
|
||||
METRICS_V2_LIBBPF_STATS,
|
||||
METRIC_VALUE_TYPE_U64,
|
||||
METRIC_VALUE_UNIT_TIME_NS_COUNT,
|
||||
METRIC_VALUE_METRIC_TYPE_MONOTONIC,
|
||||
agent_info->start_ts_epoch));
|
||||
static_metrics.push_back(libs_metrics_collector.new_metric("falco_host_boot_ts",
|
||||
METRICS_V2_LIBBPF_STATS,
|
||||
METRIC_VALUE_TYPE_U64,
|
||||
METRIC_VALUE_UNIT_TIME_NS_COUNT,
|
||||
METRIC_VALUE_METRIC_TYPE_MONOTONIC,
|
||||
machine_info->boot_ts_epoch));
|
||||
static_metrics.push_back(libs_metrics_collector.new_metric("falco_host_num_cpus",
|
||||
METRICS_V2_LIBBPF_STATS,
|
||||
METRIC_VALUE_TYPE_U64,
|
||||
METRIC_VALUE_UNIT_TIME_NS_COUNT,
|
||||
METRIC_VALUE_METRIC_TYPE_MONOTONIC,
|
||||
machine_info->num_cpus));
|
||||
|
||||
for (auto metrics: static_metrics)
|
||||
{
|
||||
prometheus_metrics_converter.convert_metric_to_unit_convention(metrics);
|
||||
prometheus_text += prometheus_metrics_converter.convert_metric_to_text_prometheus(metrics, "falcosecurity", "falco");
|
||||
}
|
||||
}
|
||||
|
||||
for (auto metrics_collector: m_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, "falcosecurity", "scap");
|
||||
}
|
||||
}
|
||||
return prometheus_text;
|
||||
}
|
38
userspace/falco/falco_metrics.h
Normal file
38
userspace/falco/falco_metrics.h
Normal file
@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
Copyright (C) 2024 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
#include <libsinsp/sinsp.h>
|
||||
|
||||
namespace falco::app {
|
||||
struct state;
|
||||
}
|
||||
|
||||
class falco_metrics
|
||||
{
|
||||
public:
|
||||
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;
|
||||
};
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||
|
||||
#include "webserver.h"
|
||||
#include "falco_utils.h"
|
||||
#include "falco_metrics.h"
|
||||
#include "versions_info.h"
|
||||
#include <atomic>
|
||||
|
||||
@ -27,8 +28,8 @@ falco_webserver::~falco_webserver()
|
||||
|
||||
void falco_webserver::start(
|
||||
const std::shared_ptr<sinsp>& inspector,
|
||||
const std::vector<libs::metrics::libs_metrics_collector>& metrics_collectors,
|
||||
const falco_configuration::webserver_config& configuration)
|
||||
const falco_configuration::webserver_config& webserver_config,
|
||||
const falco_metrics& metrics)
|
||||
{
|
||||
if (m_running)
|
||||
{
|
||||
@ -37,11 +38,11 @@ void falco_webserver::start(
|
||||
}
|
||||
|
||||
// allocate and configure server
|
||||
if (configuration.m_ssl_enabled)
|
||||
if (webserver_config.m_ssl_enabled)
|
||||
{
|
||||
m_server = std::make_unique<httplib::SSLServer>(
|
||||
configuration.m_ssl_certificate.c_str(),
|
||||
configuration.m_ssl_certificate.c_str());
|
||||
webserver_config.m_ssl_certificate.c_str(),
|
||||
webserver_config.m_ssl_certificate.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -49,10 +50,10 @@ void falco_webserver::start(
|
||||
}
|
||||
|
||||
// configure server
|
||||
m_server->new_task_queue = [configuration] { return new httplib::ThreadPool(configuration.m_threadiness); };
|
||||
m_server->new_task_queue = [webserver_config] { return new httplib::ThreadPool(webserver_config.m_threadiness); };
|
||||
|
||||
// setup healthz endpoint
|
||||
m_server->Get(configuration.m_k8s_healthz_endpoint,
|
||||
m_server->Get(webserver_config.m_k8s_healthz_endpoint,
|
||||
[](const httplib::Request &, httplib::Response &res) {
|
||||
res.set_content("{\"status\": \"ok\"}", "application/json");
|
||||
});
|
||||
@ -64,26 +65,11 @@ void falco_webserver::start(
|
||||
res.set_content(versions_json_str, "application/json");
|
||||
});
|
||||
|
||||
if (!metrics_collectors.empty())
|
||||
if (metrics.is_enabled())
|
||||
{
|
||||
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, "falcosecurity", "falco");
|
||||
}
|
||||
}
|
||||
|
||||
res.set_content(prometheus_text, "text/plain; version=0.0.4");
|
||||
[metrics](const httplib::Request &, httplib::Response &res) {
|
||||
res.set_content(metrics.to_text(), "text/plain; version=0.0.4");
|
||||
});
|
||||
}
|
||||
// run server in a separate thread
|
||||
@ -95,11 +81,11 @@ void falco_webserver::start(
|
||||
|
||||
std::atomic<bool> failed;
|
||||
failed.store(false, std::memory_order_release);
|
||||
m_server_thread = std::thread([this, configuration, &failed]
|
||||
m_server_thread = std::thread([this, webserver_config, &failed]
|
||||
{
|
||||
try
|
||||
{
|
||||
this->m_server->listen(configuration.m_listen_address, configuration.m_listen_port);
|
||||
this->m_server->listen(webserver_config.m_listen_address, webserver_config.m_listen_port);
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
|
@ -25,6 +25,8 @@ limitations under the License.
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
class falco_metrics;
|
||||
|
||||
class falco_webserver
|
||||
{
|
||||
public:
|
||||
@ -36,8 +38,8 @@ public:
|
||||
falco_webserver& operator = (const falco_webserver&) = delete;
|
||||
virtual void start(
|
||||
const std::shared_ptr<sinsp>& inspector,
|
||||
const std::vector<libs::metrics::libs_metrics_collector>& metrics_collectors,
|
||||
const falco_configuration::webserver_config& configuration);
|
||||
const falco_configuration::webserver_config& webserver_config,
|
||||
const falco_metrics& metrics);
|
||||
virtual void stop();
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user