Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update(userspace/falco): add libsinsp state metrics option #2883

Merged
merged 5 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmake/modules/driver.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ else()
# In case you want to test against another driver version (or branch, or commit) just pass the variable -
# ie., `cmake -DDRIVER_VERSION=dev ..`
if(NOT DRIVER_VERSION)
set(DRIVER_VERSION "7cbc03a535ead9d530f7b77ffd68766d5e22da74")
set(DRIVER_CHECKSUM "SHA256=94d110ad1738cce2635fd15d41701bea5e061fd9a5a4be3f2ee8ec7a28fe50cc")
set(DRIVER_VERSION "c2fd3086ff1bd0fce20a24a6da9f03c47332d68a")
set(DRIVER_CHECKSUM "SHA256=b25de5174b9f7199ecaedeb84bdbb9b075871478547de4e724e625bc43322aa9")
endif()

# cd /path/to/build && cmake /path/to/source
Expand Down
4 changes: 2 additions & 2 deletions cmake/modules/falcosecurity-libs.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ else()
# In case you want to test against another falcosecurity/libs version (or branch, or commit) just pass the variable -
# ie., `cmake -DFALCOSECURITY_LIBS_VERSION=dev ..`
if(NOT FALCOSECURITY_LIBS_VERSION)
set(FALCOSECURITY_LIBS_VERSION "7cbc03a535ead9d530f7b77ffd68766d5e22da74")
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=94d110ad1738cce2635fd15d41701bea5e061fd9a5a4be3f2ee8ec7a28fe50cc")
set(FALCOSECURITY_LIBS_VERSION "c2fd3086ff1bd0fce20a24a6da9f03c47332d68a")
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=b25de5174b9f7199ecaedeb84bdbb9b075871478547de4e724e625bc43322aa9")
endif()

# cd /path/to/build && cmake /path/to/source
Expand Down
24 changes: 17 additions & 7 deletions falco.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -725,13 +725,22 @@ syscall_event_drops:
# number of CPUs to determine overall usage. Memory metrics are provided in raw
# units (`kb` for `RSS`, `PSS` and `VSZ` or `bytes` for `container_memory_used`)
# and can be uniformly converted to megabytes (MB) using the
# `convert_memory_to_mb` functionality. In environments such as Kubernetes, it
# is crucial to track Falco's container memory usage. To customize the path of
# the memory metric file, you can create an environment variable named
# `FALCO_CGROUP_MEM_PATH` and set it to the desired file path. By default, Falco
# uses the file `/sys/fs/cgroup/memory/memory.usage_in_bytes` to monitor
# container memory usage, which aligns with Kubernetes'
# `container_memory_working_set_bytes` metric.
# `convert_memory_to_mb` functionality. In environments such as Kubernetes when
# deployed as daemonset, it is crucial to track Falco's container memory usage.
# To customize the path of the memory metric file, you can create an environment
# variable named `FALCO_CGROUP_MEM_PATH` and set it to the desired file path. By
# default, Falco uses the file `/sys/fs/cgroup/memory/memory.usage_in_bytes` to
# monitor container memory usage, which aligns with Kubernetes'
# `container_memory_working_set_bytes` metric. Finally, we emit the overall host
# CPU and memory usages, along with the total number of processes and open file
# descriptors (fds) on the host, obtained from the proc file system unrelated to
# Falco's monitoring. These metrics help assess Falco's usage in relation to the
# server's workload intensity.
#
# `state_counters_enabled`: Emit counters related to Falco's state engine, including
# added, removed threads or file descriptors (fds), and failed lookup, store, or
# retrieve actions in relation to Falco's underlying process cache table (threadtable).
# We also log the number of currently cached containers if applicable.
#
# `kernel_event_counters_enabled`: Emit kernel side event and drop counters, as
# an alternative to `syscall_event_drops`, but with some differences. These
Expand Down Expand Up @@ -764,6 +773,7 @@ metrics:
output_rule: true
# output_file: /tmp/falco_stats.jsonl
resource_utilization_enabled: true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about having a list of metrics instead of many boolean values? maybe something like

