diff --git a/falco.yaml b/falco.yaml index 1000d4fc..64220494 100644 --- a/falco.yaml +++ b/falco.yaml @@ -53,8 +53,13 @@ outputs: syslog_output: enabled: true +# If keep_alive is set to true, the file will be opened once and +# continuously written to, with each output message on its own +# line. If keep_alive is set to false, the file will be re-opened +# for each output message. file_output: enabled: false + keep_alive: false filename: ./events.txt stdout_output: @@ -65,6 +70,8 @@ stdout_output: # program: "jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/XXX" # - logging (alternate method than syslog): # program: logger -t falco-test +# - send over a network connection: +# program: nc host.example.com 80 # If keep_alive is set to true, the program will be started once and # continuously written to, with each output message on its own diff --git a/userspace/falco/configuration.cpp b/userspace/falco/configuration.cpp index 7cfe4a57..6d266311 100644 --- a/userspace/falco/configuration.cpp +++ b/userspace/falco/configuration.cpp @@ -71,13 +71,17 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio file_output.name = "file"; if (m_config->get_scalar("file_output", "enabled", false)) { - string filename; + string filename, keep_alive; filename = m_config->get_scalar("file_output", "filename", ""); if (filename == string("")) { throw invalid_argument("Error reading config file (" + m_config_file + "): file output enabled but no filename in configuration block"); } file_output.options["filename"] = filename; + + keep_alive = m_config->get_scalar("file_output", "keep_alive", ""); + file_output.options["keep_alive"] = keep_alive; + m_outputs.push_back(file_output); } @@ -99,13 +103,17 @@ void falco_configuration::init(string conf_filename, list &cmdline_optio program_output.name = "program"; if (m_config->get_scalar("program_output", "enabled", false)) { - string program; + string program, keep_alive; program = m_config->get_scalar("program_output", "program", ""); if (program == string("")) { throw sinsp_exception("Error reading config file (" + m_config_file + "): program output enabled but no program in configuration block"); } program_output.options["program"] = program; + + keep_alive = m_config->get_scalar("program_output", "keep_alive", ""); + program_output.options["keep_alive"] = keep_alive; + m_outputs.push_back(program_output); } diff --git a/userspace/falco/lua/output.lua b/userspace/falco/lua/output.lua index f4d571f3..b0f5145a 100644 --- a/userspace/falco/lua/output.lua +++ b/userspace/falco/lua/output.lua @@ -29,7 +29,7 @@ function mod.file_validate(options) error("File output needs to be configured with a valid filename") end - file, err = io.open(options.filename, "a+") + local file, err = io.open(options.filename, "a+") if file == nil then error("Error with file output: "..err) end @@ -38,9 +38,21 @@ function mod.file_validate(options) end function mod.file(priority, priority_num, msg, options) - file = io.open(options.filename, "a+") + if options.keep_alive == "true" then + if file == nil then + file = io.open(options.filename, "a+") + end + else + file = io.open(options.filename, "a+") + end + file:write(msg, "\n") - file:close() + + if options.keep_alive == nil or + options.keep_alive ~= "true" then + file:close() + file = nil + end end function mod.syslog(priority, priority_num, msg, options) @@ -52,10 +64,22 @@ function mod.program(priority, priority_num, msg, options) -- successfully. However, the luajit we're using returns true even -- when the shell can't run the program. - file = io.popen(options.program, "w") + -- Note: options are all strings + if options.keep_alive == "true" then + if file == nil then + file = io.popen(options.program, "w") + end + else + file = io.popen(options.program, "w") + end file:write(msg, "\n") - file:close() + + if options.keep_alive == nil or + options.keep_alive ~= "true" then + file:close() + file = nil + end end function output_event(event, rule, priority, priority_num, format)