mirror of
https://github.com/falcosecurity/falco.git
synced 2025-06-26 22:57:24 +00:00
Add ability to filter events by priority/cleanups
Clean up the handling of priority levels within rules. It used to be a mix of strings handled in various places. Now, in falco_common.h there's a consistent type for priority-as-number as well as a list of priority-as-string values. Priorities are passed around as numbers instead of strings. It's still permissive about capitalization. Also add the ability to load rules by severity. New falco config option "priority=<val>"/-o priority=<val> specifies the minimum priority level of rules that will be loaded. Add unit tests for same. The test suppresses INFO notifications for a rule/trace file combination that would otherwise generate them.
This commit is contained in:
parent
c41bcbd240
commit
aa073586f1
@ -15,6 +15,12 @@ log_syslog: true
|
|||||||
# "alert", "critical", "error", "warning", "notice", "info", "debug".
|
# "alert", "critical", "error", "warning", "notice", "info", "debug".
|
||||||
log_level: info
|
log_level: info
|
||||||
|
|
||||||
|
# Minimum rule priority level to load and run. All rules having a
|
||||||
|
# priority more severe than this level will be loaded/run. Can be one
|
||||||
|
# of "emergency", "alert", "critical", "error", "warning", "notice",
|
||||||
|
# "info", "debug".
|
||||||
|
priority: debug
|
||||||
|
|
||||||
# A throttling mechanism implemented as a token bucket limits the
|
# A throttling mechanism implemented as a token bucket limits the
|
||||||
# rate of falco notifications. This throttling is controlled by the following configuration
|
# rate of falco notifications. This throttling is controlled by the following configuration
|
||||||
# options:
|
# options:
|
||||||
|
@ -30,6 +30,7 @@ class FalcoTest(Test):
|
|||||||
self.trace_file = os.path.join(self.basedir, self.trace_file)
|
self.trace_file = os.path.join(self.basedir, self.trace_file)
|
||||||
|
|
||||||
self.json_output = self.params.get('json_output', '*', default=False)
|
self.json_output = self.params.get('json_output', '*', default=False)
|
||||||
|
self.priority = self.params.get('priority', '*', default='debug')
|
||||||
self.rules_file = self.params.get('rules_file', '*', default=os.path.join(self.basedir, '../rules/falco_rules.yaml'))
|
self.rules_file = self.params.get('rules_file', '*', default=os.path.join(self.basedir, '../rules/falco_rules.yaml'))
|
||||||
|
|
||||||
if not isinstance(self.rules_file, list):
|
if not isinstance(self.rules_file, list):
|
||||||
@ -347,8 +348,8 @@ class FalcoTest(Test):
|
|||||||
trace_arg = "-e {}".format(self.trace_file)
|
trace_arg = "-e {}".format(self.trace_file)
|
||||||
|
|
||||||
# Run falco
|
# Run falco
|
||||||
cmd = '{} {} {} -c {} {} -o json_output={} -v'.format(
|
cmd = '{} {} {} -c {} {} -o json_output={} -o priority={} -v'.format(
|
||||||
self.falco_binary_path, self.rules_args, self.disabled_args, self.conf_file, trace_arg, self.json_output)
|
self.falco_binary_path, self.rules_args, self.disabled_args, self.conf_file, trace_arg, self.json_output, self.priority)
|
||||||
|
|
||||||
for tag in self.disable_tags:
|
for tag in self.disable_tags:
|
||||||
cmd += ' -T {}'.format(tag)
|
cmd += ' -T {}'.format(tag)
|
||||||
|
@ -129,6 +129,21 @@ trace_files: !mux
|
|||||||
- rules/double_rule.yaml
|
- rules/double_rule.yaml
|
||||||
trace_file: trace_files/cat_write.scap
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
|
multiple_rules_suppress_info:
|
||||||
|
detect: True
|
||||||
|
detect_level:
|
||||||
|
- WARNING
|
||||||
|
- ERROR
|
||||||
|
priority: WARNING
|
||||||
|
detect_counts:
|
||||||
|
- open_from_cat: 8
|
||||||
|
- exec_from_cat: 1
|
||||||
|
- access_from_cat: 0
|
||||||
|
rules_file:
|
||||||
|
- rules/single_rule.yaml
|
||||||
|
- rules/double_rule.yaml
|
||||||
|
trace_file: trace_files/cat_write.scap
|
||||||
|
|
||||||
multiple_rules_overriding:
|
multiple_rules_overriding:
|
||||||
detect: False
|
detect: False
|
||||||
rules_file:
|
rules_file:
|
||||||
|
@ -21,6 +21,16 @@ along with falco. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include "config_falco_engine.h"
|
#include "config_falco_engine.h"
|
||||||
#include "falco_common.h"
|
#include "falco_common.h"
|
||||||
|
|
||||||
|
std::vector<std::string> falco_common::priority_names = {
|
||||||
|
"Emergency",
|
||||||
|
"Alert",
|
||||||
|
"Critical",
|
||||||
|
"Error",
|
||||||
|
"Warning",
|
||||||
|
"Notice",
|
||||||
|
"Informational",
|
||||||
|
"Debug"};
|
||||||
|
|
||||||
falco_common::falco_common()
|
falco_common::falco_common()
|
||||||
{
|
{
|
||||||
m_ls = lua_open();
|
m_ls = lua_open();
|
||||||
|
@ -74,6 +74,22 @@ public:
|
|||||||
|
|
||||||
void set_inspector(sinsp *inspector);
|
void set_inspector(sinsp *inspector);
|
||||||
|
|
||||||
|
// Priority levels, as a vector of strings
|
||||||
|
static std::vector<std::string> priority_names;
|
||||||
|
|
||||||
|
// Same as numbers/indices into the above vector
|
||||||
|
enum priority_type
|
||||||
|
{
|
||||||
|
PRIORITY_EMERGENCY = 0,
|
||||||
|
PRIORITY_ALERT = 1,
|
||||||
|
PRIORITY_CRITICAL = 2,
|
||||||
|
PRIORITY_ERROR = 3,
|
||||||
|
PRIORITY_WARNING = 4,
|
||||||
|
PRIORITY_NOTICE = 5,
|
||||||
|
PRIORITY_INFORMATIONAL = 6,
|
||||||
|
PRIORITY_DEBUG = 7
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
lua_State *m_ls;
|
lua_State *m_ls;
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ using namespace std;
|
|||||||
|
|
||||||
falco_engine::falco_engine(bool seed_rng)
|
falco_engine::falco_engine(bool seed_rng)
|
||||||
: m_rules(NULL), m_next_ruleset_id(0),
|
: m_rules(NULL), m_next_ruleset_id(0),
|
||||||
|
m_min_priority(falco_common::PRIORITY_DEBUG),
|
||||||
m_sampling_ratio(1), m_sampling_multiplier(0),
|
m_sampling_ratio(1), m_sampling_multiplier(0),
|
||||||
m_replace_container_info(false)
|
m_replace_container_info(false)
|
||||||
{
|
{
|
||||||
@ -89,7 +90,7 @@ void falco_engine::load_rules(const string &rules_content, bool verbose, bool al
|
|||||||
bool json_output = false;
|
bool json_output = false;
|
||||||
falco_formats::init(m_inspector, m_ls, json_output);
|
falco_formats::init(m_inspector, m_ls, json_output);
|
||||||
|
|
||||||
m_rules->load_rules(rules_content, verbose, all_events, m_extra, m_replace_container_info);
|
m_rules->load_rules(rules_content, verbose, all_events, m_extra, m_replace_container_info, m_min_priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
void falco_engine::load_rules_file(const string &rules_filename, bool verbose, bool all_events)
|
void falco_engine::load_rules_file(const string &rules_filename, bool verbose, bool all_events)
|
||||||
@ -134,6 +135,11 @@ void falco_engine::enable_rule_by_tag(const set<string> &tags, bool enabled)
|
|||||||
enable_rule_by_tag(tags, enabled, m_default_ruleset);
|
enable_rule_by_tag(tags, enabled, m_default_ruleset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void falco_engine::set_min_priority(falco_common::priority_type priority)
|
||||||
|
{
|
||||||
|
m_min_priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t falco_engine::find_ruleset_id(const std::string &ruleset)
|
uint16_t falco_engine::find_ruleset_id(const std::string &ruleset)
|
||||||
{
|
{
|
||||||
auto it = m_known_rulesets.lower_bound(ruleset);
|
auto it = m_known_rulesets.lower_bound(ruleset);
|
||||||
@ -178,7 +184,7 @@ unique_ptr<falco_engine::rule_result> falco_engine::process_event(sinsp_evt *ev,
|
|||||||
res->evt = ev;
|
res->evt = ev;
|
||||||
const char *p = lua_tostring(m_ls, -3);
|
const char *p = lua_tostring(m_ls, -3);
|
||||||
res->rule = p;
|
res->rule = p;
|
||||||
res->priority = lua_tostring(m_ls, -2);
|
res->priority_num = (falco_common::priority_type) lua_tonumber(m_ls, -2);
|
||||||
res->format = lua_tostring(m_ls, -1);
|
res->format = lua_tostring(m_ls, -1);
|
||||||
lua_pop(m_ls, 3);
|
lua_pop(m_ls, 3);
|
||||||
}
|
}
|
||||||
|
@ -67,10 +67,13 @@ public:
|
|||||||
// Wrapper that assumes the default ruleset
|
// Wrapper that assumes the default ruleset
|
||||||
void enable_rule_by_tag(const std::set<std::string> &tags, bool enabled);
|
void enable_rule_by_tag(const std::set<std::string> &tags, bool enabled);
|
||||||
|
|
||||||
|
// Only load rules having this priority or more severe.
|
||||||
|
void set_min_priority(falco_common::priority_type priority);
|
||||||
|
|
||||||
struct rule_result {
|
struct rule_result {
|
||||||
sinsp_evt *evt;
|
sinsp_evt *evt;
|
||||||
std::string rule;
|
std::string rule;
|
||||||
std::string priority;
|
falco_common::priority_type priority_num;
|
||||||
std::string format;
|
std::string format;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -158,6 +161,7 @@ private:
|
|||||||
uint16_t m_next_ruleset_id;
|
uint16_t m_next_ruleset_id;
|
||||||
std::map<string, uint16_t> m_known_rulesets;
|
std::map<string, uint16_t> m_known_rulesets;
|
||||||
std::unique_ptr<sinsp_evttype_filter> m_evttype_filter;
|
std::unique_ptr<sinsp_evttype_filter> m_evttype_filter;
|
||||||
|
falco_common::priority_type m_min_priority;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Here's how the sampling ratio and multiplier influence
|
// Here's how the sampling ratio and multiplier influence
|
||||||
|
@ -58,6 +58,17 @@ function map(f, arr)
|
|||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
|
|
||||||
|
priorities = {"Emergency", "Alert", "Critical", "Error", "Warning", "Notice", "Informational", "Debug"}
|
||||||
|
|
||||||
|
local function priority_num_for(s)
|
||||||
|
s = string.lower(s)
|
||||||
|
for i,v in ipairs(priorities) do
|
||||||
|
if (string.find(string.lower(v), "^"..s)) then
|
||||||
|
return i - 1 -- (numbers start at 0, lua indices start at 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
error("Invalid priority level: "..s)
|
||||||
|
end
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
Take a filter AST and set it up in the libsinsp runtime, using the filter API.
|
Take a filter AST and set it up in the libsinsp runtime, using the filter API.
|
||||||
@ -171,7 +182,7 @@ function table.tostring( tbl )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function load_rules(rules_content, rules_mgr, verbose, all_events, extra, replace_container_info)
|
function load_rules(rules_content, rules_mgr, verbose, all_events, extra, replace_container_info, min_priority)
|
||||||
|
|
||||||
compiler.set_verbose(verbose)
|
compiler.set_verbose(verbose)
|
||||||
compiler.set_all_events(all_events)
|
compiler.set_all_events(all_events)
|
||||||
@ -293,18 +304,23 @@ function load_rules(rules_content, rules_mgr, verbose, all_events, extra, replac
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Note that we can overwrite rules, but the rules are still
|
-- Convert the priority-as-string to a priority-as-number now
|
||||||
-- loaded in the order in which they first appeared,
|
v['priority_num'] = priority_num_for(v['priority'])
|
||||||
-- potentially across multiple files.
|
|
||||||
if state.rules_by_name[v['rule']] == nil then
|
if v['priority_num'] <= min_priority then
|
||||||
state.ordered_rule_names[#state.ordered_rule_names+1] = v['rule']
|
-- Note that we can overwrite rules, but the rules are still
|
||||||
|
-- loaded in the order in which they first appeared,
|
||||||
|
-- potentially across multiple files.
|
||||||
|
if state.rules_by_name[v['rule']] == nil then
|
||||||
|
state.ordered_rule_names[#state.ordered_rule_names+1] = v['rule']
|
||||||
|
end
|
||||||
|
|
||||||
|
-- The output field might be a folded-style, which adds a
|
||||||
|
-- newline to the end. Remove any trailing newlines.
|
||||||
|
v['output'] = compiler.trim(v['output'])
|
||||||
|
|
||||||
|
state.rules_by_name[v['rule']] = v
|
||||||
end
|
end
|
||||||
|
|
||||||
-- The output field might be a folded-style, which adds a
|
|
||||||
-- newline to the end. Remove any trailing newlines.
|
|
||||||
v['output'] = compiler.trim(v['output'])
|
|
||||||
|
|
||||||
state.rules_by_name[v['rule']] = v
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
error ("Unknown rule object: "..table.tostring(v))
|
error ("Unknown rule object: "..table.tostring(v))
|
||||||
@ -504,7 +520,7 @@ function on_event(evt_, rule_id)
|
|||||||
-- Prefix output with '*' so formatting is permissive
|
-- Prefix output with '*' so formatting is permissive
|
||||||
output = "*"..rule.output
|
output = "*"..rule.output
|
||||||
|
|
||||||
return rule.rule, rule.priority, output
|
return rule.rule, rule.priority_num, output
|
||||||
end
|
end
|
||||||
|
|
||||||
function print_stats()
|
function print_stats()
|
||||||
|
@ -145,7 +145,8 @@ void falco_rules::enable_rule(string &rule, bool enabled)
|
|||||||
|
|
||||||
void falco_rules::load_rules(const string &rules_content,
|
void falco_rules::load_rules(const string &rules_content,
|
||||||
bool verbose, bool all_events,
|
bool verbose, bool all_events,
|
||||||
string &extra, bool replace_container_info)
|
string &extra, bool replace_container_info,
|
||||||
|
falco_common::priority_type min_priority)
|
||||||
{
|
{
|
||||||
lua_getglobal(m_ls, m_lua_load_rules.c_str());
|
lua_getglobal(m_ls, m_lua_load_rules.c_str());
|
||||||
if(lua_isfunction(m_ls, -1))
|
if(lua_isfunction(m_ls, -1))
|
||||||
@ -221,7 +222,8 @@ void falco_rules::load_rules(const string &rules_content,
|
|||||||
lua_pushboolean(m_ls, (all_events ? 1 : 0));
|
lua_pushboolean(m_ls, (all_events ? 1 : 0));
|
||||||
lua_pushstring(m_ls, extra.c_str());
|
lua_pushstring(m_ls, extra.c_str());
|
||||||
lua_pushboolean(m_ls, (replace_container_info ? 1 : 0));
|
lua_pushboolean(m_ls, (replace_container_info ? 1 : 0));
|
||||||
if(lua_pcall(m_ls, 6, 0, 0) != 0)
|
lua_pushnumber(m_ls, min_priority);
|
||||||
|
if(lua_pcall(m_ls, 7, 0, 0) != 0)
|
||||||
{
|
{
|
||||||
const char* lerr = lua_tostring(m_ls, -1);
|
const char* lerr = lua_tostring(m_ls, -1);
|
||||||
string err = "Error loading rules:" + string(lerr);
|
string err = "Error loading rules:" + string(lerr);
|
||||||
|
@ -24,6 +24,8 @@ along with falco. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#include "lua_parser.h"
|
#include "lua_parser.h"
|
||||||
|
|
||||||
|
#include "falco_common.h"
|
||||||
|
|
||||||
class falco_engine;
|
class falco_engine;
|
||||||
|
|
||||||
class falco_rules
|
class falco_rules
|
||||||
@ -32,7 +34,8 @@ class falco_rules
|
|||||||
falco_rules(sinsp* inspector, falco_engine *engine, lua_State *ls);
|
falco_rules(sinsp* inspector, falco_engine *engine, lua_State *ls);
|
||||||
~falco_rules();
|
~falco_rules();
|
||||||
void load_rules(const string &rules_content, bool verbose, bool all_events,
|
void load_rules(const string &rules_content, bool verbose, bool all_events,
|
||||||
std::string &extra, bool replace_container_info);
|
std::string &extra, bool replace_container_info,
|
||||||
|
falco_common::priority_type min_priority);
|
||||||
void describe_rule(string *rule);
|
void describe_rule(string *rule);
|
||||||
|
|
||||||
static void init(lua_State *ls);
|
static void init(lua_State *ls);
|
||||||
|
@ -108,6 +108,19 @@ void falco_configuration::init(string conf_filename, list<string> &cmdline_optio
|
|||||||
m_notifications_rate = m_config->get_scalar<uint32_t>("outputs", "rate", 1);
|
m_notifications_rate = m_config->get_scalar<uint32_t>("outputs", "rate", 1);
|
||||||
m_notifications_max_burst = m_config->get_scalar<uint32_t>("outputs", "max_burst", 1000);
|
m_notifications_max_burst = m_config->get_scalar<uint32_t>("outputs", "max_burst", 1000);
|
||||||
|
|
||||||
|
string priority = m_config->get_scalar<string>("priority", "debug");
|
||||||
|
vector<string>::iterator it;
|
||||||
|
|
||||||
|
auto comp = [priority] (string &s) {
|
||||||
|
return (strcasecmp(s.c_str(), priority.c_str()) == 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
if((it = std::find_if(falco_common::priority_names.begin(), falco_common::priority_names.end(), comp)) == falco_common::priority_names.end())
|
||||||
|
{
|
||||||
|
throw invalid_argument("Unknown priority \"" + priority + "\"--must be one of emergency, alert, critical, error, warning, notice, informational, debug");
|
||||||
|
}
|
||||||
|
m_min_priority = (falco_common::priority_type) (it - falco_common::priority_names.begin());
|
||||||
|
|
||||||
falco_logger::log_stderr = m_config->get_scalar<bool>("log_stderr", false);
|
falco_logger::log_stderr = m_config->get_scalar<bool>("log_stderr", false);
|
||||||
falco_logger::log_syslog = m_config->get_scalar<bool>("log_syslog", true);
|
falco_logger::log_syslog = m_config->get_scalar<bool>("log_syslog", true);
|
||||||
}
|
}
|
||||||
|
@ -146,6 +146,8 @@ class falco_configuration
|
|||||||
std::vector<falco_outputs::output_config> m_outputs;
|
std::vector<falco_outputs::output_config> m_outputs;
|
||||||
uint32_t m_notifications_rate;
|
uint32_t m_notifications_rate;
|
||||||
uint32_t m_notifications_max_burst;
|
uint32_t m_notifications_max_burst;
|
||||||
|
|
||||||
|
falco_common::priority_type m_min_priority;
|
||||||
private:
|
private:
|
||||||
void init_cmdline_options(std::list<std::string> &cmdline_options);
|
void init_cmdline_options(std::list<std::string> &cmdline_options);
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ uint64_t do_inspect(falco_engine *engine,
|
|||||||
unique_ptr<falco_engine::rule_result> res = engine->process_event(ev);
|
unique_ptr<falco_engine::rule_result> res = engine->process_event(ev);
|
||||||
if(res)
|
if(res)
|
||||||
{
|
{
|
||||||
outputs->handle_event(res->evt, res->rule, res->priority, res->format);
|
outputs->handle_event(res->evt, res->rule, res->priority_num, res->format);
|
||||||
}
|
}
|
||||||
|
|
||||||
num_evts++;
|
num_evts++;
|
||||||
@ -461,6 +461,8 @@ int falco_init(int argc, char **argv)
|
|||||||
config.m_rules_filenames = rules_filenames;
|
config.m_rules_filenames = rules_filenames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
engine->set_min_priority(config.m_min_priority);
|
||||||
|
|
||||||
for (auto filename : config.m_rules_filenames)
|
for (auto filename : config.m_rules_filenames)
|
||||||
{
|
{
|
||||||
engine->load_rules_file(filename, verbose, all_events);
|
engine->load_rules_file(filename, verbose, all_events);
|
||||||
|
@ -105,7 +105,7 @@ void falco_outputs::add_output(output_config oc)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void falco_outputs::handle_event(sinsp_evt *ev, string &rule, string &priority, string &format)
|
void falco_outputs::handle_event(sinsp_evt *ev, string &rule, falco_common::priority_type priority, string &format)
|
||||||
{
|
{
|
||||||
if(!m_notifications_tb.claim())
|
if(!m_notifications_tb.claim())
|
||||||
{
|
{
|
||||||
@ -119,10 +119,11 @@ void falco_outputs::handle_event(sinsp_evt *ev, string &rule, string &priority,
|
|||||||
{
|
{
|
||||||
lua_pushlightuserdata(m_ls, ev);
|
lua_pushlightuserdata(m_ls, ev);
|
||||||
lua_pushstring(m_ls, rule.c_str());
|
lua_pushstring(m_ls, rule.c_str());
|
||||||
lua_pushstring(m_ls, priority.c_str());
|
lua_pushstring(m_ls, falco_common::priority_names[priority].c_str());
|
||||||
|
lua_pushnumber(m_ls, priority);
|
||||||
lua_pushstring(m_ls, format.c_str());
|
lua_pushstring(m_ls, format.c_str());
|
||||||
|
|
||||||
if(lua_pcall(m_ls, 4, 0, 0) != 0)
|
if(lua_pcall(m_ls, 5, 0, 0) != 0)
|
||||||
{
|
{
|
||||||
const char* lerr = lua_tostring(m_ls, -1);
|
const char* lerr = lua_tostring(m_ls, -1);
|
||||||
string err = "Error invoking function output: " + string(lerr);
|
string err = "Error invoking function output: " + string(lerr);
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
// ev is an event that has matched some rule. Pass the event
|
// ev is an event that has matched some rule. Pass the event
|
||||||
// to all configured outputs.
|
// to all configured outputs.
|
||||||
//
|
//
|
||||||
void handle_event(sinsp_evt *ev, std::string &rule, std::string &priority, std::string &format);
|
void handle_event(sinsp_evt *ev, std::string &rule, falco_common::priority_type priority, std::string &format);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
|
@ -18,13 +18,9 @@
|
|||||||
|
|
||||||
local mod = {}
|
local mod = {}
|
||||||
|
|
||||||
levels = {"Emergency", "Alert", "Critical", "Error", "Warning", "Notice", "Informational", "Debug"}
|
|
||||||
|
|
||||||
mod.levels = levels
|
|
||||||
|
|
||||||
local outputs = {}
|
local outputs = {}
|
||||||
|
|
||||||
function mod.stdout(level, msg)
|
function mod.stdout(priority, priority_num, msg)
|
||||||
print (msg)
|
print (msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -41,17 +37,17 @@ function mod.file_validate(options)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mod.file(level, msg, options)
|
function mod.file(priority, priority_num, msg, options)
|
||||||
file = io.open(options.filename, "a+")
|
file = io.open(options.filename, "a+")
|
||||||
file:write(msg, "\n")
|
file:write(msg, "\n")
|
||||||
file:close()
|
file:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
function mod.syslog(level, msg, options)
|
function mod.syslog(priority, priority_num, msg, options)
|
||||||
falco.syslog(level, msg)
|
falco.syslog(priority_num, msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mod.program(level, msg, options)
|
function mod.program(priority, priority_num, msg, options)
|
||||||
-- XXX Ideally we'd check that the program ran
|
-- XXX Ideally we'd check that the program ran
|
||||||
-- successfully. However, the luajit we're using returns true even
|
-- successfully. However, the luajit we're using returns true even
|
||||||
-- when the shell can't run the program.
|
-- when the shell can't run the program.
|
||||||
@ -62,31 +58,19 @@ function mod.program(level, msg, options)
|
|||||||
file:close()
|
file:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function level_of(s)
|
function output_event(event, rule, priority, priority_num, format)
|
||||||
s = string.lower(s)
|
|
||||||
for i,v in ipairs(levels) do
|
|
||||||
if (string.find(string.lower(v), "^"..s)) then
|
|
||||||
return i - 1 -- (syslog levels start at 0, lua indices start at 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
error("Invalid severity level: "..s)
|
|
||||||
end
|
|
||||||
|
|
||||||
function output_event(event, rule, priority, format)
|
|
||||||
local level = level_of(priority)
|
|
||||||
|
|
||||||
-- If format starts with a *, remove it, as we're adding our own
|
-- If format starts with a *, remove it, as we're adding our own
|
||||||
-- prefix here.
|
-- prefix here.
|
||||||
if format:sub(1,1) == "*" then
|
if format:sub(1,1) == "*" then
|
||||||
format = format:sub(2)
|
format = format:sub(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
format = "*%evt.time: "..levels[level+1].." "..format
|
format = "*%evt.time: "..priority.." "..format
|
||||||
|
|
||||||
msg = formats.format_event(event, rule, levels[level+1], format)
|
msg = formats.format_event(event, rule, priority, format)
|
||||||
|
|
||||||
for index,o in ipairs(outputs) do
|
for index,o in ipairs(outputs) do
|
||||||
o.output(level, msg, o.config)
|
o.output(priority, priority_num, msg, o.config)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user