From 1572c78b53585caba18552407b9ee914609e65c3 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 30 May 2024 11:31:54 +0200 Subject: [PATCH] cleanup(userspace/libsinsp): small perf improvements. Properly keep a reference on m_sinsp_stats_v2 where needed, instead of fetching it every time. Moreover, improve perf in `sinsp_utils::ts_to_string`: cache `gmt2local` result instead of fetching it every time as it is an heavy operation. Signed-off-by: Federico Di Pierro --- userspace/libsinsp/container.cpp | 18 ++- userspace/libsinsp/container.h | 1 + userspace/libsinsp/fdinfo.cpp | 36 +++-- userspace/libsinsp/fdinfo.h | 4 + userspace/libsinsp/metrics_collector.cpp | 126 +++++++++--------- userspace/libsinsp/metrics_collector.h | 1 + userspace/libsinsp/parsers.cpp | 45 ++++--- userspace/libsinsp/parsers.h | 2 + userspace/libsinsp/sinsp.cpp | 30 +---- userspace/libsinsp/sinsp.h | 13 +- userspace/libsinsp/test/sinsp_metrics.ut.cpp | 9 +- .../libsinsp/test/sinsp_with_test_input.h | 2 +- userspace/libsinsp/threadinfo.cpp | 38 +++--- userspace/libsinsp/threadinfo.h | 2 + userspace/libsinsp/utils.cpp | 8 +- 15 files changed, 175 insertions(+), 160 deletions(-) diff --git a/userspace/libsinsp/container.cpp b/userspace/libsinsp/container.cpp index bee446b3868..1ea31a1a78d 100644 --- a/userspace/libsinsp/container.cpp +++ b/userspace/libsinsp/container.cpp @@ -50,6 +50,14 @@ sinsp_container_manager::sinsp_container_manager(sinsp* inspector, bool static_c m_static_image(static_image), m_container_engine_mask(~0ULL) { + if (m_inspector != nullptr) + { + m_sinsp_stats_v2 = m_inspector->get_sinsp_stats_v2(); + } + else + { + m_sinsp_stats_v2 = nullptr; + } } bool sinsp_container_manager::remove_inactive_containers() @@ -83,22 +91,22 @@ bool sinsp_container_manager::remove_inactive_containers() }); auto containers = m_containers.lock(); - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_missing_container_images = 0; + m_sinsp_stats_v2->m_n_missing_container_images = 0; // Will include pod sanboxes, but that's ok - m_inspector->get_sinsp_stats_v2()->m_n_containers = containers->size(); + m_sinsp_stats_v2->m_n_containers = containers->size(); } for(auto it = containers->begin(); it != containers->end();) { sinsp_container_info::ptr_t container = it->second; - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2) { auto container_info = container.get(); if (!container_info || (container_info && !container_info->m_is_pod_sandbox && container_info->m_image.empty())) { // Only count missing container images and exclude sandboxes - m_inspector->get_sinsp_stats_v2()->m_n_missing_container_images++; + m_sinsp_stats_v2->m_n_missing_container_images++; } } if(containers_in_use.find(it->first) == containers_in_use.end()) diff --git a/userspace/libsinsp/container.h b/userspace/libsinsp/container.h index 2bc3fb2344f..1301acc79bd 100644 --- a/userspace/libsinsp/container.h +++ b/userspace/libsinsp/container.h @@ -242,6 +242,7 @@ class sinsp_container_manager : std::map> m_container_engine_by_type; sinsp* m_inspector; + std::shared_ptr m_sinsp_stats_v2; libsinsp::Mutex>> m_containers; std::unordered_map> m_lookups; std::list m_new_callbacks; diff --git a/userspace/libsinsp/fdinfo.cpp b/userspace/libsinsp/fdinfo.cpp index 39448d3acc9..6f069eb4dd9 100644 --- a/userspace/libsinsp/fdinfo.cpp +++ b/userspace/libsinsp/fdinfo.cpp @@ -282,6 +282,14 @@ sinsp_fdtable::sinsp_fdtable(sinsp* inspector) { m_tid = 0; m_inspector = inspector; + if (m_inspector != nullptr) + { + m_sinsp_stats_v2 = m_inspector->get_sinsp_stats_v2(); + } + else + { + m_sinsp_stats_v2 = nullptr; + } reset_cache(); } @@ -292,9 +300,9 @@ inline std::shared_ptr sinsp_fdtable::find_ref(int64_t fd) // if(m_last_accessed_fd != -1 && fd == m_last_accessed_fd) { - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2) { - m_inspector->get_sinsp_stats_v2()->m_n_cached_fd_lookups++; + m_sinsp_stats_v2->m_n_cached_fd_lookups++; } return m_last_accessed_fdinfo; } @@ -306,17 +314,17 @@ inline std::shared_ptr sinsp_fdtable::find_ref(int64_t fd) if(fdit == m_table.end()) { - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2) { - m_inspector->get_sinsp_stats_v2()->m_n_failed_fd_lookups++; + m_sinsp_stats_v2->m_n_failed_fd_lookups++; } - return NULL; + return nullptr; } else { - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_noncached_fd_lookups++; + m_sinsp_stats_v2->m_n_noncached_fd_lookups++; } m_last_accessed_fd = fd; @@ -353,9 +361,9 @@ inline std::shared_ptr sinsp_fdtable::add_ref(int64_t fd, std::uni // No entry in the table, this is the normal case // m_last_accessed_fd = -1; - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_added_fds++; + m_sinsp_stats_v2->m_n_added_fds++; } return m_table.emplace(fd, std::move(fdinfo)).first->second; @@ -424,19 +432,19 @@ bool sinsp_fdtable::erase(int64_t fd) // call that created this fd. The assertion will detect it, while in release mode we just // keep going. // - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_failed_fd_lookups++; + m_sinsp_stats_v2->m_n_failed_fd_lookups++; } return false; } else { m_table.erase(fdit); - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_noncached_fd_lookups++; - m_inspector->get_sinsp_stats_v2()->m_n_removed_fds++; + m_sinsp_stats_v2->m_n_noncached_fd_lookups++; + m_sinsp_stats_v2->m_n_removed_fds++; } return true; } diff --git a/userspace/libsinsp/fdinfo.h b/userspace/libsinsp/fdinfo.h index 7890916420a..b3c42e52e5c 100644 --- a/userspace/libsinsp/fdinfo.h +++ b/userspace/libsinsp/fdinfo.h @@ -438,6 +438,9 @@ class SINSP_PUBLIC sinsp_fdinfo : public libsinsp::state::table_entry /*@}*/ +// Forward declare sinsp_stats_v2 to avoid including metrics_collector.h here. +struct sinsp_stats_v2; + /////////////////////////////////////////////////////////////////////////////// // fd info table /////////////////////////////////////////////////////////////////////////////// @@ -547,6 +550,7 @@ class sinsp_fdtable : public libsinsp::state::table private: sinsp* m_inspector; std::unordered_map> m_table; + std::shared_ptr m_sinsp_stats_v2; // // Simple fd cache diff --git a/userspace/libsinsp/metrics_collector.cpp b/userspace/libsinsp/metrics_collector.cpp index a3fdff1b4cd..493874ba0ae 100644 --- a/userspace/libsinsp/metrics_collector.cpp +++ b/userspace/libsinsp/metrics_collector.cpp @@ -485,7 +485,11 @@ void libs_metrics_collector::snapshot() // METRICS_V2_STATE_COUNTERS related uint64_t n_fds = 0; uint64_t n_threads = 0; - std::shared_ptr sinsp_stats_v2 = m_inspector->get_sinsp_stats_v2(); + if (!m_sinsp_stats_v2) + { + // Sinsp stats disabled. + return; + } const std::function sinsp_stats_v2_collectors[] = { [SINSP_RESOURCE_UTILIZATION_CPU_PERC] = [this,&cpu_usage_perc]() { @@ -576,147 +580,146 @@ void libs_metrics_collector::snapshot() METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, n_fds); }, - [SINSP_STATS_V2_NONCACHED_FD_LOOKUPS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_NONCACHED_FD_LOOKUPS] = [this]() { return new_metric("n_noncached_fd_lookups", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_noncached_fd_lookups); + m_sinsp_stats_v2->m_n_noncached_fd_lookups); }, - [SINSP_STATS_V2_CACHED_FD_LOOKUPS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_CACHED_FD_LOOKUPS] = [this]() { return new_metric("n_cached_fd_lookups", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_cached_fd_lookups); + m_sinsp_stats_v2->m_n_cached_fd_lookups); }, - [SINSP_STATS_V2_FAILED_FD_LOOKUPS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_FAILED_FD_LOOKUPS] = [this]() { return new_metric("n_failed_fd_lookups", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_failed_fd_lookups); + m_sinsp_stats_v2->m_n_failed_fd_lookups); }, - [SINSP_STATS_V2_ADDED_FDS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_ADDED_FDS] = [this]() { return new_metric("n_added_fds", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_added_fds); + m_sinsp_stats_v2->m_n_added_fds); }, - [SINSP_STATS_V2_REMOVED_FDS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_REMOVED_FDS] = [this]() { return new_metric("n_removed_fds", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_removed_fds); + m_sinsp_stats_v2->m_n_removed_fds); }, - [SINSP_STATS_V2_STORED_EVTS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_STORED_EVTS] = [this]() { return new_metric("n_stored_evts", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_stored_evts); + m_sinsp_stats_v2->m_n_stored_evts); }, - [SINSP_STATS_V2_STORE_EVTS_DROPS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_STORE_EVTS_DROPS] = [this]() { return new_metric("n_store_evts_drops", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_store_evts_drops); + m_sinsp_stats_v2->m_n_store_evts_drops); }, - [SINSP_STATS_V2_RETRIEVED_EVTS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_RETRIEVED_EVTS] = [this]() { return new_metric("n_retrieved_evts", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_retrieved_evts); + m_sinsp_stats_v2->m_n_retrieved_evts); }, - [SINSP_STATS_V2_RETRIEVE_EVTS_DROPS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_RETRIEVE_EVTS_DROPS] = [this]() { return new_metric("n_retrieve_evts_drops", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_retrieve_evts_drops); + m_sinsp_stats_v2->m_n_retrieve_evts_drops); }, - [SINSP_STATS_V2_NONCACHED_THREAD_LOOKUPS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_NONCACHED_THREAD_LOOKUPS] = [this]() { return new_metric("n_noncached_thread_lookups", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_noncached_thread_lookups); + m_sinsp_stats_v2->m_n_noncached_thread_lookups); }, - [SINSP_STATS_V2_CACHED_THREAD_LOOKUPS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_CACHED_THREAD_LOOKUPS] = [this]() { return new_metric("n_cached_thread_lookups", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_cached_thread_lookups); + m_sinsp_stats_v2->m_n_cached_thread_lookups); }, - [SINSP_STATS_V2_FAILED_THREAD_LOOKUPS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_FAILED_THREAD_LOOKUPS] = [this]() { return new_metric("n_failed_thread_lookups", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_failed_thread_lookups); + m_sinsp_stats_v2->m_n_failed_thread_lookups); }, - [SINSP_STATS_V2_ADDED_THREADS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_ADDED_THREADS] = [this]() { return new_metric("n_added_threads", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_added_threads); + m_sinsp_stats_v2->m_n_added_threads); }, - [SINSP_STATS_V2_REMOVED_THREADS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_REMOVED_THREADS] = [this]() { return new_metric("n_removed_threads", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U64, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_removed_threads); + m_sinsp_stats_v2->m_n_removed_threads); }, - [SINSP_STATS_V2_N_DROPS_FULL_THREADTABLE] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_N_DROPS_FULL_THREADTABLE] = [this]() { return new_metric("n_drops_full_threadtable", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U32, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_MONOTONIC, - sinsp_stats_v2->m_n_drops_full_threadtable); + m_sinsp_stats_v2->m_n_drops_full_threadtable); }, - [SINSP_STATS_V2_N_MISSING_CONTAINER_IMAGES] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_N_MISSING_CONTAINER_IMAGES] = [this]() { 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, - sinsp_stats_v2->m_n_missing_container_images); + m_sinsp_stats_v2->m_n_missing_container_images); }, - [SINSP_STATS_V2_N_CONTAINERS] = [this,&sinsp_stats_v2]() { + [SINSP_STATS_V2_N_CONTAINERS] = [this]() { return new_metric("n_containers", METRICS_V2_STATE_COUNTERS, METRIC_VALUE_TYPE_U32, METRIC_VALUE_UNIT_COUNT, METRIC_VALUE_METRIC_TYPE_NON_MONOTONIC_CURRENT, - sinsp_stats_v2->m_n_containers); + m_sinsp_stats_v2->m_n_containers); }, }; 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 */ @@ -736,38 +739,29 @@ void libs_metrics_collector::snapshot() if((m_metrics_flags & METRICS_V2_STATE_COUNTERS)) { - if (!sinsp_stats_v2) + auto thread_manager = m_inspector->m_thread_manager.get(); + if (thread_manager) { - m_inspector->set_sinsp_stats_v2_enabled(); - sinsp_stats_v2 = m_inspector->get_sinsp_stats_v2(); - } - - if (sinsp_stats_v2) - { - 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) { - n_threads = thread_manager->get_thread_count(); - threadinfo_map_t* threadtable = thread_manager->get_threads(); - if (threadtable) + threadtable->loop([&n_fds] (sinsp_threadinfo& tinfo) { - threadtable->loop([&n_fds] (sinsp_threadinfo& tinfo) + sinsp_fdtable* fdtable = tinfo.get_fd_table(); + if (fdtable != nullptr) { - sinsp_fdtable* fdtable = tinfo.get_fd_table(); - if (fdtable != nullptr) - { - n_fds += fdtable->size(); - } - return true; - }); - } + 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++) - { - m_metrics.emplace_back(sinsp_stats_v2_collectors[i]()); - } + // Resource utilization of the agent itself + for (int i = SINSP_STATS_V2_N_THREADS; i < SINSP_MAX_STATS_V2; i++) + { + m_metrics.emplace_back(sinsp_stats_v2_collectors[i]()); } } @@ -799,6 +793,14 @@ libs_metrics_collector::libs_metrics_collector(sinsp* inspector, uint32_t flags) m_inspector(inspector), m_metrics_flags(flags) { + if (m_inspector != nullptr) + { + m_sinsp_stats_v2 = m_inspector->get_sinsp_stats_v2(); + } + else + { + m_sinsp_stats_v2 = nullptr; + } } } // namespace libs::metrics diff --git a/userspace/libsinsp/metrics_collector.h b/userspace/libsinsp/metrics_collector.h index 147ac0aeefd..4f80e947f68 100644 --- a/userspace/libsinsp/metrics_collector.h +++ b/userspace/libsinsp/metrics_collector.h @@ -271,6 +271,7 @@ class libs_metrics_collector private: sinsp* m_inspector; + 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; diff --git a/userspace/libsinsp/parsers.cpp b/userspace/libsinsp/parsers.cpp index d73cf451497..4e3b00ca43e 100644 --- a/userspace/libsinsp/parsers.cpp +++ b/userspace/libsinsp/parsers.cpp @@ -51,7 +51,14 @@ sinsp_parser::sinsp_parser(sinsp *inspector) : m_tmp_evt(m_inspector), m_syscall_event_source_idx(sinsp_no_event_source_idx) { - + if (m_inspector != nullptr) + { + m_sinsp_stats_v2 = m_inspector->get_sinsp_stats_v2(); + } + else + { + m_sinsp_stats_v2 = nullptr; + } } sinsp_parser::~sinsp_parser() @@ -672,9 +679,9 @@ bool sinsp_parser::reset(sinsp_evt *evt) etype == PPME_SYSCALL_VFORK_20_X || etype == PPME_SYSCALL_CLONE3_X) { - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_failed_thread_lookups--; + m_sinsp_stats_v2->m_n_failed_thread_lookups--; } } return false; @@ -823,9 +830,9 @@ void sinsp_parser::store_event(sinsp_evt *evt) // we won't be able to parse the corresponding exit event and we'll have // to drop the information it carries. // - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_store_evts_drops++; + m_sinsp_stats_v2->m_n_store_evts_drops++; } return; } @@ -859,9 +866,9 @@ void sinsp_parser::store_event(sinsp_evt *evt) memcpy(tinfo->get_last_event_data(), evt->get_scap_evt(), elen); tinfo->set_lastevent_cpuid(evt->get_cpuid()); - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_stored_evts++; + m_sinsp_stats_v2->m_n_stored_evts++; } } @@ -884,9 +891,9 @@ bool sinsp_parser::retrieve_enter_event(sinsp_evt *enter_evt, sinsp_evt *exit_ev // This happen especially at the beginning of trace files, where events // can be truncated // - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_retrieve_evts_drops++; + m_sinsp_stats_v2->m_n_retrieve_evts_drops++; } return false; } @@ -907,9 +914,9 @@ bool sinsp_parser::retrieve_enter_event(sinsp_evt *enter_evt, sinsp_evt *exit_ev && enter_evt->get_type() == PPME_SYSCALL_EXECVEAT_E) { - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_retrieved_evts++; + m_sinsp_stats_v2->m_n_retrieved_evts++; } return true; } @@ -922,15 +929,15 @@ bool sinsp_parser::retrieve_enter_event(sinsp_evt *enter_evt, sinsp_evt *exit_ev { //ASSERT(false); exit_evt->get_tinfo()->set_lastevent_data_validity(false); - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_retrieve_evts_drops++; + m_sinsp_stats_v2->m_n_retrieve_evts_drops++; } return false; } - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_retrieved_evts++; + m_sinsp_stats_v2->m_n_retrieved_evts++; } return true; @@ -3609,15 +3616,15 @@ void sinsp_parser::parse_close_exit(sinsp_evt *evt) // It is normal when a close fails that the fd lookup failed, so we revert the // increment of m_n_failed_fd_lookups (for the enter event too if there's one). // - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_failed_fd_lookups--; + m_sinsp_stats_v2->m_n_failed_fd_lookups--; } if(evt->get_tinfo() && evt->get_tinfo()->is_lastevent_data_valid()) { - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_failed_fd_lookups--; + m_sinsp_stats_v2->m_n_failed_fd_lookups--; } } } diff --git a/userspace/libsinsp/parsers.h b/userspace/libsinsp/parsers.h index 07ab25c8074..8b143a10ecb 100644 --- a/userspace/libsinsp/parsers.h +++ b/userspace/libsinsp/parsers.h @@ -145,6 +145,8 @@ class sinsp_parser // sinsp* m_inspector; + std::shared_ptr m_sinsp_stats_v2; + // // Temporary storage to avoid memory allocation // diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index 59068466a5b..51c6a211ccb 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -64,8 +64,9 @@ int32_t on_new_entry_from_proc(void* context, char* error, int64_t tid, scap_thr /////////////////////////////////////////////////////////////////////////////// std::atomic sinsp::instance_count{0}; -sinsp::sinsp(bool static_container, const std::string &static_id, const std::string &static_name, const std::string &static_image) : +sinsp::sinsp(bool static_container, const std::string &static_id, const std::string &static_name, const std::string &static_image, bool with_metrics) : m_external_event_processor(), + m_sinsp_stats_v2(with_metrics ? std::make_shared() : nullptr), m_evt(this), m_lastevent_ts(0), m_host_root(scap_get_host_root()), @@ -80,6 +81,7 @@ sinsp::sinsp(bool static_container, const std::string &static_id, const std::str // used by container_manager curl_global_init(CURL_GLOBAL_DEFAULT); #endif + m_h = NULL; m_parser = NULL; m_is_dumping = false; @@ -104,7 +106,6 @@ sinsp::sinsp(bool static_container, const std::string &static_id, const std::str m_next_flush_time_ns = 0; m_last_procrequest_tod = 0; m_get_procs_cpu_from_driver = false; - m_flush_memory_dump = false; m_next_stats_print_time_ns = 0; m_large_envs_enabled = false; m_increased_snaplen_port_range = DEFAULT_INCREASE_SNAPLEN_PORT_RANGE; @@ -1967,31 +1968,6 @@ void sinsp::set_proc_scan_log_interval_ms(uint64_t val) m_proc_scan_log_interval_ms = val; } -void sinsp::set_sinsp_stats_v2_enabled() -{ - if (m_sinsp_stats_v2 == nullptr) - { - m_sinsp_stats_v2 = std::make_unique(); - m_sinsp_stats_v2->m_n_noncached_fd_lookups = 0; - m_sinsp_stats_v2->m_n_cached_fd_lookups = 0; - m_sinsp_stats_v2->m_n_failed_fd_lookups = 0; - m_sinsp_stats_v2->m_n_added_fds = 0; - m_sinsp_stats_v2->m_n_removed_fds = 0; - m_sinsp_stats_v2->m_n_stored_evts = 0; - m_sinsp_stats_v2->m_n_store_evts_drops = 0; - m_sinsp_stats_v2->m_n_retrieved_evts = 0; - m_sinsp_stats_v2->m_n_retrieve_evts_drops = 0; - m_sinsp_stats_v2->m_n_noncached_thread_lookups = 0; - m_sinsp_stats_v2->m_n_cached_thread_lookups = 0; - m_sinsp_stats_v2->m_n_failed_thread_lookups = 0; - m_sinsp_stats_v2->m_n_added_threads = 0; - m_sinsp_stats_v2->m_n_removed_threads = 0; - m_sinsp_stats_v2->m_n_drops_full_threadtable = 0; - m_sinsp_stats_v2->m_n_missing_container_images = 0; - m_sinsp_stats_v2->m_n_containers= 0; - } -} - /////////////////////////////////////////////////////////////////////////////// // Note: this is defined here so we can inline it in sinso::next /////////////////////////////////////////////////////////////////////////////// diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index 6e53c199db2..de9c394f313 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -161,7 +161,8 @@ class SINSP_PUBLIC sinsp : public capture_stats_source sinsp(bool static_container = false, const std::string &static_id = "", const std::string &static_name = "", - const std::string &static_image = ""); + const std::string &static_image = "", + bool with_metrics = false); virtual ~sinsp() override; @@ -438,11 +439,6 @@ class SINSP_PUBLIC sinsp : public capture_stats_source */ void set_proc_scan_log_interval_ms(uint64_t val); - /*! - * \brief enabling sinsp state counters on the hot path via initializing the respective smart pointer. - */ - void set_sinsp_stats_v2_enabled(); - /*! \brief Returns a new instance of a filtercheck supporting fields for a generic event source (e.g. evt.num, evt.time, evt.pluginname...) @@ -700,7 +696,7 @@ class SINSP_PUBLIC sinsp : public capture_stats_source /*! \brief Returns true if truncated environments should be loaded from /proc */ - inline bool large_envs_enabled() + inline bool large_envs_enabled() const { return (is_live() || is_syscall_plugin()) && m_large_envs_enabled; } @@ -1158,6 +1154,7 @@ class SINSP_PUBLIC sinsp : public capture_stats_source return left == static_cast(-1) || left <= right; } + std::shared_ptr m_sinsp_stats_v2; scap_t* m_h; struct scap_platform* m_platform {}; char m_platform_lasterr[SCAP_LASTERR_SIZE]; @@ -1188,9 +1185,7 @@ class SINSP_PUBLIC sinsp : public capture_stats_source bool m_is_dumping; const scap_machine_info* m_machine_info; const scap_agent_info* m_agent_info; - std::shared_ptr m_sinsp_stats_v2; uint32_t m_num_cpus; - bool m_flush_memory_dump; bool m_large_envs_enabled; sinsp_network_interfaces m_network_interfaces {}; diff --git a/userspace/libsinsp/test/sinsp_metrics.ut.cpp b/userspace/libsinsp/test/sinsp_metrics.ut.cpp index f3bc8c08fc2..6a90cddd2f7 100644 --- a/userspace/libsinsp/test/sinsp_metrics.ut.cpp +++ b/userspace/libsinsp/test/sinsp_metrics.ut.cpp @@ -23,9 +23,6 @@ limitations under the License. TEST_F(sinsp_with_test_input, sinsp_libs_metrics_collector_prometheus) { - m_inspector.set_sinsp_stats_v2_enabled(); - // Extra call to verify that we don't fail - m_inspector.set_sinsp_stats_v2_enabled(); DEFAULT_TREE auto evt = generate_random_event(p2_t1_tid); ASSERT_EQ(get_field_as_string(evt, "proc.nthreads"), "3"); @@ -249,9 +246,6 @@ testns_falco_host_boot_timestamp_nanoseconds{raw_name="host_boot_ts"} 1708753667 TEST_F(sinsp_with_test_input, sinsp_libs_metrics_collector_output_rule) { - m_inspector.set_sinsp_stats_v2_enabled(); - // Extra call to verify that we don't fail - m_inspector.set_sinsp_stats_v2_enabled(); DEFAULT_TREE auto evt = generate_random_event(p2_t1_tid); ASSERT_EQ(get_field_as_string(evt, "proc.nthreads"), "3"); @@ -316,8 +310,9 @@ TEST_F(sinsp_with_test_input, sinsp_libs_metrics_collector_output_rule) } if (std::find(metrics_names_values_gt.begin(), metrics_names_values_gt.end(), metric.name) != metrics_names_values_gt.end()) { + printf("wow %s %ld\n", metric.name, metric.value.u64); ASSERT_GT(metric.value.u64, 0); - // Just making sure we don't get a high value due to an unitialized variables + // Just making sure we don't get a high value due to an uninitialized variables ASSERT_LT(metric.value.u64, 106721347371); success_values_cnt++; } diff --git a/userspace/libsinsp/test/sinsp_with_test_input.h b/userspace/libsinsp/test/sinsp_with_test_input.h index cac743c4366..0511a1706a9 100644 --- a/userspace/libsinsp/test/sinsp_with_test_input.h +++ b/userspace/libsinsp/test/sinsp_with_test_input.h @@ -40,7 +40,7 @@ class sinsp_with_test_input : public ::testing::Test sinsp_with_test_input(); ~sinsp_with_test_input(); - sinsp m_inspector; + sinsp m_inspector = sinsp(false, "", "", "", true); void open_inspector(sinsp_mode_t mode = SINSP_MODE_TEST); diff --git a/userspace/libsinsp/threadinfo.cpp b/userspace/libsinsp/threadinfo.cpp index 0ec2972b57b..a856098d77f 100644 --- a/userspace/libsinsp/threadinfo.cpp +++ b/userspace/libsinsp/threadinfo.cpp @@ -1388,6 +1388,14 @@ sinsp_thread_manager::sinsp_thread_manager(sinsp* inspector) m_fdtable_dyn_fields(std::make_shared()) { m_inspector = inspector; + if (m_inspector != nullptr) + { + m_sinsp_stats_v2 = m_inspector->get_sinsp_stats_v2(); + } + else + { + m_sinsp_stats_v2 = nullptr; + } clear(); } @@ -1493,15 +1501,15 @@ std::shared_ptr sinsp_thread_manager::add_thread(std::unique_p && threadinfo->m_pid != m_inspector->m_self_pid ) { - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { // rate limit messages to avoid spamming the logs - if (m_inspector->get_sinsp_stats_v2()->m_n_drops_full_threadtable % m_max_thread_table_size == 0) + if (m_sinsp_stats_v2->m_n_drops_full_threadtable % m_max_thread_table_size == 0) { libsinsp_logger()->format(sinsp_logger::SEV_INFO, "Thread table full, dropping tid %lu (pid %lu, comm \"%s\")", threadinfo->m_tid, threadinfo->m_pid, threadinfo->m_comm.c_str()); } - m_inspector->get_sinsp_stats_v2()->m_n_drops_full_threadtable++; + m_sinsp_stats_v2->m_n_drops_full_threadtable++; } return nullptr; } @@ -1526,9 +1534,9 @@ std::shared_ptr sinsp_thread_manager::add_thread(std::unique_p tinfo_shared_ptr->compute_program_hash(); m_threadtable.put(tinfo_shared_ptr); - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_added_threads++; + m_sinsp_stats_v2->m_n_added_threads++; } return tinfo_shared_ptr; @@ -1674,9 +1682,9 @@ void sinsp_thread_manager::remove_thread(int64_t tid) if(thread_to_remove == nullptr) { // Extra m_inspector nullptr check - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_failed_thread_lookups++; + m_sinsp_stats_v2->m_n_failed_thread_lookups++; } return; } @@ -1796,9 +1804,9 @@ void sinsp_thread_manager::remove_thread(int64_t tid) * the cache just to be sure. */ m_last_tid = -1; - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_removed_threads++; + m_sinsp_stats_v2->m_n_removed_threads++; } } @@ -2140,9 +2148,9 @@ threadinfo_map_t::ptr_t sinsp_thread_manager::find_thread(int64_t tid, bool look thr = m_last_tinfo.lock(); if (thr) { - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_cached_thread_lookups++; + m_sinsp_stats_v2->m_n_cached_thread_lookups++; } // This allows us to avoid performing an actual timestamp lookup // for something that may not need to be precise @@ -2158,9 +2166,9 @@ threadinfo_map_t::ptr_t sinsp_thread_manager::find_thread(int64_t tid, bool look if(thr) { - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_noncached_thread_lookups++; + m_sinsp_stats_v2->m_n_noncached_thread_lookups++; } if(!lookup_only) { @@ -2173,9 +2181,9 @@ threadinfo_map_t::ptr_t sinsp_thread_manager::find_thread(int64_t tid, bool look } else { - if (m_inspector != nullptr && m_inspector->get_sinsp_stats_v2()) + if (m_sinsp_stats_v2 != nullptr) { - m_inspector->get_sinsp_stats_v2()->m_n_failed_thread_lookups++; + m_sinsp_stats_v2->m_n_failed_thread_lookups++; } return NULL; } diff --git a/userspace/libsinsp/threadinfo.h b/userspace/libsinsp/threadinfo.h index 4da7e655add..98db9a459fe 100644 --- a/userspace/libsinsp/threadinfo.h +++ b/userspace/libsinsp/threadinfo.h @@ -1015,6 +1015,8 @@ class SINSP_PUBLIC sinsp_thread_manager: public libsinsp::state::table void free_dump_fdinfos(std::vector* fdinfos_to_free); sinsp* m_inspector; + std::shared_ptr m_sinsp_stats_v2; + /* the key is the pid of the group, and the value is a shared pointer to the thread_group_info */ std::unordered_map> m_thread_groups; threadinfo_map_t m_threadtable; diff --git a/userspace/libsinsp/utils.cpp b/userspace/libsinsp/utils.cpp index b448160c6a9..79e92322b08 100644 --- a/userspace/libsinsp/utils.cpp +++ b/userspace/libsinsp/utils.cpp @@ -968,7 +968,13 @@ void sinsp_utils::ts_to_string(uint64_t ts, std::string* res, bool date, bool ns time_t Time; uint64_t sec = ts / ONE_SECOND_IN_NS; uint64_t nsec = ts % ONE_SECOND_IN_NS; - int32_t thiszone = gmt2local(0); + static int32_t thiszone = -1; + + if (thiszone == -1) + { + thiszone = gmt2local(0); + } + int32_t s = (sec + thiszone) % 86400; int32_t bufsize = 0; char buf[256];