enabled_metrics: ["kernel_countes", ... ]

if we like the idea we could deprecate the old flags and introduce this new config. If we go in this way probably I would merge libbpf_stats_enabled into kernel_event_counters_enabled, in the end, to have the libbpf_stats_enabled you need to enable the stats sudo sysctl -w kernel.bpf_stats_enabled=1, so we already have a knob. Moreover, it is something only related to bpf so maybe it is better to be more agnostic and hide it inside kernel_countes WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can discuss a enabled_metrics list. Given we are deprecating more urgent old settings I am not be sure if this is worth it in the near-term. Since metrics is now "Stable" we would need to follow a deprecation cycle. I would propose to open a discussion issue, tag all libs and falco maintainers and if the majority votes in favor of enabled_metrics: ["kernel_countes", ... ] start the proper deprecation cycle. WDYT?

Kernel settings can be shared amongst teams deploying their tools. Therefore, it can be fair to assume that maybe another team enabled libbpf stats, but you still have a use case of not wanting to collect libbpf stats for Falco. I would prefer giving the end user full control and be very selective with the metrics especially given it's quite a lot of metrics and perhaps you only need some of them sometimes. With that I would also not merge libbf stats and the kernel event counters. All these reasons were the motivation to have these flags that are all teh way pushed down to libs in the first place.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah we can discuss it without blocking the PR, i will tag all here so even if we merge this we can discuss with the clear scope of this PR @falcosecurity/falco-maintainers

Re libbpf_stats_enabled: my idea was to use the sysctl option kernel.bpf_stats_enabled as a knob, so if a team wants to enable libbpf stats together with the kernel stats it has just to type a sudo sysctl -w kernel.bpf_stats_enabled=1 on the node, while if they want to disable them they could use sudo sysctl -w kernel.bpf_stats_enabled=0. The libsinsp code at every interval could check kernel.bpf_stats_enabled (or maybe just at init time, it depends on what we want) and add the libbpf metrics if needed. BTW it was just an idea, no strong opinion here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree about using sysctl value kernel.bpf_stats_enabled to chose whether to enable/disable our kernel stats without further configuration by the user, it's a great idea actually! We could use its value as a default value for the configuration key and ship it commented? (same for kernel_event_counters_enabled eventually)

We can discuss a enabled_metrics list

I don't have a strong opinion on this one; i think from an UX perspective it is better to already have all the keys and just set "true"/"false" whether i need them, than to add strings inside a set.

state_counters_enabled: true
kernel_event_counters_enabled: true
libbpf_stats_enabled: true
convert_memory_to_mb: true
Expand Down
4 changes: 2 additions & 2 deletions userspace/engine/falco_engine_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ limitations under the License.

// The version of this Falco engine
#define FALCO_ENGINE_VERSION_MAJOR 0
#define FALCO_ENGINE_VERSION_MINOR 27
#define FALCO_ENGINE_VERSION_MINOR 28
#define FALCO_ENGINE_VERSION_PATCH 0

#define FALCO_ENGINE_VERSION \
Expand All @@ -34,4 +34,4 @@ limitations under the License.
// It represents the fields supported by this version of Falco,
// the event types, and the underlying driverevent schema. It's used to
// detetect changes in engine version in our CI jobs.
#define FALCO_ENGINE_CHECKSUM "dbc34e88ab420320994d85f155dee6baff2dd018aacc00e249f897edc8b1e0f4"
#define FALCO_ENGINE_CHECKSUM "5d488b68856d70300ae37453295383821822d8423af170eb28e1bef52042f0b3"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jasondellaluce the instructions above to calculate the checksum seem outdated. I tried it locally before pushing and it was wrong, had to re-push the correct value based on CI error logs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the right number by running the command in this branch 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh I will double check later, thanks for checking! Maybe I messed up somewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I seem to have some stale Falco version in my local branch somehow.

