diff --git a/userspace/falco/falco_outputs.cpp b/userspace/falco/falco_outputs.cpp index f77eb80231b..2f11a9b607b 100644 --- a/userspace/falco/falco_outputs.cpp +++ b/userspace/falco/falco_outputs.cpp @@ -27,13 +27,28 @@ along with falco. If not, see . using namespace std; falco_outputs::falco_outputs() + : m_initialized(false) { } falco_outputs::~falco_outputs() { + if(m_initialized) + { + lua_getglobal(m_ls, m_lua_output_cleanup.c_str()); + if(!lua_isfunction(m_ls, -1)) + { + throw falco_exception("No function " + m_lua_output_cleanup + " found. "); + } + + if(lua_pcall(m_ls, 0, 0, 0) != 0) + { + const char* lerr = lua_tostring(m_ls, -1); + throw falco_exception(string(lerr)); + } + } } void falco_outputs::init(bool json_output) @@ -52,6 +67,8 @@ void falco_outputs::init(bool json_output) falco_formats::init(m_inspector, m_ls, json_output); falco_logger::init(m_ls); + + m_initialized = true; } void falco_outputs::add_output(output_config oc) diff --git a/userspace/falco/falco_outputs.h b/userspace/falco/falco_outputs.h index 247d837c831..b9627489d66 100644 --- a/userspace/falco/falco_outputs.h +++ b/userspace/falco/falco_outputs.h @@ -51,7 +51,10 @@ class falco_outputs : public falco_common void handle_event(sinsp_evt *ev, std::string &level, std::string &priority, std::string &format); private: + bool m_initialized; + std::string m_lua_add_output = "add_output"; std::string m_lua_output_event = "output_event"; + std::string m_lua_output_cleanup = "output_cleanup"; std::string m_lua_main_filename = "output.lua"; }; diff --git a/userspace/falco/lua/output.lua b/userspace/falco/lua/output.lua index e2ec0127e26..39a321c87c2 100644 --- a/userspace/falco/lua/output.lua +++ b/userspace/falco/lua/output.lua @@ -24,6 +24,8 @@ mod.levels = levels local outputs = {} +local formatters = {} + function mod.stdout(level, msg) print (msg) end @@ -75,14 +77,26 @@ end function output_event(event, rule, priority, format) local level = level_of(priority) format = "*%evt.time: "..levels[level+1].." "..format - formatter = formats.formatter(format) + if formatters[rule] == nil then + formatter = formats.formatter(format) + formatters[rule] = formatter + else + formatter = formatters[rule] + end + msg = formats.format_event(event, rule, levels[level+1], formatter) for index,o in ipairs(outputs) do o.output(level, msg, o.config) end +end + +function output_cleanup() + for rule, formatter in pairs(formatters) do + formats.free_formatter(formatter) + end - formats.free_formatter(formatter) + formatters = {} end function add_output(output_name, config)