mirror of
https://github.com/falcosecurity/falco.git
synced 2025-09-14 05:51:43 +00:00
rework digwatch event output handling
the high-level change is that events matching a rule are now send into a lua "on_event" function for handling, rather than doing the handling down in c++. more specifics: before, the lua "load_rule" function registered formatters with associated IDs with the c++ side, which later used this state to reconcile events with formats and print output accordingly. now, no such state is kept on the c++ side. the lua "load_rule" function maintains the id->formatters map, and uses it to print outputs when it receives events. this change simplifies the existing flow and will also make the forthcoming implementation of function outputs far simpler than it would have been in the current setup.
This commit is contained in:
@@ -45,18 +45,19 @@ static void usage()
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string lua_on_event = "on_event";
|
||||||
|
|
||||||
//
|
//
|
||||||
// Event processing loop
|
// Event processing loop
|
||||||
//
|
//
|
||||||
void do_inspect(sinsp* inspector,
|
void do_inspect(sinsp* inspector,
|
||||||
digwatch_rules* rules,
|
digwatch_rules* rules,
|
||||||
digwatch_formats* formats)
|
digwatch_formats* formats,
|
||||||
|
lua_State* ls)
|
||||||
{
|
{
|
||||||
int32_t res;
|
int32_t res;
|
||||||
sinsp_evt* ev;
|
sinsp_evt* ev;
|
||||||
string line;
|
string line;
|
||||||
sinsp_evt_formatter* formatter;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Loop through the events
|
// Loop through the events
|
||||||
@@ -89,20 +90,24 @@ void do_inspect(sinsp* inspector,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
formatter = formats->lookup_formatter(ev->get_check_id());
|
lua_getglobal(ls, lua_on_event.c_str());
|
||||||
if(!formatter)
|
|
||||||
|
if(lua_isfunction(ls, -1))
|
||||||
{
|
{
|
||||||
throw sinsp_exception("Error: No formatter for event with id %d " + to_string(ev->get_check_id()));
|
lua_pushlightuserdata(ls, ev);
|
||||||
|
lua_pushnumber(ls, ev->get_check_id());
|
||||||
|
|
||||||
|
if(lua_pcall(ls, 2, 0, 0) != 0)
|
||||||
|
{
|
||||||
|
const char* lerr = lua_tostring(ls, -1);
|
||||||
|
string err = "Error installing rules: " + string(lerr);
|
||||||
|
throw sinsp_exception(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
bool has_all = formatter->tostring(ev, &line);
|
{
|
||||||
if(!has_all) {
|
throw sinsp_exception("No function " + lua_on_event + " found in lua compiler module");
|
||||||
cout << "(missing fields) ";
|
|
||||||
}
|
}
|
||||||
cout << line;
|
|
||||||
cout << endl;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +224,8 @@ int digwatch_init(int argc, char **argv)
|
|||||||
|
|
||||||
do_inspect(inspector,
|
do_inspect(inspector,
|
||||||
rules,
|
rules,
|
||||||
formats);
|
formats,
|
||||||
|
ls);
|
||||||
|
|
||||||
inspector->close();
|
inspector->close();
|
||||||
}
|
}
|
||||||
|
@@ -6,12 +6,12 @@ extern "C" {
|
|||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<uint32_t, sinsp_evt_formatter*> g_format_map;
|
|
||||||
sinsp* g_inspector;
|
sinsp* g_inspector;
|
||||||
|
|
||||||
const static struct luaL_reg ll_digwatch [] =
|
const static struct luaL_reg ll_digwatch [] =
|
||||||
{
|
{
|
||||||
{"set_formatter", &digwatch_formats::set_formatter},
|
{"formatter", &digwatch_formats::formatter},
|
||||||
|
{"format_event", &digwatch_formats::format_event},
|
||||||
{NULL,NULL}
|
{NULL,NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -24,20 +24,12 @@ digwatch_formats::digwatch_formats(sinsp* inspector, lua_State *ls)
|
|||||||
luaL_openlib(m_ls, "digwatch", ll_digwatch, 0);
|
luaL_openlib(m_ls, "digwatch", ll_digwatch, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int digwatch_formats::set_formatter (lua_State *ls) {
|
int digwatch_formats::formatter(lua_State *ls) {
|
||||||
uint32_t index = luaL_checkinteger(ls, 1);
|
string format = luaL_checkstring(ls, 1);
|
||||||
string format = luaL_checkstring(ls, 2);
|
sinsp_evt_formatter* formatter;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(format == "" || format == "default")
|
formatter = new sinsp_evt_formatter(g_inspector, format);
|
||||||
{
|
|
||||||
g_format_map[index] = new sinsp_evt_formatter(g_inspector, DEFAULT_OUTPUT_STR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_format_map[index] = new sinsp_evt_formatter(g_inspector, format);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch(sinsp_exception& e)
|
catch(sinsp_exception& e)
|
||||||
{
|
{
|
||||||
@@ -46,12 +38,24 @@ int digwatch_formats::set_formatter (lua_State *ls) {
|
|||||||
throw sinsp_exception("set_formatter error");
|
throw sinsp_exception("set_formatter error");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
lua_pushlightuserdata(ls, formatter);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sinsp_evt_formatter* digwatch_formats::lookup_formatter(uint32_t index)
|
int digwatch_formats::format_event (lua_State *ls) {
|
||||||
{
|
string line;
|
||||||
return g_format_map[index];
|
|
||||||
|
if (!lua_islightuserdata(ls, -1) || !lua_islightuserdata(ls, -2)) {
|
||||||
|
string err = "invalid arguments passed to format_event() ";
|
||||||
|
throw sinsp_exception("format_event error");
|
||||||
|
}
|
||||||
|
sinsp_evt* evt = (sinsp_evt*)lua_topointer(ls, 1);
|
||||||
|
sinsp_evt_formatter* formatter = (sinsp_evt_formatter*)lua_topointer(ls, 2);
|
||||||
|
|
||||||
|
formatter->tostring(evt, &line);
|
||||||
|
|
||||||
|
lua_pushstring(ls, line.c_str());
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -10,9 +10,11 @@ class digwatch_formats
|
|||||||
public:
|
public:
|
||||||
digwatch_formats(sinsp* inspector, lua_State *ls);
|
digwatch_formats(sinsp* inspector, lua_State *ls);
|
||||||
|
|
||||||
// set_formatter(index, format_string)
|
// formatter = digwatch.formatter(format_string)
|
||||||
static int set_formatter(lua_State *ls);
|
static int formatter(lua_State *ls);
|
||||||
sinsp_evt_formatter* lookup_formatter(uint32_t index);
|
|
||||||
|
// formatted_string = digwatch.format_event(evt, formatter)
|
||||||
|
static int format_event(lua_State *ls);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
lua_State* m_ls;
|
lua_State* m_ls;
|
||||||
|
@@ -173,7 +173,7 @@ end
|
|||||||
|
|
||||||
local function rule(filter, output)
|
local function rule(filter, output)
|
||||||
if not output then
|
if not output then
|
||||||
output = outputformat("")
|
output = outputformat(nil)
|
||||||
end
|
end
|
||||||
return {type = "Rule", filter = filter, output = output}
|
return {type = "Rule", filter = filter, output = output}
|
||||||
end
|
end
|
||||||
|
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
|
local DEFAULT_OUTPUT_FORMAT = "%evt.num %evt.time %evt.cpu %proc.name (%thread.tid) %evt.dir %evt.type %evt.args"
|
||||||
|
|
||||||
local compiler = require "compiler"
|
local compiler = require "compiler"
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
@@ -72,7 +74,7 @@ local state
|
|||||||
to the line-oriented compiler.
|
to the line-oriented compiler.
|
||||||
--]]
|
--]]
|
||||||
local function init()
|
local function init()
|
||||||
return {macros={}, filter_ast=nil, n_rules=0}
|
return {macros={}, filter_ast=nil, n_rules=0, outputs={}}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -90,8 +92,16 @@ function load_rule(r)
|
|||||||
error ("Unexpected type in load_rule: "..line_ast.type)
|
error ("Unexpected type in load_rule: "..line_ast.type)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Register a formatter with the output string from this rule
|
state.n_rules = state.n_rules + 1
|
||||||
digwatch.set_formatter(state.n_rules, line_ast.output.value)
|
|
||||||
|
local format
|
||||||
|
if line_ast.output.value==nil then
|
||||||
|
format = DEFAULT_OUTPUT_FORMAT
|
||||||
|
else
|
||||||
|
format = line_ast.output.value
|
||||||
|
end
|
||||||
|
|
||||||
|
state.outputs[state.n_rules] = digwatch.formatter(format)
|
||||||
|
|
||||||
-- Store the index of this formatter in each relational expression that
|
-- Store the index of this formatter in each relational expression that
|
||||||
-- this rule contains.
|
-- this rule contains.
|
||||||
@@ -100,8 +110,6 @@ function load_rule(r)
|
|||||||
-- event.
|
-- event.
|
||||||
mark_relational_nodes(line_ast.filter.value, state.n_rules)
|
mark_relational_nodes(line_ast.filter.value, state.n_rules)
|
||||||
|
|
||||||
state.n_rules = state.n_rules + 1
|
|
||||||
|
|
||||||
-- Rule ASTs are merged together into one big AST, with "OR" between each
|
-- Rule ASTs are merged together into one big AST, with "OR" between each
|
||||||
-- rule.
|
-- rule.
|
||||||
if (state.filter_ast == nil) then
|
if (state.filter_ast == nil) then
|
||||||
@@ -114,3 +122,8 @@ end
|
|||||||
function on_done()
|
function on_done()
|
||||||
install_filter(state.filter_ast)
|
install_filter(state.filter_ast)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function on_event(evt, rule_id)
|
||||||
|
print(digwatch.format_event(evt, state.outputs[rule_id]))
|
||||||
|
end
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user