cleanup(libsinsp): simplify metrics flags config handling

Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
This commit is contained in:
Melissa Kilby
2023-10-23 16:22:21 +00:00
committed by poiana
parent af7192bdc3
commit 8196ee3b83
3 changed files with 54 additions and 116 deletions

View File

@@ -69,10 +69,7 @@ falco_configuration::falco_configuration():
m_metrics_interval(5000),
m_metrics_stats_rule_enabled(false),
m_metrics_output_file(""),
m_metrics_resource_utilization_enabled(true),
m_metrics_state_counters_enabled(true),
m_metrics_kernel_event_counters_enabled(true),
m_metrics_libbpf_stats_enabled(true),
m_metrics_flags((PPM_SCAP_STATS_KERNEL_COUNTERS | PPM_SCAP_STATS_LIBBPF_STATS | PPM_SCAP_STATS_RESOURCE_UTILIZATION | PPM_SCAP_STATS_STATE_COUNTERS)),
m_metrics_convert_memory_to_mb(true),
m_metrics_include_empty_values(false)
{
@@ -454,10 +451,29 @@ void falco_configuration::load_yaml(const std::string& config_name, const yaml_h
m_metrics_interval = falco::utils::parse_prometheus_interval(m_metrics_interval_str);
m_metrics_stats_rule_enabled = config.get_scalar<bool>("metrics.output_rule", false);
m_metrics_output_file = config.get_scalar<std::string>("metrics.output_file", "");
m_metrics_resource_utilization_enabled = config.get_scalar<bool>("metrics.resource_utilization_enabled", true);
m_metrics_state_counters_enabled = config.get_scalar<bool>("metrics.state_counters_enabled", true);
m_metrics_kernel_event_counters_enabled = config.get_scalar<bool>("metrics.kernel_event_counters_enabled", true);
m_metrics_libbpf_stats_enabled = config.get_scalar<bool>("metrics.libbpf_stats_enabled", true);
m_metrics_flags = 0;
if (config.get_scalar<bool>("metrics.resource_utilization_enabled", true))
{
m_metrics_flags |= PPM_SCAP_STATS_RESOURCE_UTILIZATION;
}
if (config.get_scalar<bool>("metrics.state_counters_enabled", true))
{
m_metrics_flags |= PPM_SCAP_STATS_STATE_COUNTERS;
}
if (config.get_scalar<bool>("metrics.kernel_event_counters_enabled", true))
{
m_metrics_flags |= PPM_SCAP_STATS_KERNEL_COUNTERS;
}
if (config.get_scalar<bool>("metrics.libbpf_stats_enabled", true))
{
m_metrics_flags |= PPM_SCAP_STATS_LIBBPF_STATS;
}
m_metrics_convert_memory_to_mb = config.get_scalar<bool>("metrics.convert_memory_to_mb", true);
m_metrics_include_empty_values = config.get_scalar<bool>("metrics.include_empty_values", false);

View File

@@ -158,10 +158,7 @@ public:
uint64_t m_metrics_interval;
bool m_metrics_stats_rule_enabled;
std::string m_metrics_output_file;
bool m_metrics_resource_utilization_enabled;
bool m_metrics_state_counters_enabled;
bool m_metrics_kernel_event_counters_enabled;
bool m_metrics_libbpf_stats_enabled;
uint32_t m_metrics_flags;
bool m_metrics_convert_memory_to_mb;
bool m_metrics_include_empty_values;
std::vector<plugin_config> m_plugins;

View File

@@ -15,9 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef _WIN32
#include <sys/time.h>
#endif
#include <ctime>
#include <csignal>
#include <nlohmann/json.hpp>
@@ -35,11 +33,7 @@ limitations under the License.
// overflows here. Threads calling stats_writer::handle() will just
// check that this value changed since their last observation.
static std::atomic<stats_writer::ticker_t> s_timer((stats_writer::ticker_t) 0);
#if !defined(__APPLE__) && !defined(_WIN32)
static timer_t s_timerid;
#else
static uint16_t s_timerid;
#endif
// note: Workaround for older GLIBC versions (< 2.35), where calling timer_delete()
// with an invalid timer ID not returned by timer_create() causes a segfault because of
// a bug in GLIBC (https://sourceware.org/bugzilla/show_bug.cgi?id=28257).
@@ -52,65 +46,6 @@ static void timer_handler(int signum)
s_timer.fetch_add(1, std::memory_order_relaxed);
}
#if defined(_WIN32)
bool stats_writer::init_ticker(uint32_t interval_msec, std::string &err)
{
return true;
}
#endif
#if defined(__APPLE__)
bool stats_writer::init_ticker(uint32_t interval_msec, std::string &err)
{
struct sigaction handler = {};
memset (&handler, 0, sizeof(handler));
handler.sa_handler = &timer_handler;
if (sigaction(SIGALRM, &handler, NULL) == -1)
{
err = std::string("Could not set up signal handler for periodic timer: ") + strerror(errno);
return false;
}
struct sigevent sev = {};
/* Create the timer */
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGALRM;
sev.sigev_value.sival_ptr = &s_timerid;
return true;
}
#endif
#if defined(EMSCRIPTEN)
bool stats_writer::init_ticker(uint32_t interval_msec, std::string &err)
{
struct itimerspec timer = {};
struct sigaction handler = {};
memset (&handler, 0, sizeof(handler));
handler.sa_handler = &timer_handler;
if (sigaction(SIGALRM, &handler, NULL) == -1)
{
err = std::string("Could not set up signal handler for periodic timer: ") + strerror(errno);
return false;
}
struct sigevent sev = {};
/* Create the timer */
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGALRM;
sev.sigev_value.sival_ptr = &s_timerid;
timer.it_value.tv_sec = interval_msec / 1000;
timer.it_value.tv_nsec = (interval_msec % 1000) * 1000 * 1000;
timer.it_interval = timer.it_value;
return true;
}
#endif
#if defined(__linux__)
bool stats_writer::init_ticker(uint32_t interval_msec, std::string &err)
{
struct itimerspec timer = {};
@@ -129,6 +64,7 @@ bool stats_writer::init_ticker(uint32_t interval_msec, std::string &err)
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGALRM;
sev.sigev_value.sival_ptr = &s_timerid;
#ifndef __EMSCRIPTEN__
// delete any previously set timer
if (s_timerid_exists)
{
@@ -147,19 +83,20 @@ bool stats_writer::init_ticker(uint32_t interval_msec, std::string &err)
}
s_timerid_exists = true;
#endif
timer.it_value.tv_sec = interval_msec / 1000;
timer.it_value.tv_nsec = (interval_msec % 1000) * 1000 * 1000;
timer.it_interval = timer.it_value;
#ifndef __EMSCRIPTEN__
if (timer_settime(s_timerid, 0, &timer, NULL) == -1)
{
err = std::string("Could not set up periodic timer: ") + strerror(errno);
return false;
}
#endif
return true;
}
#endif
stats_writer::ticker_t stats_writer::get_ticker()
{
@@ -214,7 +151,7 @@ stats_writer::~stats_writer()
m_file_output.close();
}
// delete timerID and reset timer
#ifdef __linux__
#ifndef __EMSCRIPTEN__
if (s_timerid_exists)
{
timer_delete(s_timerid);
@@ -295,7 +232,7 @@ void stats_writer::worker() noexcept
}
catch(const std::exception &e)
{
falco_logger::log(falco_logger::level::ERR, "stats_writer (worker): " + std::string(e.what()) + "\n");
falco_logger::log(LOG_ERR, "stats_writer (worker): " + std::string(e.what()) + "\n");
}
}
}
@@ -356,26 +293,15 @@ void stats_writer::collector::get_metrics_output_fields_additional(
double stats_snapshot_time_delta_sec, const std::string& src)
{
const scap_agent_info* agent_info = inspector->get_agent_info();
const scap_machine_info* machine_info = inspector->get_machine_info();
#if !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
uint32_t nstats = 0;
int32_t rc = 0;
uint32_t flags = 0;
if (m_writer->m_config->m_metrics_resource_utilization_enabled)
{
/* Resource utilization, CPU and memory usage etc. */
flags |= PPM_SCAP_STATS_RESOURCE_UTILIZATION;
}
if (m_writer->m_config->m_metrics_state_counters_enabled)
{
/* Counters related to sinsp state (threadtable including fds per thread as well as container cache) */
flags |= PPM_SCAP_STATS_STATE_COUNTERS;
}
uint32_t flags = m_writer->m_config->m_metrics_flags;
auto buffer = inspector->get_sinsp_stats_v2_buffer();
sinsp_stats_v2 sinsp_stats_v2 = inspector->get_sinsp_stats_v2();
auto sinsp_stats_v2 = inspector->get_sinsp_stats_v2();
sinsp_thread_manager* thread_manager = inspector->m_thread_manager;
const scap_stats_v2* sinsp_stats_v2_snapshot = libsinsp::stats::get_sinsp_stats_v2(flags, agent_info, thread_manager, sinsp_stats_v2, buffer, &nstats, &rc);
@@ -450,18 +376,17 @@ void stats_writer::collector::get_metrics_output_fields_additional(
/* Kernel side stats counters and libbpf stats if applicable. */
nstats = 0;
rc = 0;
flags = 0;
if (!(inspector->check_current_engine(BPF_ENGINE) || inspector->check_current_engine(MODERN_BPF_ENGINE)))
{
flags &= ~PPM_SCAP_STATS_LIBBPF_STATS;
}
if (!(machine_info->flags & PPM_BPF_STATS_ENABLED))
{
flags &= ~PPM_SCAP_STATS_LIBBPF_STATS;
}
if (m_writer->m_config->m_metrics_kernel_event_counters_enabled)
{
flags |= PPM_SCAP_STATS_KERNEL_COUNTERS;
}
if (m_writer->m_config->m_metrics_libbpf_stats_enabled && (inspector->check_current_engine(BPF_ENGINE) || inspector->check_current_engine(MODERN_BPF_ENGINE)))
{
flags |= PPM_SCAP_STATS_LIBBPF_STATS;
}
const scap_stats_v2* stats_v2_snapshot = inspector->get_capture_stats_v2(flags, &nstats, &rc);
if (stats_v2_snapshot && nstats > 0 && rc == 0)
const scap_stats_v2* scap_stats_v2_snapshot = inspector->get_capture_stats_v2(flags, &nstats, &rc);
if (scap_stats_v2_snapshot && nstats > 0 && rc == 0)
{
/* Cache n_evts and n_drops to derive n_drops_perc. */
uint64_t n_evts = 0;
@@ -470,21 +395,21 @@ void stats_writer::collector::get_metrics_output_fields_additional(
uint64_t n_drops_delta = 0;
for(uint32_t stat = 0; stat < nstats; stat++)
{
if (stats_v2_snapshot[stat].name[0] == '\0')
if (scap_stats_v2_snapshot[stat].name[0] == '\0')
{
break;
}
// todo: as we expand scap_stats_v2 prefix may be pushed to scap or we may need to expand
// functionality here for example if we add userspace syscall counters that should be prefixed w/ `falco.`
char metric_name[STATS_NAME_MAX] = "scap.";
strlcat(metric_name, stats_v2_snapshot[stat].name, sizeof(metric_name));
switch(stats_v2_snapshot[stat].type)
strlcat(metric_name, scap_stats_v2_snapshot[stat].name, sizeof(metric_name));
switch(scap_stats_v2_snapshot[stat].type)
{
case STATS_VALUE_TYPE_U64:
/* Always send high level n_evts related fields, even if zero. */
if (strncmp(stats_v2_snapshot[stat].name, "n_evts", 7) == 0) // exact not prefix match here
if (strncmp(scap_stats_v2_snapshot[stat].name, "n_evts", 7) == 0) // exact not prefix match here
{
n_evts = stats_v2_snapshot[stat].value.u64;
n_evts = scap_stats_v2_snapshot[stat].value.u64;
output_fields[metric_name] = n_evts;
output_fields["scap.n_evts_prev"] = m_last_n_evts;
n_evts_delta = n_evts - m_last_n_evts;
@@ -500,9 +425,9 @@ void stats_writer::collector::get_metrics_output_fields_additional(
m_last_n_evts = n_evts;
}
/* Always send high level n_drops related fields, even if zero. */
else if (strncmp(stats_v2_snapshot[stat].name, "n_drops", 8) == 0) // exact not prefix match here
else if (strncmp(scap_stats_v2_snapshot[stat].name, "n_drops", 8) == 0) // exact not prefix match here
{
n_drops = stats_v2_snapshot[stat].value.u64;
n_drops = scap_stats_v2_snapshot[stat].value.u64;
output_fields[metric_name] = n_drops;
output_fields["scap.n_drops_prev"] = m_last_n_drops;
n_drops_delta = n_drops - m_last_n_drops;
@@ -517,11 +442,11 @@ void stats_writer::collector::get_metrics_output_fields_additional(
}
m_last_n_drops = n_drops;
}
if (stats_v2_snapshot[stat].value.u64 == 0 && !m_writer->m_config->m_metrics_include_empty_values)
if (scap_stats_v2_snapshot[stat].value.u64 == 0 && !m_writer->m_config->m_metrics_include_empty_values)
{
break;
}
output_fields[metric_name] = stats_v2_snapshot[stat].value.u64;
output_fields[metric_name] = scap_stats_v2_snapshot[stat].value.u64;
break;
default:
break;