From 7417269311e5a2348d53dae6820cb7f46731e6f0 Mon Sep 17 00:00:00 2001 From: Mauro Ezequiel Moltrasio Date: Tue, 18 Jun 2024 11:28:32 +0200 Subject: [PATCH] chore(metrics): refactor metrics v2 so it uses classes This is an alternative to the original implementation. Instead of using capturing lambdas that get called back after some additional work is done, we use classes and gather data during instantiation of the object. This approach should be a lot more straight forward and it also doesn't create unneeded objects when there's no need to do so. Signed-off-by: Mauro Ezequiel Moltrasio --- userspace/libsinsp/metrics_collector.cpp | 573 ++++++++----------- userspace/libsinsp/metrics_collector.h | 220 ++++--- userspace/libsinsp/test/sinsp_metrics.ut.cpp | 64 +-- 3 files changed, 389 insertions(+), 468 deletions(-) diff --git a/userspace/libsinsp/metrics_collector.cpp b/userspace/libsinsp/metrics_collector.cpp index a9a5beff24..0c430034fe 100644 --- a/userspace/libsinsp/metrics_collector.cpp +++ b/userspace/libsinsp/metrics_collector.cpp @@ -207,7 +207,7 @@ void prometheus_metrics_converter::convert_metric_to_unit_convention(metrics_v2& } } -void libs_metrics_collector::get_rss_vsz_pss_total_memory_and_open_fds(uint32_t &rss, uint32_t &vsz, uint32_t &pss, uint64_t &host_memory_used, uint64_t &host_open_fds) +void libs_resource_utilization::get_rss_vsz_pss_total_memory_and_open_fds() { FILE* f; char filepath[512]; @@ -221,19 +221,18 @@ void libs_metrics_collector::get_rss_vsz_pss_total_memory_and_open_fds(uint32_t f = fopen("/proc/self/status", "r"); if(!f) { - ASSERT(false); return; } - while(fgets(line, sizeof(line), f) != NULL) + while(fgets(line, sizeof(line), f) != nullptr) { if(strncmp(line, "VmSize:", 7) == 0) { - sscanf(line, "VmSize: %" SCNu32, &vsz); /* memory size returned in kb */ + sscanf(line, "VmSize: %" SCNu32, &m_vsz); /* memory size returned in kb */ } else if(strncmp(line, "VmRSS:", 6) == 0) { - sscanf(line, "VmRSS: %" SCNu32, &rss); /* memory size returned in kb */ + sscanf(line, "VmRSS: %" SCNu32, &m_rss); /* memory size returned in kb */ } } fclose(f); @@ -250,7 +249,7 @@ void libs_metrics_collector::get_rss_vsz_pss_total_memory_and_open_fds(uint32_t { if(strncmp(line, "Pss:", 4) == 0) { - sscanf(line, "Pss: %" SCNu32, &pss); /* memory size returned in kb */ + sscanf(line, "Pss: %" SCNu32, &m_pss); /* memory size returned in kb */ break; } } @@ -291,7 +290,7 @@ void libs_metrics_collector::get_rss_vsz_pss_total_memory_and_open_fds(uint32_t } } fclose(f); - host_memory_used = mem_total - mem_free - mem_buff - mem_cache; + m_host_memory_used = mem_total - mem_free - mem_buff - mem_cache; /* * Get total number of allocated file descriptors (not all open files!) @@ -306,7 +305,7 @@ void libs_metrics_collector::get_rss_vsz_pss_total_memory_and_open_fds(uint32_t ASSERT(false); return; } - int matched_fds = fscanf(f, "%" SCNu64, &host_open_fds); + int matched_fds = fscanf(f, "%" SCNu64, &m_host_open_fds); fclose(f); if (matched_fds != 1) { @@ -315,7 +314,7 @@ void libs_metrics_collector::get_rss_vsz_pss_total_memory_and_open_fds(uint32_t } } -void libs_metrics_collector::get_cpu_usage_and_total_procs(double start_time, double &cpu_usage_perc, double &host_cpu_usage_perc, uint32_t &host_procs_running) +void libs_resource_utilization::get_cpu_usage_and_total_procs(double start_time) { FILE* f; char filepath[512]; @@ -374,8 +373,8 @@ void libs_metrics_collector::get_cpu_usage_and_total_procs(double start_time, do double elapsed_sec = machine_uptime_sec - start_time; if (elapsed_sec > 0) { - cpu_usage_perc = (double)100.0 * (user_sec + system_sec) / elapsed_sec; - cpu_usage_perc = std::round(cpu_usage_perc * 10.0) / 10.0; // round to 1 decimal + m_cpu_usage_perc = (double)100.0 * (user_sec + system_sec) / elapsed_sec; + m_cpu_usage_perc = std::round(m_cpu_usage_perc * 10.0) / 10.0; // round to 1 decimal } /* @@ -402,7 +401,7 @@ void libs_metrics_collector::get_cpu_usage_and_total_procs(double start_time, do } else if(strncmp(line, "procs_running ", 14) == 0) { - sscanf(line, "procs_running %" SCNu32, &host_procs_running); + sscanf(line, "procs_running %" SCNu32, &m_host_procs_running); break; } } @@ -410,12 +409,73 @@ void libs_metrics_collector::get_cpu_usage_and_total_procs(double start_time, do auto sum = user + nice + system + idle + iowait + irq + softirq; if (sum > 0) { - host_cpu_usage_perc = 100.0 - ((idle * 100.0) / sum); - host_cpu_usage_perc = std::round(host_cpu_usage_perc * 10.0) / 10.0; // round to 1 decimal + m_host_cpu_usage_perc = 100.0 - ((idle * 100.0) / sum); + m_host_cpu_usage_perc = std::round(m_host_cpu_usage_perc * 10.0) / 10.0; // round to 1 decimal } } -uint64_t libs_metrics_collector::get_container_memory_used() const +std::vector libs_resource_utilization::to_metrics() +{ + std::vector metrics; + metrics.emplace_back(new_metric("cpu_usage_perc", + METRICS_V2_RESOURCE_UTILIZATION, + METRIC_VALUE_TYPE_D, + METRIC_VALUE_UNIT_PERC, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + m_cpu_usage_perc)); + metrics.emplace_back(new_metric("memory_rss_kb", + METRICS_V2_RESOURCE_UTILIZATION, + METRIC_VALUE_TYPE_U32, + METRIC_VALUE_UNIT_MEMORY_KIBIBYTES, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + m_rss)); + metrics.emplace_back(new_metric("memory_vsz_kb", + METRICS_V2_RESOURCE_UTILIZATION, + METRIC_VALUE_TYPE_U32, + METRIC_VALUE_UNIT_MEMORY_KIBIBYTES, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + m_vsz)); + metrics.emplace_back(new_metric("memory_pss_kb", + METRICS_V2_RESOURCE_UTILIZATION, + METRIC_VALUE_TYPE_U32, + METRIC_VALUE_UNIT_MEMORY_KIBIBYTES, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + m_pss)); + metrics.emplace_back(new_metric("container_memory_used_bytes", + METRICS_V2_RESOURCE_UTILIZATION, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_MEMORY_BYTES, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + m_container_memory_used)); + metrics.emplace_back(new_metric("host_cpu_usage_perc", + METRICS_V2_RESOURCE_UTILIZATION, + METRIC_VALUE_TYPE_D, + METRIC_VALUE_UNIT_PERC, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + m_host_cpu_usage_perc)); + metrics.emplace_back(new_metric("host_memory_used_kb", + METRICS_V2_RESOURCE_UTILIZATION, + METRIC_VALUE_TYPE_U32, + METRIC_VALUE_UNIT_MEMORY_KIBIBYTES, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + m_host_memory_used)); + metrics.emplace_back(new_metric("host_procs_running", + METRICS_V2_RESOURCE_UTILIZATION, + METRIC_VALUE_TYPE_U32, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + m_host_procs_running)); + metrics.emplace_back(new_metric("host_open_fds", + METRICS_V2_RESOURCE_UTILIZATION, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + m_host_open_fds)); + + return metrics; +} + +void libs_resource_utilization::get_container_memory_used() { /* In Kubernetes `container_memory_working_set_bytes` is the memory measure the OOM killer uses * and values from `/sys/fs/cgroup/memory/memory.usage_in_bytes` are close enough. @@ -424,7 +484,6 @@ uint64_t libs_metrics_collector::get_container_memory_used() const * typically libs clients (e.g. Falco) pods contain sidekick containers that use memory as well. * This metric accounts only for the container with the security monitoring agent running. */ - uint64_t memory_used = 0; const char* filepath = getenv(SINSP_AGENT_CGROUP_MEM_PATH_ENV_VAR); if (filepath == nullptr) { @@ -436,24 +495,159 @@ uint64_t libs_metrics_collector::get_container_memory_used() const FILE* f = fopen(filepath, "r"); if(!f) { - return 0; + return; } /* memory size returned in bytes */ - int fscanf_matched = fscanf(f, "%" SCNu64, &memory_used); + fscanf(f, "%" SCNu64, &m_container_memory_used); fclose(f); - if (fscanf_matched != 1) { - return 0; + return; +} + +libs_state_counters::libs_state_counters(std::shared_ptr sinsp_stats_v2, sinsp_thread_manager* thread_manager) : m_sinsp_stats_v2(sinsp_stats_v2), m_n_fds(0), m_n_threads(0) { + if (thread_manager != nullptr) + { + m_n_threads = thread_manager->get_thread_count(); + threadinfo_map_t* threadtable = thread_manager->get_threads(); + if (threadtable != nullptr) + { + threadtable->loop([this] (sinsp_threadinfo& tinfo) { + sinsp_fdtable* fdtable = tinfo.get_fd_table(); + if (fdtable != nullptr) + { + this->m_n_fds += fdtable->size(); + } + return true; + }); + } } - return memory_used; } -// Small helper to be used by sinsp_stats_v2_collectors as -// empty lambda return value. -static metrics_v2 null_metric() +std::vector libs_state_counters::to_metrics() { - return metrics_v2{}; + std::vector metrics; + + metrics.emplace_back(new_metric("n_threads", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + m_n_threads)); + metrics.emplace_back(new_metric("n_fds", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + m_n_fds)); + + if (m_sinsp_stats_v2 == nullptr) { + return metrics; + } + + metrics.emplace_back(new_metric("n_noncached_fd_lookups", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_noncached_fd_lookups)); + metrics.emplace_back(new_metric("n_cached_fd_lookups", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_cached_fd_lookups)); + metrics.emplace_back(new_metric("n_failed_fd_lookups", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_failed_fd_lookups)); + metrics.emplace_back(new_metric("n_added_fds", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_added_fds)); + metrics.emplace_back(new_metric("n_removed_fds", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_removed_fds)); + metrics.emplace_back(new_metric("n_stored_evts", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_stored_evts)); + metrics.emplace_back(new_metric("n_store_evts_drops", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_store_evts_drops)); + metrics.emplace_back(new_metric("n_retrieved_evts", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_retrieved_evts)); + metrics.emplace_back(new_metric("n_retrieve_evts_drops", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_retrieve_evts_drops)); + metrics.emplace_back(new_metric("n_noncached_thread_lookups", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_noncached_thread_lookups)); + metrics.emplace_back(new_metric("n_cached_thread_lookups", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_cached_thread_lookups)); + metrics.emplace_back(new_metric("n_failed_thread_lookups", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_failed_thread_lookups)); + metrics.emplace_back(new_metric("n_added_threads", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_added_threads)); + metrics.emplace_back(new_metric("n_removed_threads", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U64, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_removed_threads)); + metrics.emplace_back(new_metric("n_drops_full_threadtable", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U32, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, + m_sinsp_stats_v2->m_n_drops_full_threadtable)); + metrics.emplace_back(new_metric("n_missing_container_images", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U32, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + m_sinsp_stats_v2->m_n_missing_container_images)); + metrics.emplace_back(new_metric("n_containers", + METRICS_V2_STATE_COUNTERS, + METRIC_VALUE_TYPE_U32, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + m_sinsp_stats_v2->m_n_containers)); + return metrics; } void libs_metrics_collector::snapshot() @@ -464,15 +658,15 @@ void libs_metrics_collector::snapshot() return; } - /* - * libscap metrics + /* + * libscap metrics */ if((m_metrics_flags & METRICS_V2_KERNEL_COUNTERS) || (m_metrics_flags & METRICS_V2_LIBBPF_STATS)) { uint32_t nstats = 0; int32_t rc = 0; - // libscap metrics: m_metrics_flags are pushed down from consumers' input, + // libscap metrics: m_metrics_flags are pushed down from consumers' input, // libbpf stats only collected when ENGINE_FLAG_BPF_STATS_ENABLED aka `kernel.bpf_stats_enabled = 1` const metrics_v2* metrics_v2_scap_snapshot = m_inspector->get_capture_stats_v2(m_metrics_flags, &nstats, &rc); if (metrics_v2_scap_snapshot && nstats > 0 && rc == 0) @@ -482,329 +676,22 @@ void libs_metrics_collector::snapshot() } } - /* We need to declare here all variables since they are captured by reference by the lambdas */ - // METRICS_V2_RESOURCE_UTILIZATION related - uint32_t rss{0}, vsz{0}, pss{0}, host_procs_running{0}; - uint64_t host_memory_used{0}, host_open_fds{0}; - double cpu_usage_perc{0.0}, host_cpu_usage_perc{0.0}; - uint64_t container_memory_used = get_container_memory_used(); - - // METRICS_V2_STATE_COUNTERS related - uint64_t n_fds = 0; - uint64_t n_threads = 0; - - const std::function sinsp_stats_v2_collectors[] = { - [SINSP_RESOURCE_UTILIZATION_CPU_PERC] = [this,&cpu_usage_perc]() { - return new_metric("cpu_usage_perc", - METRICS_V2_RESOURCE_UTILIZATION, - METRIC_VALUE_TYPE_D, - METRIC_VALUE_UNIT_PERC, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - cpu_usage_perc); - }, - [SINSP_RESOURCE_UTILIZATION_MEMORY_RSS] = [this,&rss]() { - return new_metric("memory_rss_kb", - METRICS_V2_RESOURCE_UTILIZATION, - METRIC_VALUE_TYPE_U32, - METRIC_VALUE_UNIT_MEMORY_KIBIBYTES, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - rss); - }, - [SINSP_RESOURCE_UTILIZATION_MEMORY_VSZ] = [this,&vsz]() { - return new_metric("memory_vsz_kb", - METRICS_V2_RESOURCE_UTILIZATION, - METRIC_VALUE_TYPE_U32, - METRIC_VALUE_UNIT_MEMORY_KIBIBYTES, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - vsz); - }, - [SINSP_RESOURCE_UTILIZATION_MEMORY_PSS] = [this,&pss]() { - return new_metric("memory_pss_kb", - METRICS_V2_RESOURCE_UTILIZATION, - METRIC_VALUE_TYPE_U32, - METRIC_VALUE_UNIT_MEMORY_KIBIBYTES, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - pss); - }, - [SINSP_RESOURCE_UTILIZATION_CONTAINER_MEMORY] = [this,&container_memory_used]() { - return new_metric("container_memory_used_bytes", - METRICS_V2_RESOURCE_UTILIZATION, - METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_MEMORY_BYTES, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - container_memory_used); - }, - [SINSP_RESOURCE_UTILIZATION_HOST_CPU_PERC] = [this,&host_cpu_usage_perc]() { - return new_metric("host_cpu_usage_perc", - METRICS_V2_RESOURCE_UTILIZATION, - METRIC_VALUE_TYPE_D, - METRIC_VALUE_UNIT_PERC, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - host_cpu_usage_perc); - }, - [SINSP_RESOURCE_UTILIZATION_HOST_MEMORY] = [this,&host_memory_used]() { - return new_metric("host_memory_used_kb", - METRICS_V2_RESOURCE_UTILIZATION, - METRIC_VALUE_TYPE_U32, - METRIC_VALUE_UNIT_MEMORY_KIBIBYTES, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - host_memory_used); - }, - [SINSP_RESOURCE_UTILIZATION_HOST_PROCS] = [this,&host_procs_running]() { - return new_metric("host_procs_running", - METRICS_V2_RESOURCE_UTILIZATION, - METRIC_VALUE_TYPE_U32, - METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - host_procs_running); - }, - [SINSP_RESOURCE_UTILIZATION_HOST_FDS] = [this,&host_open_fds]() { - return new_metric("host_open_fds", - METRICS_V2_RESOURCE_UTILIZATION, - METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - host_open_fds); - }, - [SINSP_STATS_V2_N_THREADS] = [this,&n_threads]() { - return new_metric("n_threads", - METRICS_V2_STATE_COUNTERS, - METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - n_threads); - }, - [SINSP_STATS_V2_N_FDS] = [this,&n_fds]() { - return new_metric("n_fds", - METRICS_V2_STATE_COUNTERS, - METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - n_fds); - }, - [SINSP_STATS_V2_NONCACHED_FD_LOOKUPS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_noncached_fd_lookups", METRICS_V2_STATE_COUNTERS, - METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_noncached_fd_lookups); - } - return null_metric(); - }, - [SINSP_STATS_V2_CACHED_FD_LOOKUPS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_cached_fd_lookups", METRICS_V2_STATE_COUNTERS, - METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_cached_fd_lookups); - } - return null_metric(); - }, - [SINSP_STATS_V2_FAILED_FD_LOOKUPS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_failed_fd_lookups", METRICS_V2_STATE_COUNTERS, - METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_failed_fd_lookups); - } - return null_metric(); - }, - [SINSP_STATS_V2_ADDED_FDS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_added_fds", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_added_fds); - } - return null_metric(); - }, - [SINSP_STATS_V2_REMOVED_FDS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_removed_fds", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_removed_fds); - } - return null_metric(); - }, - [SINSP_STATS_V2_STORED_EVTS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_stored_evts", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_stored_evts); - } - return null_metric(); - }, - [SINSP_STATS_V2_STORE_EVTS_DROPS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_store_evts_drops", METRICS_V2_STATE_COUNTERS, - METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_store_evts_drops); - } - return null_metric(); - }, - [SINSP_STATS_V2_RETRIEVED_EVTS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_retrieved_evts", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_retrieved_evts); - } - return null_metric(); - }, - [SINSP_STATS_V2_RETRIEVE_EVTS_DROPS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_retrieve_evts_drops", METRICS_V2_STATE_COUNTERS, - METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_retrieve_evts_drops); - } - return null_metric(); - }, - [SINSP_STATS_V2_NONCACHED_THREAD_LOOKUPS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_noncached_thread_lookups", METRICS_V2_STATE_COUNTERS, - METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_noncached_thread_lookups); - } - return null_metric(); - }, - [SINSP_STATS_V2_CACHED_THREAD_LOOKUPS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_cached_thread_lookups", METRICS_V2_STATE_COUNTERS, - METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_cached_thread_lookups); - } - return null_metric(); - }, - [SINSP_STATS_V2_FAILED_THREAD_LOOKUPS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_failed_thread_lookups", METRICS_V2_STATE_COUNTERS, - METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_failed_thread_lookups); - } - return null_metric(); - }, - [SINSP_STATS_V2_ADDED_THREADS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_added_threads", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_added_threads); - } - return null_metric(); - }, - [SINSP_STATS_V2_REMOVED_THREADS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_removed_threads", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_removed_threads); - } - return null_metric(); - }, - [SINSP_STATS_V2_N_DROPS_FULL_THREADTABLE] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_drops_full_threadtable", METRICS_V2_STATE_COUNTERS, - METRIC_VALUE_TYPE_U32, METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, - m_sinsp_stats_v2->m_n_drops_full_threadtable); - } - return null_metric(); - }, - [SINSP_STATS_V2_N_MISSING_CONTAINER_IMAGES] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_missing_container_images", METRICS_V2_STATE_COUNTERS, - METRIC_VALUE_TYPE_U32, METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - m_sinsp_stats_v2->m_n_missing_container_images); - } - return null_metric(); - }, - [SINSP_STATS_V2_N_CONTAINERS] = [this]() { - if (m_sinsp_stats_v2) - { - return new_metric("n_containers", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U32, - METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - m_sinsp_stats_v2->m_n_containers); - } - return null_metric(); - }, - }; - static_assert(sizeof(sinsp_stats_v2_collectors) / sizeof(sinsp_stats_v2_collectors[0]) == SINSP_MAX_STATS_V2, "sinsp_stats_v2_resource_utilization_names array size does not match expected size"); - - /* - * libsinsp metrics + /* + * libsinsp metrics */ if((m_metrics_flags & METRICS_V2_RESOURCE_UTILIZATION)) { const scap_agent_info* agent_info = m_inspector->get_agent_info(); - get_cpu_usage_and_total_procs(agent_info->start_time, cpu_usage_perc, host_cpu_usage_perc, host_procs_running); - get_rss_vsz_pss_total_memory_and_open_fds(rss, vsz, pss, host_memory_used, host_open_fds); - - // Resource utilization of the agent itself - for (int i = SINSP_RESOURCE_UTILIZATION_CPU_PERC; i <= SINSP_RESOURCE_UTILIZATION_HOST_FDS; i++) - { - auto metric = sinsp_stats_v2_collectors[i](); - if (metric.name[0] != '\0') - { - // Check that metric is actually initialized, - // ie: it is not referencing m_sinsp_stats_v2 - // when sinsp stats are not enabled. - m_metrics.emplace_back(metric); - } - } + libs_resource_utilization resource_utilization(agent_info->start_time); + std::vector ru_metrics = resource_utilization.to_metrics(); + m_metrics.insert(m_metrics.end(), ru_metrics.begin(), ru_metrics.end()); } if((m_metrics_flags & METRICS_V2_STATE_COUNTERS)) { - auto thread_manager = m_inspector->m_thread_manager.get(); - if (thread_manager) - { - n_threads = thread_manager->get_thread_count(); - threadinfo_map_t* threadtable = thread_manager->get_threads(); - if (threadtable) - { - threadtable->loop([&n_fds] (sinsp_threadinfo& tinfo) - { - sinsp_fdtable* fdtable = tinfo.get_fd_table(); - if (fdtable != nullptr) - { - n_fds += fdtable->size(); - } - return true; - }); - } - } - - // Resource utilization of the agent itself - for (int i = SINSP_STATS_V2_N_THREADS; i < SINSP_MAX_STATS_V2; i++) - { - auto metric = sinsp_stats_v2_collectors[i](); - if (metric.name[0] != '\0') - { - // Check that metric is actually initialized, - // ie: it is not referencing m_sinsp_stats_v2 - // when sinsp stats are not enabled. - m_metrics.emplace_back(metric); - } - } + libs_state_counters state_counters(m_sinsp_stats_v2, m_inspector->m_thread_manager.get()); + std::vector sc_metrics = state_counters.to_metrics(); + m_metrics.insert(m_metrics.end(), sc_metrics.begin(), sc_metrics.end()); } /* diff --git a/userspace/libsinsp/metrics_collector.h b/userspace/libsinsp/metrics_collector.h index 4f80e947f6..0d9e38b65c 100644 --- a/userspace/libsinsp/metrics_collector.h +++ b/userspace/libsinsp/metrics_collector.h @@ -23,6 +23,8 @@ limitations under the License. #include #include #include +#include +#include #include struct sinsp_stats_v2 @@ -46,39 +48,6 @@ struct sinsp_stats_v2 uint32_t m_n_containers; }; -enum sinsp_stats_v2_resource_utilization -{ - SINSP_RESOURCE_UTILIZATION_CPU_PERC = 0, ///< Current CPU usage, `ps` util like calculation for the calling process (/proc/self), unit: percentage of one CPU. - SINSP_RESOURCE_UTILIZATION_MEMORY_RSS, ///< Current RSS (Resident Set Size), calculated based on /proc/self/status info, unit: kb. - SINSP_RESOURCE_UTILIZATION_MEMORY_VSZ, ///< Current VSZ (Virtual Memory Size), calculated based on /proc/self/status info, unit: kb. - SINSP_RESOURCE_UTILIZATION_MEMORY_PSS, ///< Current PSS (Proportional Set Size), calculated based on /proc/self/smaps_rollup info, unit: kb. - SINSP_RESOURCE_UTILIZATION_CONTAINER_MEMORY, ///< Cgroup current memory used, default Kubernetes /sys/fs/cgroup/memory/memory.usage_in_bytes, unit: bytes. - SINSP_RESOURCE_UTILIZATION_HOST_CPU_PERC, ///< Current total host CPU usage (all CPUs), calculated based on ${HOST_ROOT}/proc/stat info, unit: percentage. - SINSP_RESOURCE_UTILIZATION_HOST_MEMORY, ///< Current total memory used out of available host memory, calculated based on ${HOST_ROOT}/proc/meminfo info, unit: kb. - SINSP_RESOURCE_UTILIZATION_HOST_PROCS, ///< Number of processes currently running on CPUs on the host, retrieved from ${HOST_ROOT}/proc/stat line `procs_running`, unit: count. - SINSP_RESOURCE_UTILIZATION_HOST_FDS, ///< Number of allocated fds on the host, retrieved from ${HOST_ROOT}/proc/sys/fs/file-nr, unit: count. - SINSP_STATS_V2_N_THREADS, ///< Total number of threads currently stored in the sinsp state thread table, unit: count. - SINSP_STATS_V2_N_FDS, ///< Total number of fds currently stored across all threadtables associated with each active thread in the sinsp state thread table, unit: count. - SINSP_STATS_V2_NONCACHED_FD_LOOKUPS, ///< fdtable state related counters, unit: count. - SINSP_STATS_V2_CACHED_FD_LOOKUPS, ///< fdtable state related counters, unit: count. - SINSP_STATS_V2_FAILED_FD_LOOKUPS, ///< fdtable state related counters, unit: count. - SINSP_STATS_V2_ADDED_FDS, ///< fdtable state related counters, unit: count. - SINSP_STATS_V2_REMOVED_FDS, ///< fdtable state related counters, unit: count. - SINSP_STATS_V2_STORED_EVTS, ///< evt parsing related counters, unit: count. - SINSP_STATS_V2_STORE_EVTS_DROPS, ///< evt parsing related counters, unit: count. - SINSP_STATS_V2_RETRIEVED_EVTS, ///< evt parsing related counters, unit: count. - SINSP_STATS_V2_RETRIEVE_EVTS_DROPS, ///< evt parsing related counters, unit: count. - SINSP_STATS_V2_NONCACHED_THREAD_LOOKUPS, ///< threadtable state related counters, unit: count. - SINSP_STATS_V2_CACHED_THREAD_LOOKUPS, ///< threadtable state related counters, unit: count. - SINSP_STATS_V2_FAILED_THREAD_LOOKUPS, ///< threadtable state related counters, unit: count. - SINSP_STATS_V2_ADDED_THREADS, ///< threadtable state related counters, unit: count. - SINSP_STATS_V2_REMOVED_THREADS, ///< threadtable state related counters, unit: count. - SINSP_STATS_V2_N_DROPS_FULL_THREADTABLE, ///< Number of drops due to full threadtable, unit: count. - SINSP_STATS_V2_N_MISSING_CONTAINER_IMAGES, ///< Number of cached containers (cgroups) without container info such as image, hijacked sinsp_container_manager::remove_inactive_containers() -> every flush snapshot update, unit: count. - SINSP_STATS_V2_N_CONTAINERS, ///< Number of containers (cgroups) currently cached by sinsp_container_manager, hijacked sinsp_container_manager::remove_inactive_containers() -> every flush snapshot update, unit: count. - SINSP_MAX_STATS_V2 -}; - #ifdef __linux__ namespace libs::metrics @@ -134,69 +103,69 @@ class prometheus_metrics_converter : public metrics_converter /*! \brief Method to convert a metrics_v2 metric to the text-based Prometheus exposition format. - * + * * Reference: https://github.com/prometheus/docs/blob/main/content/docs/instrumenting/exposition_formats.md * Note: The design idea is to expose Prometheus metrics by piping text-based formats to new line-delimited fields - * exposed at /metrics in Falco's existing HTTP webserver (w/ optional mTLS support), eliminating the need for implementing + * exposed at /metrics in Falco's existing HTTP webserver (w/ optional mTLS support), eliminating the need for implementing * a complete Prometheus client. - * + * * We exclusively support counter and gauge Prometheus metric types, covering metrics from kernel driver tracepoints * to linsinsp and client metrics. Introducing a registry seems excessive, especially given the dynamic nature of the final * metric string names, such as variations in tracepoints across architectures. - * Considering the simplistic use case, adding another dependency to the project does not seem justified. Furthermore, for C++ - * (compared to Go for example), there appear to be fewer formal client library projects available. Plus, we need to think + * Considering the simplistic use case, adding another dependency to the project does not seem justified. Furthermore, for C++ + * (compared to Go for example), there appear to be fewer formal client library projects available. Plus, we need to think * about stability and long-term support before adding any new dependency. - * + * * The final fully qualified Prometheus metric name partially follows https://prometheus.io/docs/practices/naming/ - * Prepend namespace and subsystem with "_" delimiter to create a fully qualified metric name according to + * Prepend namespace and subsystem with "_" delimiter to create a fully qualified metric name according to * https://pkg.go.dev/github.com/prometheus/client_golang/prometheus#Opts + append unit with "_" delimiter - * We do not strictly follow and enforce the concept of base_units, but guarantee no units are mixed per unique + * We do not strictly follow and enforce the concept of base_units, but guarantee no units are mixed per unique * `prometheus_metric_name_fully_qualified` - * + * * We are monitoring updates wrt https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md - * + * * Example: - * + * * # HELP testns_falco_n_threads_total https://falco.org/docs/metrics/ * # TYPE testns_falco_n_threads_total gauge * testns_falco_n_threads_total{raw_name="n_threads",example_key1="example1",example_key2="example2"} 12 * # HELP testns_falco_memory_rss_megabytes https://falco.org/docs/metrics/ * # TYPE testns_falco_memory_rss_megabytes gauge * testns_falco_memory_rss_megabytes{raw_name="memory_rss",example_key1="example1",example_key2="example2"} 350.000000 - * + * * This method is a work in progress. - * + * * @param metric metrics_v2 metric * @param prometheus_namespace first component of `prometheus_metric_name_fully_qualified` (optional) * @param prometheus_subsystem second component of `prometheus_metric_name_fully_qualified` (optional) * @param const_labels map of additional labels (rarely used for a metrics_v2 metric) - * @return Complete new line delimited text-based Prometheus exposition format metric string - * w/ a `prometheus_metric_name_fully_qualified` - optional components prepended to and unit appended to. + * @return Complete new line delimited text-based Prometheus exposition format metric string + * w/ a `prometheus_metric_name_fully_qualified` - optional components prepended to and unit appended to. * 3-lines including # HELP and # TYPE lines followed by the metric line, raw metric name always present as label. */ std::string convert_metric_to_text_prometheus(const metrics_v2& metric, std::string_view prometheus_namespace = "", std::string_view prometheus_subsystem = "", const std::map& const_labels = {}) const; /*! \brief Overloaded method to convert a pseudo-metric / software version like metric_name to the text-based Prometheus exposition format. - * - * Note: Instead of using const_labels, which is a rare use case according to - * https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels, + * + * Note: Instead of using const_labels, which is a rare use case according to + * https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels, * exposing an overload to support metrics similar to https://www.robustperception.io/exposing-the-software-version-to-prometheus/. - * This approach is applicable to https://falco.org/docs/metrics/, such as Falco's "Base Fields" like + * This approach is applicable to https://falco.org/docs/metrics/, such as Falco's "Base Fields" like * falco.kernel_release and falco.version. * * Example: - * + * * # HELP testns_falco_kernel_release_info https://falco.org/docs/metrics/ * # TYPE testns_falco_kernel_release_info gauge * testns_falco_kernel_release_info{raw_name="kernel_release",kernel_release="6.6.7-200.fc39.x86_64"} 1 - * + * * @param metric_name raw metric name * @param prometheus_namespace first component of `prometheus_metric_name_fully_qualified` (optional) * @param prometheus_subsystem second component of `prometheus_metric_name_fully_qualified` (optional) * @param const_labels map of additional labels (typically used in software version like metrics) - * @return Complete new line delimited text-based Prometheus exposition format metric string - * w/ a `prometheus_metric_name_fully_qualified` - optional components prepended to and unit appended to. + * @return Complete new line delimited text-based Prometheus exposition format metric string + * w/ a `prometheus_metric_name_fully_qualified` - optional components prepended to and unit appended to. * 3-lines including # HELP and # TYPE lines followed by the metric line, raw metric name always present as label. */ std::string convert_metric_to_text_prometheus(std::string_view metric_name, std::string_view prometheus_namespace = "", std::string_view prometheus_subsystem = "", const std::map& const_labels = {}) const; @@ -209,7 +178,7 @@ class prometheus_metrics_converter : public metrics_converter * https://prometheus.io/docs/practices/naming/ or https://prometheus.io/docs/practices/naming/#base-units. * We conform to the best practices except for keeping libbpf stats metrics and timestamps in nanoseconds * to avoid precision loss when converting them to seconds. - * Please note that, for example, even cAdvisor sometimes deviates from the standards, e.g., + * Please note that, for example, even cAdvisor sometimes deviates from the standards, e.g., * `container_memory_rss` instead of `container_memory_rss_bytes`. * `metric.unit` is also modified and always matches the metric name unit suffix. * @@ -228,11 +197,111 @@ class output_rule_metrics_converter : public metrics_converter * * \note metrics names w/ unit suffix shall be updated within this method. * `metric.unit` is also modified and always matches the metric name unit suffix if applicable. - * + * */ void convert_metric_to_unit_convention(metrics_v2& metric) const override; }; +class libsinsp_metrics +{ +protected: + template + static void set_metric_value(metrics_v2& metric, metrics_v2_value_type type, T val) + { + switch (type) + { + case METRIC_VALUE_TYPE_U32: + metric.value.u32 = static_cast(val); + break; + case METRIC_VALUE_TYPE_S32: + metric.value.s32 = static_cast(val); + break; + case METRIC_VALUE_TYPE_U64: + metric.value.u64 = static_cast(val); + break; + case METRIC_VALUE_TYPE_S64: + metric.value.s64 = static_cast(val); + break; + case METRIC_VALUE_TYPE_D: + metric.value.d = static_cast(val); + break; + case METRIC_VALUE_TYPE_F: + metric.value.f = static_cast(val); + break; + case METRIC_VALUE_TYPE_I: + metric.value.i = static_cast(val); + break; + default: + break; + } + } + +public: + template + static inline metrics_v2 new_metric(const char* name, uint32_t flags, metrics_v2_value_type type, metrics_v2_value_unit unit, metrics_v2_metric_type metric_type, T val) + { + metrics_v2 metric; + strlcpy(metric.name, name, METRIC_NAME_MAX); + metric.flags = flags; + metric.type = type; + metric.unit = unit; + metric.metric_type = metric_type; + set_metric_value(metric, type, val); + return metric; + } + + libsinsp_metrics() = default; + libsinsp_metrics(const libsinsp_metrics&) = default; + libsinsp_metrics(libsinsp_metrics&&) = delete; + libsinsp_metrics& operator=(const libsinsp_metrics&) = default; + libsinsp_metrics& operator=(libsinsp_metrics&&) = delete; + virtual ~libsinsp_metrics() = default; + virtual std::vector to_metrics() = 0; + +}; + +class libs_resource_utilization : libsinsp_metrics +{ +public: + libs_resource_utilization(double start_time) + { + get_cpu_usage_and_total_procs(start_time); + get_rss_vsz_pss_total_memory_and_open_fds(); + get_container_memory_used(); + } + + std::vector to_metrics() override; + +private: + void get_cpu_usage_and_total_procs(double start_time); + void get_rss_vsz_pss_total_memory_and_open_fds(); + void get_container_memory_used(); + + double m_start_time{}; + double m_cpu_usage_perc{}; + double m_host_cpu_usage_perc{}; + uint32_t m_host_procs_running{}; + uint32_t m_rss{}; + uint32_t m_vsz{}; + uint32_t m_pss{}; + uint64_t m_host_memory_used{}; + uint64_t m_host_open_fds{}; + uint64_t m_container_memory_used{}; +}; + +class libs_state_counters : libsinsp_metrics +{ +public: + libs_state_counters(std::shared_ptr sinsp_stats_v2, sinsp_thread_manager* thread_manager); + + std::vector to_metrics() override; + +private: + std::shared_ptr m_sinsp_stats_v2; + uint64_t m_n_fds; + uint64_t m_n_threads; +}; + class libs_metrics_collector { public: @@ -274,41 +343,6 @@ class libs_metrics_collector std::shared_ptr m_sinsp_stats_v2; uint32_t m_metrics_flags = METRICS_V2_KERNEL_COUNTERS | METRICS_V2_LIBBPF_STATS | METRICS_V2_RESOURCE_UTILIZATION | METRICS_V2_STATE_COUNTERS | METRICS_V2_PLUGINS; std::vector m_metrics; - - void get_rss_vsz_pss_total_memory_and_open_fds(uint32_t &rss, uint32_t &vsz, uint32_t &pss, uint64_t &host_memory_used, uint64_t &host_open_fds); - void get_cpu_usage_and_total_procs(double start_time, double &cpu_usage_perc, double &host_cpu_usage_perc, uint32_t &host_procs_running); - uint64_t get_container_memory_used() const; - - template - static void set_metric_value(metrics_v2& metric, metrics_v2_value_type type, T val) - { - switch (type) - { - case METRIC_VALUE_TYPE_U32: - metric.value.u32 = static_cast(val); - break; - case METRIC_VALUE_TYPE_S32: - metric.value.s32 = static_cast(val); - break; - case METRIC_VALUE_TYPE_U64: - metric.value.u64 = static_cast(val); - break; - case METRIC_VALUE_TYPE_S64: - metric.value.s64 = static_cast(val); - break; - case METRIC_VALUE_TYPE_D: - metric.value.d = static_cast(val); - break; - case METRIC_VALUE_TYPE_F: - metric.value.f = static_cast(val); - break; - case METRIC_VALUE_TYPE_I: - metric.value.i = static_cast(val); - break; - default: - break; - } - } }; } // namespace libs::metrics diff --git a/userspace/libsinsp/test/sinsp_metrics.ut.cpp b/userspace/libsinsp/test/sinsp_metrics.ut.cpp index 23f60d8db9..cf5b38a68a 100644 --- a/userspace/libsinsp/test/sinsp_metrics.ut.cpp +++ b/userspace/libsinsp/test/sinsp_metrics.ut.cpp @@ -112,7 +112,7 @@ testns_falco_memory_rss_bytes{raw_name="memory_rss_bytes"} )"; } } - ASSERT_EQ(metrics_names_all_str_post_unit_conversion_pre_prometheus_text_conversion, + ASSERT_EQ(metrics_names_all_str_post_unit_conversion_pre_prometheus_text_conversion, "cpu_usage_ratio memory_rss_bytes memory_vsz_bytes memory_pss_bytes container_memory_used_bytes host_cpu_usage_ratio host_memory_used_bytes host_procs_running host_open_fds n_threads n_fds n_noncached_fd_lookups n_cached_fd_lookups n_failed_fd_lookups n_added_fds n_removed_fds n_stored_evts n_store_evts_drops n_retrieved_evts n_retrieve_evts_drops n_noncached_thread_lookups n_cached_thread_lookups n_failed_thread_lookups n_added_threads n_removed_threads n_drops_full_threadtable n_missing_container_images n_containers"); // Test global wrapper base metrics (pseudo metrics) @@ -126,63 +126,63 @@ testns_falco_kernel_release_info{raw_name="kernel_release",kernel_release="6.6.7 // Another round of fake metric tests since we do not fetch real scap metrics, for example. std::vector fake_metrics_snapshot; - fake_metrics_snapshot.emplace_back(libs_metrics_collector.new_metric("sys_enter.run_cnt", - METRICS_V2_LIBBPF_STATS, + fake_metrics_snapshot.emplace_back(libs::metrics::libsinsp_metrics::new_metric("sys_enter.run_cnt", + METRICS_V2_LIBBPF_STATS, METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, 76435525241UL)); - fake_metrics_snapshot.emplace_back(libs_metrics_collector.new_metric("sys_enter.run_time_ns", - METRICS_V2_LIBBPF_STATS, + fake_metrics_snapshot.emplace_back(libs::metrics::libsinsp_metrics::new_metric("sys_enter.run_time_ns", + METRICS_V2_LIBBPF_STATS, METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_TIME_NS_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, + METRIC_VALUE_UNIT_TIME_NS_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, 16269369826392UL)); - fake_metrics_snapshot.emplace_back(libs_metrics_collector.new_metric("sys_enter.avg_time_ns", - METRICS_V2_LIBBPF_STATS, + fake_metrics_snapshot.emplace_back(libs::metrics::libsinsp_metrics::new_metric("sys_enter.avg_time_ns", + METRICS_V2_LIBBPF_STATS, METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_TIME_NS, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + METRIC_VALUE_UNIT_TIME_NS, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, 203UL)); - fake_metrics_snapshot.emplace_back(libs_metrics_collector.new_metric("n_drops", - METRICS_V2_KERNEL_COUNTERS, + fake_metrics_snapshot.emplace_back(libs::metrics::libsinsp_metrics::new_metric("n_drops", + METRICS_V2_KERNEL_COUNTERS, METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, 674200UL)); - fake_metrics_snapshot.emplace_back(libs_metrics_collector.new_metric("n_drops_buffer_total", - METRICS_V2_KERNEL_COUNTERS, + fake_metrics_snapshot.emplace_back(libs::metrics::libsinsp_metrics::new_metric("n_drops_buffer_total", + METRICS_V2_KERNEL_COUNTERS, METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, + METRIC_VALUE_UNIT_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, 5000UL)); // Simulate some derived metrics; critical for example for Falco consumer use cases - fake_metrics_snapshot.emplace_back(libs_metrics_collector.new_metric("duration_sec", + fake_metrics_snapshot.emplace_back(libs::metrics::libsinsp_metrics::new_metric("duration_sec", METRICS_V2_MISC, METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_TIME_S_COUNT, - METRIC_VALUE_METRIC_TYPE_MONOTONIC, + METRIC_VALUE_UNIT_TIME_S_COUNT, + METRIC_VALUE_METRIC_TYPE_MONOTONIC, 144UL)); - fake_metrics_snapshot.emplace_back(libs_metrics_collector.new_metric("evt_rate_sec", + fake_metrics_snapshot.emplace_back(libs::metrics::libsinsp_metrics::new_metric("evt_rate_sec", METRICS_V2_MISC, METRIC_VALUE_TYPE_D, - METRIC_VALUE_UNIT_TIME_S, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + METRIC_VALUE_UNIT_TIME_S, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, 126065.4)); // Timestamps while they always go up should still be regarded as gauge from a Prometheus perspective // https://www.robustperception.io/are-increasing-timestamps-counters-or-gauges/ - fake_metrics_snapshot.emplace_back(libs_metrics_collector.new_metric("host_boot_ts", - METRICS_V2_MISC, + fake_metrics_snapshot.emplace_back(libs::metrics::libsinsp_metrics::new_metric("host_boot_ts", + METRICS_V2_MISC, METRIC_VALUE_TYPE_U64, - METRIC_VALUE_UNIT_TIME_TIMESTAMP_NS, - METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, + METRIC_VALUE_UNIT_TIME_TIMESTAMP_NS, + METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, 1708753667000000000UL)); for (auto& metric: fake_metrics_snapshot) @@ -270,7 +270,7 @@ TEST_F(sinsp_with_test_input, sinsp_libs_metrics_collector_output_rule) for(const auto& metric_name : minimal_metrics_names) { size_t i = 0; - for (const auto& metric: metrics_snapshot) + for (const auto& metric: metrics_snapshot) { if(metric_name == metric.name) {