Print stats when shutting down.

At shutdown, print stats on the number of rules triggered by severity
and rule name. This is done by a lua function print_stats and the
associated table rule_output_counts.

When passing rules to outputs, update the counts in rule_output_counts.
This commit is contained in:
Mark Stemm 2016-05-19 16:19:45 -07:00
parent 1a2719437f
commit a41bb0dac0
3 changed files with 63 additions and 1 deletions

View File

@ -75,6 +75,7 @@ static void display_fatal_err(const string &msg, bool daemon)
string lua_on_event = "on_event";
string lua_add_output = "add_output";
string lua_print_stats = "print_stats";
// Splitting into key=value or key.subkey=value will be handled by configuration class.
std::list<string> cmdline_options;
@ -211,6 +212,26 @@ void add_output(lua_State *ls, output_config oc)
}
// Print statistics on the the rules that triggered
void print_stats(lua_State *ls)
{
lua_getglobal(ls, lua_print_stats.c_str());
if(lua_isfunction(ls, -1))
{
if(lua_pcall(ls, 0, 0, 0) != 0)
{
const char* lerr = lua_tostring(ls, -1);
string err = "Error invoking function print_stats: " + string(lerr);
throw sinsp_exception(err);
}
}
else
{
throw sinsp_exception("No function " + lua_print_stats + " found in lua rule loader module");
}
}
//
// ARGUMENT PARSING AND PROGRAM SETUP
@ -504,6 +525,8 @@ int falco_init(int argc, char **argv)
ls);
inspector->close();
print_stats(ls);
}
catch(sinsp_exception& e)
{

View File

@ -2,6 +2,8 @@ local mod = {}
levels = {"Emergency", "Alert", "Critical", "Error", "Warning", "Notice", "Informational", "Debug"}
mod.levels = levels
local outputs = {}
function mod.stdout(evt, level, format)

View File

@ -230,12 +230,49 @@ function describe_rule(name)
end
end
local rule_output_counts = {by_level={}, by_name={}}
for idx, level in ipairs(output.levels) do
rule_output_counts[level] = 0
end
function on_event(evt_, rule_id)
if state.rules_by_idx[rule_id] == nil then
error ("rule_loader.on_event(): event with invalid rule_id: ", rule_id)
end
output.event(evt_, state.rules_by_idx[rule_id].level, state.rules_by_idx[rule_id].output)
local rule = state.rules_by_idx[rule_id]
if rule_output_counts.by_level[rule.level] == nil then
rule_output_counts.by_level[rule.level] = 1
else
rule_output_counts.by_level[rule.level] = rule_output_counts.by_level[rule.level] + 1
end
if rule_output_counts.by_name[rule.rule] == nil then
rule_output_counts.by_name[rule.rule] = 1
else
rule_output_counts.by_name[rule.rule] = rule_output_counts.by_name[rule.rule] + 1
end
output.event(evt_, rule.level, rule.output)
end
function print_stats()
print("Rule counts by severity:")
for idx, level in ipairs(output.levels) do
-- To keep the output concise, we only print 0 counts for error, warning, and info levels
if rule_output_counts[level] > 0 or level == "Error" or level == "Warning" or level == "Informational" then
print (" "..level..": "..rule_output_counts[level])
end
end
print("Triggered rules by rule name:")
for name, count in pairs(rule_output_counts.by_name) do
print (" "..name..": "..count)
end
end