FALCO="build/userspace/falco/falco -c ./falco.yaml";
echo $($FALCO --version | grep 'Engine:' | awk '{print $2}') $(echo $($FALCO --version | grep 'Schema version:' | awk '{print $3}') $($FALCO --list --markdown | grep '^`' | sort) $($FALCO --list-events | sort) | sha256sum);
Tue Nov 28 05:29:32 2023: Falco version: 0.33.0-1218+6b05bcf (x86_64)
Tue Nov 28 05:29:32 2023: Falco initialized with configuration file: ./falco.yaml
Tue Nov 28 05:29:32 2023: Falco version: 0.33.0-1218+6b05bcf (x86_64)
Tue Nov 28 05:29:32 2023: Falco initialized with configuration file: ./falco.yaml
Tue Nov 28 05:29:32 2023: Falco version: 0.33.0-1218+6b05bcf (x86_64)
Tue Nov 28 05:29:32 2023: Falco initialized with configuration file: ./falco.yaml
Tue Nov 28 05:29:32 2023: Falco version: 0.33.0-1218+6b05bcf (x86_64)
Tue Nov 28 05:29:32 2023: Falco initialized with configuration file: ./falco.yaml
0.28.0 1b160cdb7e22279bcc43cd381c66750e3db9ab4431c7fb74b93070d4cb37c7d8 -
cmake \
-DUSE_BUNDLED_DEPS=ON \
-DBUILD_LIBSCAP_GVISOR=ON \
-DBUILD_BPF=ON \
-DBUILD_DRIVER=ON \
-DBUILD_FALCO_MODERN_BPF=OFF \
-DCREATE_TEST_TARGETS=ON \
-DBUILD_FALCO_UNIT_TESTS=ON ..

Not sure what's up here, but it's also not that important as I don't really have any issues on my fedora box ...

