Skip to content

Commit

Permalink
Allow outputs to keep file/program open
Browse files Browse the repository at this point in the history
Add the ability to keep file/program outputs open (i.e. writing to the
same open file/program for multiple notifications). A new option to the
file/program output "keep_alive", if true, keeps the file/program pipe
open across events.

This makes the need for unbuffered output aka
#211 more pressing. Will add that next.
  • Loading branch information
mstemm committed Oct 6, 2017
1 parent c3ee6a9 commit 68a83e0
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 7 deletions.
7 changes: 7 additions & 0 deletions falco.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,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:
Expand All @@ -49,6 +54,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
Expand Down
12 changes: 10 additions & 2 deletions userspace/falco/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,17 @@ void falco_configuration::init(string conf_filename, list<string> &cmdline_optio
file_output.name = "file";
if (m_config->get_scalar<bool>("file_output", "enabled", false))
{
string filename;
string filename, keep_alive;
filename = m_config->get_scalar<string>("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<string>("file_output", "keep_alive", "");
file_output.options["keep_alive"] = keep_alive;

m_outputs.push_back(file_output);
}

Expand All @@ -86,13 +90,17 @@ void falco_configuration::init(string conf_filename, list<string> &cmdline_optio
program_output.name = "program";
if (m_config->get_scalar<bool>("program_output", "enabled", false))
{
string program;
string program, keep_alive;
program = m_config->get_scalar<string>("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<string>("program_output", "keep_alive", "");
program_output.options["keep_alive"] = keep_alive;

m_outputs.push_back(program_output);
}

Expand Down
34 changes: 29 additions & 5 deletions userspace/falco/lua/output.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,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
Expand All @@ -42,9 +42,21 @@ function mod.file_validate(options)
end

function mod.file(level, 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(level, msg, options)
Expand All @@ -56,10 +68,22 @@ function mod.program(level, 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

local function level_of(s)
Expand Down

0 comments on commit 68a83e0

Please sign in to comment.