diff --git a/userspace/engine/falco_engine.cpp b/userspace/engine/falco_engine.cpp index c4dcb771..15aa11d4 100644 --- a/userspace/engine/falco_engine.cpp +++ b/userspace/engine/falco_engine.cpp @@ -1,3 +1,5 @@ +#include +#include #include #include @@ -17,14 +19,19 @@ string lua_print_stats = "print_stats"; using namespace std; -falco_engine::falco_engine() - : m_rules(NULL) +falco_engine::falco_engine(bool seed_rng) + : m_rules(NULL), m_sampling_ratio(1), m_sampling_multiplier(0) { luaopen_lpeg(m_ls); luaopen_yaml(m_ls); falco_common::init(m_lua_main_filename.c_str(), FALCO_ENGINE_SOURCE_LUA_DIR); falco_rules::init(m_ls); + + if(seed_rng) + { + srandom((unsigned) getpid()); + } } falco_engine::~falco_engine() @@ -75,6 +82,12 @@ void falco_engine::enable_rule(string &pattern, bool enabled) falco_engine::rule_result *falco_engine::process_event(sinsp_evt *ev) { + + if(should_drop_evt()) + { + return NULL; + } + if(!m_evttype_filter.run(ev)) { return NULL; @@ -142,4 +155,28 @@ void falco_engine::add_evttype_filter(string &rule, m_evttype_filter.add(rule, evttypes, filter); } +void falco_engine::set_sampling_ratio(uint32_t sampling_ratio) +{ + m_sampling_ratio = sampling_ratio; +} +void falco_engine::set_sampling_multiplier(double sampling_multiplier) +{ + m_sampling_multiplier = sampling_multiplier; +} + +inline bool falco_engine::should_drop_evt() +{ + if(m_sampling_multiplier == 0) + { + return false; + } + + if(m_sampling_ratio == 1) + { + return false; + } + + double coin = (random() * (1.0/RAND_MAX)); + return (coin >= (1.0/(m_sampling_multiplier * m_sampling_ratio))); +} diff --git a/userspace/engine/falco_engine.h b/userspace/engine/falco_engine.h index 38661a06..30223c99 100644 --- a/userspace/engine/falco_engine.h +++ b/userspace/engine/falco_engine.h @@ -18,7 +18,7 @@ class falco_engine : public falco_common { public: - falco_engine(); + falco_engine(bool seed_rng=true); virtual ~falco_engine(); // @@ -66,10 +66,53 @@ public: list &evttypes, sinsp_filter* filter); + // + // Set the sampling ratio, which can affect which events are + // matched against the set of rules. + // + void set_sampling_ratio(uint32_t sampling_ratio); + + // + // Set the sampling ratio multiplier, which can affect which + // events are matched against the set of rules. + // + void set_sampling_multiplier(double sampling_multiplier); + private: + + // + // Determine whether the given event should be matched at all + // against the set of rules, given the current sampling + // ratio/multiplier. + // + inline bool should_drop_evt(); + falco_rules *m_rules; sinsp_evttype_filter m_evttype_filter; + // + // Here's how the sampling ratio and multiplier influence + // whether or not an event is dropped in + // should_drop_evt(). The intent is that m_sampling_ratio is + // generally changing external to the engine e.g. in the main + // inspector class based on how busy the inspector is. A + // sampling ratio implies no dropping. Values > 1 imply + // increasing levels of dropping. External to the engine, the + // sampling ratio results in events being dropped at the + // kernel/inspector interface. + // + // The sampling multiplier is an amplification to the sampling + // factor in m_sampling_ratio. If 0, no additional events are + // dropped other than those that might be dropped by the + // kernel/inspector interface. If 1, events that make it past + // the kernel module are subject to an additional level of + // dropping at the falco engine, scaling with the sampling + // ratio in m_sampling_ratio. + // + + uint32_t m_sampling_ratio; + double m_sampling_multiplier; + std::string m_lua_main_filename = "rule_loader.lua"; };