5 changes: 5 additions & 0 deletions userspace/falco/app/actions/helpers_inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ falco::app::run_result falco::app::actions::open_live_inspector(
{
try
{
if((s.config->m_metrics_flags & PPM_SCAP_STATS_STATE_COUNTERS))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we enable these stats with a source plugin should we expect all empty values?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think metrics and plugins is currently a bit broken because of some recent libs refactors (linux platform which does not apply for plugins hence we don't fetch some constants that are needed to for example calculate the CPU utilization). Since the kernel drivers are Falco's primary use case, we can work on the plugin cases later. End goal: When running metrics with plugins you should still be able to fetch all libsinsp metrics that are applicable (depending on the nature of the plugin).

{
inspector->set_sinsp_stats_v2_enabled();
}

if (source != falco_common::syscall_source) /* Plugin engine */
{
for (const auto& p: inspector->get_plugin_manager()->plugins())
Expand Down
30 changes: 24 additions & 6 deletions userspace/falco/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,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_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)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change seems to go in the same direction proposed above, one unique config 'to rule them all'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As commented above we can discuss.

m_metrics_convert_memory_to_mb(true),
m_metrics_include_empty_values(false)
{
Expand Down Expand Up @@ -380,9 +378,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_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);

Expand Down
4 changes: 1 addition & 3 deletions userspace/falco/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,7 @@ class falco_configuration
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_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;

Expand Down
138 changes: 77 additions & 61 deletions userspace/falco/stats_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ void stats_writer::collector::get_metrics_output_fields_wrapper(
if (m_last_num_evts != 0 && stats_snapshot_time_delta_sec > 0)
{
/* Successfully processed userspace event rate. */
output_fields["falco.evts_rate_sec"] = (double)((num_evts - m_last_num_evts) / (double)stats_snapshot_time_delta_sec);
output_fields["falco.evts_rate_sec"] = std::round((double)((num_evts - m_last_num_evts) / (double)stats_snapshot_time_delta_sec) * 10.0) / 10.0; // round to 1 decimal
}
output_fields["falco.num_evts"] = num_evts;
output_fields["falco.num_evts_prev"] = m_last_num_evts;
Expand All @@ -358,60 +358,74 @@ void stats_writer::collector::get_metrics_output_fields_additional(
const scap_agent_info* agent_info = inspector->get_agent_info();

#if !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
/* Resource utilization, CPU and memory usage etc. */
uint32_t nstats = 0;
int32_t rc = 0;
if (m_writer->m_config->m_metrics_resource_utilization_enabled)
uint32_t flags = m_writer->m_config->m_metrics_flags;

auto buffer = inspector->get_sinsp_stats_v2_buffer();
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);

if (sinsp_stats_v2_snapshot && rc == 0 && nstats > 0)
{
const scap_stats_v2* utilization;
auto buffer = inspector->get_sinsp_stats_v2_buffer();
utilization = libsinsp::resource_utilization::get_resource_utilization(agent_info, buffer, &nstats, &rc);
if (utilization && rc == 0 && nstats > 0)
for(uint32_t stat = 0; stat < nstats; stat++)
{
for(uint32_t stat = 0; stat < nstats; stat++)
if (sinsp_stats_v2_snapshot[stat].name[0] == '\0')
{
break;
}
char metric_name[STATS_NAME_MAX] = "falco.";
strlcat(metric_name, sinsp_stats_v2_snapshot[stat].name, sizeof(metric_name));
switch(sinsp_stats_v2_snapshot[stat].type)
{
char metric_name[STATS_NAME_MAX] = "falco.";
strlcat(metric_name, utilization[stat].name, sizeof(metric_name));
switch(utilization[stat].type)
case STATS_VALUE_TYPE_U64:
if (sinsp_stats_v2_snapshot[stat].value.u64 == 0 && !m_writer->m_config->m_metrics_include_empty_values)
{
case STATS_VALUE_TYPE_U64:
if (utilization[stat].value.u64 == 0 && !m_writer->m_config->m_metrics_include_empty_values)
{
break;
}
if (m_writer->m_config->m_metrics_convert_memory_to_mb && strncmp(utilization[stat].name, "container_memory_used", 22) == 0) // exact str match
{
output_fields[metric_name] = (uint64_t)(utilization[stat].value.u64 / (double)1024 / (double)1024);
}
else
{
output_fields[metric_name] = utilization[stat].value.u64;
}
break;
case STATS_VALUE_TYPE_U32:
if (utilization[stat].value.u32 == 0 && !m_writer->m_config->m_metrics_include_empty_values)
{
break;
}
if (m_writer->m_config->m_metrics_convert_memory_to_mb && strncmp(utilization[stat].name, "memory_", 7) == 0) // prefix match
}
if (m_writer->m_config->m_metrics_convert_memory_to_mb)
{
if (strncmp(sinsp_stats_v2_snapshot[stat].name, "container_memory_used", 22) == 0) // exact str match
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe in the future, we could add a flag inside the sinsp struct saying that the metric is relative to the "memory" In this way we could avoid the specific strncmp or maybe we could use just one base unit as suggested by Prometheus best practises https://prometheus.io/docs/practices/naming/#base-units

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes had something like that in mind for the libs refactor I will start in Dec.

For example, in libs there is still a todo comment to add a unit item to the new metrics schema struct. All these if conditions are not what we want as falco should just be a simple loop over the metrics. In addition, will look into the base units concept you shared.

{
output_fields[metric_name] = (uint32_t)(utilization[stat].value.u32 / (double)1024);
}
else
output_fields[metric_name] = (uint64_t)(sinsp_stats_v2_snapshot[stat].value.u64 / (double)1024 / (double)1024);

} else if (strncmp(sinsp_stats_v2_snapshot[stat].name, "memory_", 7) == 0) // prefix match
{
output_fields[metric_name] = utilization[stat].value.u32;
}
break;
case STATS_VALUE_TYPE_D:
if (utilization[stat].value.d == 0 && !m_writer->m_config->m_metrics_include_empty_values)
output_fields[metric_name] = (uint64_t)(sinsp_stats_v2_snapshot[stat].value.u64 / (double)1024);
} else
{
break;
output_fields[metric_name] = sinsp_stats_v2_snapshot[stat].value.u64;
}
output_fields[metric_name] = utilization[stat].value.d;
}
else
{
output_fields[metric_name] = sinsp_stats_v2_snapshot[stat].value.u64;
}
break;
case STATS_VALUE_TYPE_U32:
if (sinsp_stats_v2_snapshot[stat].value.u32 == 0 && !m_writer->m_config->m_metrics_include_empty_values)
{
break;
default:
}
if (m_writer->m_config->m_metrics_convert_memory_to_mb && strncmp(sinsp_stats_v2_snapshot[stat].name, "memory_", 7) == 0) // prefix match
{
output_fields[metric_name] = (uint32_t)(sinsp_stats_v2_snapshot[stat].value.u32 / (double)1024);
}
else
{
output_fields[metric_name] = sinsp_stats_v2_snapshot[stat].value.u32;
}
break;
case STATS_VALUE_TYPE_D:
if (sinsp_stats_v2_snapshot[stat].value.d == 0 && !m_writer->m_config->m_metrics_include_empty_values)
{
break;
}
output_fields[metric_name] = sinsp_stats_v2_snapshot[stat].value.d;
break;
default:
break;
}
}
}
Expand All @@ -424,18 +438,16 @@ void stats_writer::collector::get_metrics_output_fields_additional(
/* Kernel side stats counters and libbpf stats if applicable. */
nstats = 0;
rc = 0;
uint32_t flags = 0;

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)))
if (!(inspector->check_current_engine(BPF_ENGINE) || inspector->check_current_engine(MODERN_BPF_ENGINE)))
{
flags |= PPM_SCAP_STATS_LIBBPF_STATS;
flags &= ~PPM_SCAP_STATS_LIBBPF_STATS;
}
const scap_stats_v2* stats_v2 = inspector->get_capture_stats_v2(flags, &nstats, &rc);
if (stats_v2 && nstats > 0 && rc == 0)

// Note: ENGINE_FLAG_BPF_STATS_ENABLED check has been moved to libs, that is, when libbpf stats is not enabled
// in the kernel settings we won't collect them even if the end user enabled the libbpf stats option

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;
Expand All @@ -444,24 +456,28 @@ void stats_writer::collector::get_metrics_output_fields_additional(
uint64_t n_drops_delta = 0;
for(uint32_t stat = 0; stat < nstats; stat++)
{
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[stat].name, sizeof(metric_name));
switch(stats_v2[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[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[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;
if (n_evts_delta != 0 && stats_snapshot_time_delta_sec > 0)
{
/* n_evts is total number of kernel side events. */
output_fields["scap.evts_rate_sec"] = (double)(n_evts_delta / stats_snapshot_time_delta_sec);
output_fields["scap.evts_rate_sec"] = std::round((double)(n_evts_delta / stats_snapshot_time_delta_sec) * 10.0) / 10.0; // round to 1 decimal
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe at some point we could compute these metrics directly in sisnp and expose just a list to Falco in this way we could avoid specific strncmp on various metrics

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes totally agreed to push almost everything (or what we can) down into libs.

}
else
{
Expand All @@ -470,28 +486,28 @@ 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[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[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;
if (n_drops_delta != 0 && stats_snapshot_time_delta_sec > 0)
{
/* n_drops is total number of kernel side event drops. */
output_fields["scap.evts_drop_rate_sec"] = (double)(n_drops_delta / stats_snapshot_time_delta_sec);
output_fields["scap.evts_drop_rate_sec"] = std::round((double)(n_drops_delta / stats_snapshot_time_delta_sec) * 10.0) / 10.0; // round to 1 decimal
}
else
{
output_fields["scap.evts_drop_rate_sec"] = (double)(0);
}
m_last_n_drops = n_drops;
}
if (stats_v2[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[stat].value.u64;
output_fields[metric_name] = scap_stats_v2_snapshot[stat].value.u64;
break;
default:
break;
Expand Down
Loading