diff --git a/userspace/falco/app/actions/start_webserver.cpp b/userspace/falco/app/actions/start_webserver.cpp index d4e2c365b0e..cbb100365a1 100644 --- a/userspace/falco/app/actions/start_webserver.cpp +++ b/userspace/falco/app/actions/start_webserver.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 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(); diff --git a/userspace/falco/falco_metrics.cpp b/userspace/falco/falco_metrics.cpp new file mode 100644 index 00000000000..945f03f0832 --- /dev/null +++ b/userspace/falco/falco_metrics.cpp @@ -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 + +falco_metrics::falco_metrics(falco::app::state& state) +{ + falco_configuration::webserver_config webserver_config = state.config->m_webserver_config; + m_is_enabled = state.config->m_metrics_enabled && webserver_config.m_metrics_enabled; + + if (m_is_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_is_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 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 += 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 += converter.convert_metric_to_text_prometheus("falco_version", "falcosecurity", "falco", {{"falco_version", FALCO_VERSION}}); + prometheus_text += converter.convert_metric_to_text_prometheus("kernel_release", "falcosecurity", "falco", {{"kernel_release", agent_info->uname_r}}); + prometheus_text += converter.convert_metric_to_text_prometheus("evt_hostname", "falcosecurity", "falco", {{"evt_hostname", machine_info->hostname}}); + + std::vector 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) + { + converter.convert_metric_to_unit_convention(metrics); + prometheus_text += 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) + { + converter.convert_metric_to_unit_convention(metric); + prometheus_text += converter.convert_metric_to_text_prometheus(metric, "falcosecurity", "scap"); + } + } + return prometheus_text; +} diff --git a/userspace/falco/falco_metrics.h b/userspace/falco/falco_metrics.h new file mode 100644 index 00000000000..04f614dc82c --- /dev/null +++ b/userspace/falco/falco_metrics.h @@ -0,0 +1,40 @@ +// 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 + +namespace falco { + namespace app { + class state; + } +} + +class falco_metrics +{ +public: + falco_metrics(falco::app::state& state); + bool is_enabled() const { return m_is_enabled; }; + std::string to_text() const; + +private: + bool m_is_enabled = false; + std::vector m_inspectors; + std::vector m_metrics_collectors; +}; diff --git a/userspace/falco/webserver.cpp b/userspace/falco/webserver.cpp index 33e55477728..ee761b7f8fb 100644 --- a/userspace/falco/webserver.cpp +++ b/userspace/falco/webserver.cpp @@ -17,6 +17,7 @@ limitations under the License. #include "webserver.h" #include "falco_utils.h" +#include "falco_metrics.h" #include "versions_info.h" #include @@ -27,8 +28,8 @@ falco_webserver::~falco_webserver() void falco_webserver::start( const std::shared_ptr& inspector, - const std::vector& metrics_collectors, - const falco_configuration::webserver_config& configuration) + const falco_configuration::webserver_config& configuration, + const falco_metrics& metrics) { if (m_running) { @@ -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 diff --git a/userspace/falco/webserver.h b/userspace/falco/webserver.h index 57eae4d2b23..8ee3fddcc2a 100644 --- a/userspace/falco/webserver.h +++ b/userspace/falco/webserver.h @@ -25,6 +25,8 @@ limitations under the License. #include #include +class falco_metrics; + class falco_webserver { public: @@ -36,8 +38,8 @@ class falco_webserver falco_webserver& operator = (const falco_webserver&) = delete; virtual void start( const std::shared_ptr& inspector, - const std::vector& metrics_collectors, - const falco_configuration::webserver_config& configuration); + const falco_configuration::webserver_config& configuration, + const falco_metrics& metrics); virtual void stop(); private: