From 1c71777dbdf7bfd5f6fc1989588c4f7d5774aaed Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Wed, 20 Nov 2024 12:10:47 +0100 Subject: [PATCH] new(cmake,userspace): expose jemalloc stats in stats writer and prometheus metircs. Signed-off-by: Federico Di Pierro --- cmake/modules/jemalloc.cmake | 9 ++++-- falco.yaml | 1 + userspace/falco/config_json_schema.h | 3 ++ userspace/falco/configuration.cpp | 3 ++ userspace/falco/configuration.h | 3 ++ userspace/falco/falco_metrics.cpp | 36 ++++++++++++++++++++++++ userspace/falco/stats_writer.cpp | 41 ++++++++++++++++++++++++++++ 7 files changed, 94 insertions(+), 2 deletions(-) diff --git a/cmake/modules/jemalloc.cmake b/cmake/modules/jemalloc.cmake index 647c3bf5..3f80ac75 100644 --- a/cmake/modules/jemalloc.cmake +++ b/cmake/modules/jemalloc.cmake @@ -15,9 +15,10 @@ option(USE_BUNDLED_JEMALLOC "Use bundled jemalloc allocator" ${USE_BUNDLED_DEPS}) -if(JEMALLOC_LIB) +if(JEMALLOC_INCLUDE) # we already have JEMALLOC elseif(NOT USE_BUNDLED_JEMALLOC) + find_path(JEMALLOC_INCLUDE jemalloc/jemalloc.h) if(BUILD_SHARED_LIBS) set(JEMALLOC_LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}) else() @@ -37,6 +38,7 @@ else() endif() set(JEMALLOC_SRC "${PROJECT_BINARY_DIR}/jemalloc-prefix/src") set(JEMALLOC_LIB "${JEMALLOC_SRC}/jemalloc/lib/libjemalloc${JEMALLOC_LIB_SUFFIX}") + set(JEMALLOC_INCLUDE "${JEMALLOC_SRC}/jemalloc/include/jemalloc") ExternalProject_Add( jemalloc PREFIX "${PROJECT_BINARY_DIR}/jemalloc-prefix" @@ -49,7 +51,7 @@ else() UPDATE_COMMAND "" BUILD_BYPRODUCTS ${JEMALLOC_LIB} ) - message(STATUS "Using bundled jemalloc: lib: ${JEMALLOC_LIB}") + message(STATUS "Using bundled jemalloc: include: ${JEMALLOC_INCLUDE}, lib: ${JEMALLOC_LIB}") install( FILES "${JEMALLOC_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}" @@ -62,3 +64,6 @@ endif() if(NOT TARGET jemalloc) add_custom_target(jemalloc) endif() + +include_directories(${JEMALLOC_INCLUDE}) +add_compile_definitions(HAS_JEMALLOC) diff --git a/falco.yaml b/falco.yaml index d70fbb28..33c8dd8b 100644 --- a/falco.yaml +++ b/falco.yaml @@ -1136,6 +1136,7 @@ metrics: kernel_event_counters_per_cpu_enabled: false libbpf_stats_enabled: true plugins_metrics_enabled: true + jemalloc_stats_enabled: false convert_memory_to_mb: true include_empty_values: false diff --git a/userspace/falco/config_json_schema.h b/userspace/falco/config_json_schema.h index e988b8f6..4d2d0844 100644 --- a/userspace/falco/config_json_schema.h +++ b/userspace/falco/config_json_schema.h @@ -575,6 +575,9 @@ const char config_schema_string[] = LONG_STRING_CONST( }, "include_empty_values": { "type": "boolean" + }, + "jemalloc_stats_enabled": { + "type": "boolean" } }, "minProperties": 1, diff --git a/userspace/falco/configuration.cpp b/userspace/falco/configuration.cpp index a89fbb65..f6ff27f5 100644 --- a/userspace/falco/configuration.cpp +++ b/userspace/falco/configuration.cpp @@ -611,6 +611,9 @@ void falco_configuration::load_yaml(const std::string &config_name) { if(m_config.get_scalar("metrics.plugins_metrics_enabled", true)) { m_metrics_flags |= METRICS_V2_PLUGINS; } + if(m_config.get_scalar("metrics.jemalloc_stats_enabled", true)) { + m_metrics_flags |= METRICS_V2_JEMALLOC_STATS; + } m_metrics_convert_memory_to_mb = m_config.get_scalar("metrics.convert_memory_to_mb", true); diff --git a/userspace/falco/configuration.h b/userspace/falco/configuration.h index e6266ead..c92ada52 100644 --- a/userspace/falco/configuration.h +++ b/userspace/falco/configuration.h @@ -37,6 +37,9 @@ limitations under the License. #include "event_drops.h" #include "falco_outputs.h" +// Falco only metric +#define METRICS_V2_JEMALLOC_STATS 1 << 31 + enum class engine_kind_t : uint8_t { KMOD, EBPF, MODERN_EBPF, REPLAY, GVISOR, NODRIVER }; // Map that holds { config filename | validation status } for each loaded config file. diff --git a/userspace/falco/falco_metrics.cpp b/userspace/falco/falco_metrics.cpp index 8d58338d..aca5e8fd 100644 --- a/userspace/falco/falco_metrics.cpp +++ b/userspace/falco/falco_metrics.cpp @@ -23,6 +23,10 @@ limitations under the License. #include +#ifdef HAS_JEMALLOC +#include +#endif + namespace fs = std::filesystem; /*! @@ -249,6 +253,38 @@ std::string falco_metrics::to_text(const falco::app::state& state) { } } } +#ifdef HAS_JEMALLOC + if(state.config->m_metrics_flags & METRICS_V2_JEMALLOC_STATS) { + nlohmann::json j; + malloc_stats_print( + [](void* to, const char* from) { + nlohmann::json* j = (nlohmann::json*)to; + *j = nlohmann::json::parse(from); + }, + &j, + "Jmdablxeg"); + const auto& j_stats = j["jemalloc"]["stats"]; + for(auto it = j_stats.begin(); it != j_stats.end(); ++it) { + if(it.value().is_number_unsigned()) { + std::uint64_t val = it.value().template get(); + std::string key = "jemalloc." + it.key(); + auto metric = libs::metrics::libsinsp_metrics::new_metric( + key.c_str(), + METRICS_V2_JEMALLOC_STATS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_MEMORY_BYTES, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + val); + prometheus_metrics_converter.convert_metric_to_unit_convention(metric); + prometheus_text += + prometheus_metrics_converter.convert_metric_to_text_prometheus( + metric, + "falcosecurity", + "falco"); + } + } + } +#endif } // Libs metrics categories diff --git a/userspace/falco/stats_writer.cpp b/userspace/falco/stats_writer.cpp index c5af9698..eac9e784 100644 --- a/userspace/falco/stats_writer.cpp +++ b/userspace/falco/stats_writer.cpp @@ -32,6 +32,10 @@ limitations under the License. #include #include +#ifdef HAS_JEMALLOC +#include +#endif + namespace fs = std::filesystem; // note: ticker_t is an uint16_t, which is enough because we don't care about @@ -434,6 +438,43 @@ void stats_writer::collector::get_metrics_output_fields_additional( } } +#ifdef HAS_JEMALLOC + if(m_writer->m_config->m_metrics_flags & METRICS_V2_JEMALLOC_STATS) { + nlohmann::json j; + malloc_stats_print( + [](void* to, const char* from) { + nlohmann::json* j = (nlohmann::json*)to; + *j = nlohmann::json::parse(from); + }, + &j, + "Jmdablxeg"); + const auto& j_stats = j["jemalloc"]["stats"]; + for(auto it = j_stats.begin(); it != j_stats.end(); ++it) { + if(it.value().is_number_unsigned()) { + std::uint64_t val = it.value().template get(); + if(m_writer->m_config->m_metrics_include_empty_values || val != 0) { + std::string key = "falco.jemalloc." + it.key() + "_bytes"; + auto metric = libs::metrics::libsinsp_metrics::new_metric( + key.c_str(), + METRICS_V2_JEMALLOC_STATS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_MEMORY_BYTES, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + val); + if(m_writer->m_config->m_metrics_convert_memory_to_mb && + m_writer->m_output_rule_metrics_converter) { + m_writer->m_output_rule_metrics_converter + ->convert_metric_to_unit_convention(metric); + output_fields[metric.name] = metric.value.d; + } else { + output_fields[metric.name] = metric.value.u64; + } + } + } + } + } +#endif + #if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__) if(m_writer->m_libs_metrics_collector && m_writer->m_output_rule_metrics_converter) { // Libs metrics categories