From d759e3b94225f59bfd6a7ae276b23701dddd79bc Mon Sep 17 00:00:00 2001 From: Henri DF Date: Mon, 22 Feb 2016 16:01:40 -0800 Subject: [PATCH 01/12] Fix macro expansion bug introduced with Rules --- userspace/digwatch/lua/compiler.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/userspace/digwatch/lua/compiler.lua b/userspace/digwatch/lua/compiler.lua index d4ae127a..08e554a0 100644 --- a/userspace/digwatch/lua/compiler.lua +++ b/userspace/digwatch/lua/compiler.lua @@ -336,7 +336,9 @@ end --]] function expand_macros(node, defs, changed) - if node.type == "Filter" then + if (node.type == "Rule") then + macros = expand_macros(node.filter, defs, changed) + elseif node.type == "Filter" then if (node.value.type == "Macro") then if (defs[node.value.value] == nil) then tostring = require 'ml'.tstring @@ -344,6 +346,7 @@ function expand_macros(node, defs, changed) end node.value = defs[node.value.value] changed = true + return changed end return expand_macros(node.value, defs, changed) From 5ba821aaef7d4fb06410e2e0387665105d36e174 Mon Sep 17 00:00:00 2001 From: Henri DF Date: Mon, 22 Feb 2016 16:26:15 -0800 Subject: [PATCH 02/12] Fix handling of nested ASTs --- userspace/digwatch/lua/compiler.lua | 8 ++++---- userspace/digwatch/lua/rule_loader.lua | 8 ++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/userspace/digwatch/lua/compiler.lua b/userspace/digwatch/lua/compiler.lua index 08e554a0..84a1edbf 100644 --- a/userspace/digwatch/lua/compiler.lua +++ b/userspace/digwatch/lua/compiler.lua @@ -472,7 +472,7 @@ end to the line-oriented compiler. --]] function compiler.init() - return {macros={}, ast=nil} + return {macros={}, filter_ast=nil} end --[[ @@ -525,10 +525,10 @@ function compiler.compile_line(line, state) expanded = expand_macros(ast, state.macros, false) until expanded == false - if (state.ast == nil) then - state.ast = ast + if (state.filter_ast == nil) then + state.filter_ast = ast.filter.value else - state.ast = { type = "BinaryBoolOp", operator = "or", left = state.ast, right = ast } + state.filter_ast = { type = "BinaryBoolOp", operator = "or", left = state.filter_ast, right = ast.filter.value } end else error("Unexpected top-level AST type: "..ast.type) diff --git a/userspace/digwatch/lua/rule_loader.lua b/userspace/digwatch/lua/rule_loader.lua index 999823cb..d93361cc 100644 --- a/userspace/digwatch/lua/rule_loader.lua +++ b/userspace/digwatch/lua/rule_loader.lua @@ -10,17 +10,13 @@ local compiler = require "compiler" local function install_filter(node) local t = node.type - if t == "Filter" then - install_filter(node.value) - - elseif t == "BinaryBoolOp" then + if t == "BinaryBoolOp" then filter.nest() --io.write("(") install_filter(node.left) filter.bool_op(node.operator) --io.write(" "..node.operator.." ") install_filter(node.right) filter.unnest() --io.write(")") - elseif t == "UnaryBoolOp" then filter.nest() --io.write("(") filter.bool_op(node.operator) -- io.write(" "..node.operator.." ") @@ -62,5 +58,5 @@ function load_rule(r) end function on_done() - install_filter(state.ast) + install_filter(state.filter_ast) end From 426097241d1b6519af16ffda9e031c8c91b116b4 Mon Sep 17 00:00:00 2001 From: Henri DF Date: Mon, 22 Feb 2016 17:03:34 -0800 Subject: [PATCH 03/12] Move compiler state and AST grafting to rule_loader.lua This is needed so that rule_loader (which should be renamed in a later pass..) can tag filters with their index. --- userspace/digwatch/lua/compiler.lua | 31 +++++--------------------- userspace/digwatch/lua/rule_loader.lua | 28 ++++++++++++++++++++--- userspace/digwatch/lua/test.lua | 9 ++++---- 3 files changed, 36 insertions(+), 32 deletions(-) diff --git a/userspace/digwatch/lua/compiler.lua b/userspace/digwatch/lua/compiler.lua index 84a1edbf..81d0065f 100644 --- a/userspace/digwatch/lua/compiler.lua +++ b/userspace/digwatch/lua/compiler.lua @@ -341,7 +341,6 @@ function expand_macros(node, defs, changed) elseif node.type == "Filter" then if (node.value.type == "Macro") then if (defs[node.value.value] == nil) then - tostring = require 'ml'.tstring error("Undefined macro '".. node.value.value .. "' used in filter.") end node.value = defs[node.value.value] @@ -445,7 +444,7 @@ function print_ast(node, level) elseif t == "MacroDef" then -- don't print for now else - error ("Unexpected type: "..t) + error ("Unexpected type in print_ast: "..t) end end compiler.parser.print_ast = print_ast @@ -463,22 +462,9 @@ end --[[ - Sets up compiler state and returns it. - - This is an opaque blob that is passed into subsequent compiler calls and - should not be modified by the client. - - It holds state such as macro definitions that must be kept across calls - to the line-oriented compiler. + Compiles a single line from a digwatch ruleset and updates the passed-in macros table. Returns the AST of the line. --]] -function compiler.init() - return {macros={}, filter_ast=nil} -end - ---[[ - Compiles a single line from a digwatch ruleset and updates the passed-in state object. Returns the AST of the line. ---]] -function compiler.compile_line(line, state) +function compiler.compile_line(line, macro_defs) local ast, error_msg = compiler.parser.parse_line(line) if (error_msg) then @@ -504,7 +490,7 @@ function compiler.compile_line(line, state) end for m, _ in pairs(macros) do - if state.macros[m] == nil then + if macros[m] == nil then error ("Undefined macro '"..m.."' used in '"..line.."'") end end @@ -512,7 +498,7 @@ function compiler.compile_line(line, state) if (ast.type == "MacroDef") then -- Parsed line is a macro definition, so update our dictionary of macros and -- return - state.macros[ast.name] = ast.value + macro_defs[ast.name] = ast.value return ast elseif (ast.type == "Rule") then @@ -522,14 +508,9 @@ function compiler.compile_line(line, state) expand_in(ast.filter) repeat - expanded = expand_macros(ast, state.macros, false) + expanded = expand_macros(ast, macro_defs, false) until expanded == false - if (state.filter_ast == nil) then - state.filter_ast = ast.filter.value - else - state.filter_ast = { type = "BinaryBoolOp", operator = "or", left = state.filter_ast, right = ast.filter.value } - end else error("Unexpected top-level AST type: "..ast.type) end diff --git a/userspace/digwatch/lua/rule_loader.lua b/userspace/digwatch/lua/rule_loader.lua index d93361cc..284c1be0 100644 --- a/userspace/digwatch/lua/rule_loader.lua +++ b/userspace/digwatch/lua/rule_loader.lua @@ -32,7 +32,7 @@ local function install_filter(node) --io.write(node.argument.value.." "..node.operator) else - error ("Unexpected type: "..t) + error ("Unexpected type in install_filter: "..t) end end @@ -49,12 +49,34 @@ end local state +--[[ + Sets up compiler state and returns it. + + It holds state such as macro definitions that must be kept across calls + to the line-oriented compiler. +--]] +local function init() + return {macros={}, filter_ast=nil} +end + function load_rule(r) if (state == nil) then - state = compiler.init() + state = init() + end + local line_ast = compiler.compile_line(r, state.macros) + + if (line_ast.type == "MacroDef") then + return + elseif (not (line_ast.type == "Rule")) then + error ("Unexpected type in load_rule: "..line_ast.type) + end + + if (state.filter_ast == nil) then + state.filter_ast = line_ast.filter.value + else + state.filter_ast = { type = "BinaryBoolOp", operator = "or", left = state.filter_ast, right = line_ast.filter.value } end - compiler.compile_line(r, state) end function on_done() diff --git a/userspace/digwatch/lua/test.lua b/userspace/digwatch/lua/test.lua index e6c0dc47..03a716c9 100644 --- a/userspace/digwatch/lua/test.lua +++ b/userspace/digwatch/lua/test.lua @@ -5,10 +5,11 @@ if #arg ~= 1 then os.exit(1) end -local state = compiler.init() +local macros = {} +local ast local function doit(line) - local ast = compiler.compile_line(line, state) + ast = compiler.compile_line(line, macros) if not ast then print("error", error_msg) @@ -20,8 +21,8 @@ for str in string.gmatch(arg[1], "([^;]+)") do doit(str) end -if not (state.ast == nil) then -- can be nil if only macros - compiler.parser.print_ast(state.ast) +if not (ast) then + compiler.parser.print_ast(ast) end os.exit(0) From a7d013215448fe3df9e0988a68a4c984bfe74b37 Mon Sep 17 00:00:00 2001 From: Henri DF Date: Mon, 22 Feb 2016 18:20:55 -0800 Subject: [PATCH 04/12] Add 'sysdig.set_formatter' and use it in compiler This allows the compiler to define per-rule formats. They are currently instantiated and stored on the c++ side, but not being made use of yet. --- userspace/digwatch/lua/rule_loader.lua | 9 ++++-- userspace/digwatch/rules.cpp | 41 +++++++++++++++++++++++++- userspace/digwatch/rules.h | 6 ++++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/userspace/digwatch/lua/rule_loader.lua b/userspace/digwatch/lua/rule_loader.lua index 284c1be0..f1132d87 100644 --- a/userspace/digwatch/lua/rule_loader.lua +++ b/userspace/digwatch/lua/rule_loader.lua @@ -56,7 +56,7 @@ local state to the line-oriented compiler. --]] local function init() - return {macros={}, filter_ast=nil} + return {macros={}, filter_ast=nil, n_rules=0} end @@ -66,12 +66,17 @@ function load_rule(r) end local line_ast = compiler.compile_line(r, state.macros) - if (line_ast.type == "MacroDef") then + if (line_ast.type == nil) then -- blank line + return + elseif (line_ast.type == "MacroDef") then return elseif (not (line_ast.type == "Rule")) then error ("Unexpected type in load_rule: "..line_ast.type) end + digwatch.set_formatter(state.n_rules, line_ast.output.value) + state.n_rules = state.n_rules + 1 + if (state.filter_ast == nil) then state.filter_ast = line_ast.filter.value else diff --git a/userspace/digwatch/rules.cpp b/userspace/digwatch/rules.cpp index d8c3ecac..39f883ce 100644 --- a/userspace/digwatch/rules.cpp +++ b/userspace/digwatch/rules.cpp @@ -6,18 +6,57 @@ extern "C" { #include "lauxlib.h" } +std::map g_format_map; +sinsp* g_inspector; + +const static struct luaL_reg ll_digwatch [] = +{ + {"set_formatter", &digwatch_rules::set_formatter}, + {NULL,NULL} +}; + digwatch_rules::digwatch_rules(sinsp* inspector, string lua_main_filename, string lua_dir) { + g_inspector = inspector; + // Initialize Lua interpreter m_ls = lua_open(); luaL_openlibs(m_ls); m_lua_parser = new lua_parser(inspector, m_ls); + luaL_openlib(m_ls, "digwatch", ll_digwatch, 0); + add_lua_path(lua_dir); load_compiler(lua_main_filename); } +int digwatch_rules::set_formatter (lua_State *ls) { + uint32_t index = luaL_checkinteger(ls, 1); + string format = luaL_checkstring(ls, 2); + + try + { + if(format == "" || format == "default") + { + 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) + { + string err = "invalid output format " + format; + fprintf(stderr, "%s\n", err.c_str()); + throw sinsp_exception("set_formatter error"); + } + + return 0; +} + + void digwatch_rules::add_lua_path(string path) { path += "?.lua"; @@ -84,7 +123,7 @@ void digwatch_rules::load_rules(string rules_filename) if(lua_pcall(m_ls, 1, 0, 0) != 0) { const char* lerr = lua_tostring(m_ls, -1); - string err = "Error loading rule: " + string(lerr); + string err = "Error loading rule '" + line + "':" + string(lerr); throw sinsp_exception(err); } } diff --git a/userspace/digwatch/rules.h b/userspace/digwatch/rules.h index c46ea97f..7f007152 100644 --- a/userspace/digwatch/rules.h +++ b/userspace/digwatch/rules.h @@ -3,6 +3,8 @@ #include "sinsp.h" #include "lua_parser.h" +class sinsp_evt_formatter; + class digwatch_rules { public: @@ -11,12 +13,16 @@ class digwatch_rules void load_rules(string rules_filename); sinsp_filter* get_filter(); + // set_formatter(index, format_string) + static int set_formatter(lua_State *ls); private: void add_lua_path(string path); void load_compiler(string lua_main_filename); lua_parser* m_lua_parser; lua_State* m_ls; + string m_lua_load_rule = "load_rule"; string m_lua_on_done = "on_done"; + string m_lua_on_event = "on_event"; }; From 3a56c1a0e4f3bb33a4370cc60a1b5ef45250d5dd Mon Sep 17 00:00:00 2001 From: Henri DF Date: Mon, 22 Feb 2016 18:55:11 -0800 Subject: [PATCH 05/12] AST: Rule node always has an Output child node --- userspace/digwatch/lua/compiler.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/userspace/digwatch/lua/compiler.lua b/userspace/digwatch/lua/compiler.lua index 81d0065f..2a587f7a 100644 --- a/userspace/digwatch/lua/compiler.lua +++ b/userspace/digwatch/lua/compiler.lua @@ -168,6 +168,9 @@ local function outputformat (format) end local function rule(filter, output) + if not output then + output = outputformat("") + end return {type = "Rule", filter = filter, output = output} end From 406f079621b9f4ad55ab080def2d051038a0125e Mon Sep 17 00:00:00 2001 From: Henri DF Date: Mon, 22 Feb 2016 20:27:57 -0800 Subject: [PATCH 06/12] Deep copy macro ASTs when expanding So that we can individually tag expressions that originate from the same macro (see next commit). --- userspace/digwatch/lua/compiler.lua | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/userspace/digwatch/lua/compiler.lua b/userspace/digwatch/lua/compiler.lua index 2a587f7a..b562e269 100644 --- a/userspace/digwatch/lua/compiler.lua +++ b/userspace/digwatch/lua/compiler.lua @@ -339,6 +339,14 @@ end --]] function expand_macros(node, defs, changed) + + function copy(obj) + if type(obj) ~= 'table' then return obj end + local res = {} + for k, v in pairs(obj) do res[copy(k)] = copy(v) end + return res + end + if (node.type == "Rule") then macros = expand_macros(node.filter, defs, changed) elseif node.type == "Filter" then @@ -346,7 +354,7 @@ function expand_macros(node, defs, changed) if (defs[node.value.value] == nil) then error("Undefined macro '".. node.value.value .. "' used in filter.") end - node.value = defs[node.value.value] + node.value = copy(defs[node.value.value]) changed = true return changed end @@ -358,7 +366,7 @@ function expand_macros(node, defs, changed) if (defs[node.left.value] == nil) then error("Undefined macro '".. node.left.value .. "' used in filter.") end - node.left = defs[node.left.value] + node.left = copy(defs[node.left.value]) changed = true end @@ -366,7 +374,7 @@ function expand_macros(node, defs, changed) if (defs[node.right.value] == nil) then error("Undefined macro ".. node.right.value .. "used in filter.") end - node.right = defs[node.right.value] + node.right = copy(defs[node.right.value]) changed = true end @@ -379,7 +387,7 @@ function expand_macros(node, defs, changed) if (defs[node.argument.value] == nil) then error("Undefined macro ".. node.argument.value .. "used in filter.") end - node.argument = defs[node.argument.value] + node.argument = copy(defs[node.argument.value]) changed = true end return expand_macros(node.argument, defs, changed) From a3976281a8f2a139069dc95233c8db009bfdcb66 Mon Sep 17 00:00:00 2001 From: Henri DF Date: Mon, 22 Feb 2016 19:08:44 -0800 Subject: [PATCH 07/12] Pass rule indices down into filters This allows to match events back up with the display output they are associated with. --- userspace/digwatch/lua/rule_loader.lua | 27 ++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/userspace/digwatch/lua/rule_loader.lua b/userspace/digwatch/lua/rule_loader.lua index f1132d87..ec0a1aac 100644 --- a/userspace/digwatch/lua/rule_loader.lua +++ b/userspace/digwatch/lua/rule_loader.lua @@ -7,6 +7,27 @@ local compiler = require "compiler" +local function mark_check_nodes(ast, index) + local t = ast.type + + if t == "BinaryBoolOp" then + mark_check_nodes(ast.left, index) + mark_check_nodes(ast.right, index) + + elseif t == "UnaryBoolOp" then + mark_check_nodes(ast.argument, index) + + elseif t == "BinaryRelOp" then + ast.index = index + + elseif t == "UnaryRelOp" then + ast.index = index + + else + error ("Unexpected type in install_filter: "..t) + end +end + local function install_filter(node) local t = node.type @@ -24,11 +45,11 @@ local function install_filter(node) filter.unnest() -- io.write(")") elseif t == "BinaryRelOp" then - filter.rel_expr(node.left.value, node.operator, node.right.value) + filter.rel_expr(node.left.value, node.operator, node.right.value, node.index) -- io.write(node.left.value.." "..node.operator.." "..node.right.value) elseif t == "UnaryRelOp" then - filter.rel_expr(node.argument.value, node.operator) + filter.rel_expr(node.argument.value, node.operator, node.index) --io.write(node.argument.value.." "..node.operator) else @@ -75,6 +96,8 @@ function load_rule(r) end digwatch.set_formatter(state.n_rules, line_ast.output.value) + mark_check_nodes(line_ast.filter.value, state.n_rules) + state.n_rules = state.n_rules + 1 if (state.filter_ast == nil) then From 87186df85ae800ed21343d648d01f55047ca95f9 Mon Sep 17 00:00:00 2001 From: Henri DF Date: Tue, 23 Feb 2016 10:21:25 -0800 Subject: [PATCH 08/12] digwatch: use appropriate formatter for each event --- userspace/digwatch/digwatch.cpp | 21 +++++++++++---------- userspace/digwatch/rules.cpp | 4 ++++ userspace/digwatch/rules.h | 2 ++ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/userspace/digwatch/digwatch.cpp b/userspace/digwatch/digwatch.cpp index 0cc6f40b..469f9bc6 100644 --- a/userspace/digwatch/digwatch.cpp +++ b/userspace/digwatch/digwatch.cpp @@ -28,7 +28,7 @@ extern "C" { static void usage() { printf( - "Usage: digwatch [options] [-p ] rules_filename\n\n" + "Usage: digwatch [options] rules_filename\n\n" "Options:\n" " -h, --help Print this page\n" " -m , --main-lua \n" @@ -55,13 +55,14 @@ static void usage() captureinfo do_inspect(sinsp* inspector, uint64_t cnt, int duration_to_tot, - sinsp_evt_formatter* formatter) + digwatch_rules* rules) { captureinfo retval; int32_t res; sinsp_evt* ev; string line; int duration_start = 0; + sinsp_evt_formatter* formatter; // // Loop through the events @@ -113,6 +114,13 @@ captureinfo do_inspect(sinsp* inspector, { continue; } + + formatter = rules->lookup_formatter(ev->get_check_id()); + if (!formatter) + { + throw sinsp_exception("Error: No formatter for event with id %d " + to_string(ev->get_check_id())); + } + if(formatter->tostring(ev, &line)) { cout << line; @@ -137,7 +145,6 @@ int digwatch_init(int argc, char **argv) sinsp_evt::param_fmt event_buffer_format = sinsp_evt::PF_NORMAL; int duration_to_tot = 0; captureinfo cinfo; - string output_format; int long_index = 0; string lua_main_filename; string lua_dir = DIGWATCH_INSTALLATION_DIR; @@ -152,8 +159,6 @@ int digwatch_init(int argc, char **argv) {0, 0, 0, 0} }; - output_format = "*%evt.num %evt.outputtime %evt.cpu %proc.name (%thread.tid) %evt.dir %evt.type %evt.info"; - try { inspector = new sinsp(); @@ -240,10 +245,6 @@ int digwatch_init(int argc, char **argv) } // - // Create the event formatter - // - sinsp_evt_formatter formatter(inspector, output_format); - char* env_lua_dir = getenv("DIGWATCH_LUA_DIR"); if (env_lua_dir) { @@ -265,7 +266,7 @@ int digwatch_init(int argc, char **argv) cinfo = do_inspect(inspector, cnt, duration_to_tot, - &formatter); + rules); inspector->close(); } diff --git a/userspace/digwatch/rules.cpp b/userspace/digwatch/rules.cpp index 39f883ce..4bbe9088 100644 --- a/userspace/digwatch/rules.cpp +++ b/userspace/digwatch/rules.cpp @@ -56,6 +56,10 @@ int digwatch_rules::set_formatter (lua_State *ls) { return 0; } +sinsp_evt_formatter* digwatch_rules::lookup_formatter(uint32_t index) +{ + return g_format_map[index]; +} void digwatch_rules::add_lua_path(string path) { diff --git a/userspace/digwatch/rules.h b/userspace/digwatch/rules.h index 7f007152..bdec045a 100644 --- a/userspace/digwatch/rules.h +++ b/userspace/digwatch/rules.h @@ -15,6 +15,8 @@ class digwatch_rules // set_formatter(index, format_string) static int set_formatter(lua_State *ls); + sinsp_evt_formatter* lookup_formatter(uint32_t index); + private: void add_lua_path(string path); void load_compiler(string lua_main_filename); From 2f105932fa3302d18f871f40c3bc6a1d0ed84f0b Mon Sep 17 00:00:00 2001 From: Henri DF Date: Tue, 23 Feb 2016 11:35:11 -0800 Subject: [PATCH 09/12] parser-smoke.sh: add a test --- userspace/digwatch/lua/parser-smoke.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/userspace/digwatch/lua/parser-smoke.sh b/userspace/digwatch/lua/parser-smoke.sh index 72326712..ae8e762b 100755 --- a/userspace/digwatch/lua/parser-smoke.sh +++ b/userspace/digwatch/lua/parser-smoke.sh @@ -38,6 +38,7 @@ good "not (not (a))" good "not (a.b=1)" good "not (a.a exists)" good "not a" +good "a.b = 1 and not a" good "not not a" good "(not not a)" good "not a.b=1" From 3e73f01472131f51901bcbeaded03f4cca14d030 Mon Sep 17 00:00:00 2001 From: Henri DF Date: Tue, 23 Feb 2016 18:15:43 -0800 Subject: [PATCH 10/12] Always print events Before this change, events were only printed if they had all the fields (same behavior as with sysdig when the output format doesn't have a leading "*"). With this change, all events are printed; those that don't have all fields are prefixed with a notification. --- userspace/digwatch/digwatch.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/userspace/digwatch/digwatch.cpp b/userspace/digwatch/digwatch.cpp index 469f9bc6..24a5a887 100644 --- a/userspace/digwatch/digwatch.cpp +++ b/userspace/digwatch/digwatch.cpp @@ -121,11 +121,13 @@ captureinfo do_inspect(sinsp* inspector, throw sinsp_exception("Error: No formatter for event with id %d " + to_string(ev->get_check_id())); } - if(formatter->tostring(ev, &line)) - { - cout << line; - cout << endl; + bool has_all = formatter->tostring(ev, &line); + if (!has_all) { + cout << "(missing fields) "; } + cout << line; + cout << endl; + } From 636429c674e7c216c3de05d250b8b7def7d0e39f Mon Sep 17 00:00:00 2001 From: Henri DF Date: Tue, 23 Feb 2016 18:18:43 -0800 Subject: [PATCH 11/12] Move lua_State creation to digwatch main --- userspace/digwatch/digwatch.cpp | 8 +++++++- userspace/digwatch/rules.cpp | 6 ++---- userspace/digwatch/rules.h | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/userspace/digwatch/digwatch.cpp b/userspace/digwatch/digwatch.cpp index 24a5a887..d58c522a 100644 --- a/userspace/digwatch/digwatch.cpp +++ b/userspace/digwatch/digwatch.cpp @@ -150,6 +150,7 @@ int digwatch_init(int argc, char **argv) int long_index = 0; string lua_main_filename; string lua_dir = DIGWATCH_INSTALLATION_DIR; + lua_State* ls; static struct option long_options[] = { @@ -259,7 +260,11 @@ int digwatch_init(int argc, char **argv) lua_main_filename = lua_dir + DIGWATCH_LUA_MAIN; } - rules = new digwatch_rules(inspector, lua_main_filename, lua_dir); + // Initialize Lua interpreter + ls = lua_open(); + luaL_openlibs(ls); + + rules = new digwatch_rules(inspector, ls, lua_main_filename, lua_dir); rules->load_rules(rules_file); inspector->set_filter(rules->get_filter()); @@ -290,6 +295,7 @@ exit: delete inspector; } + lua_close(ls); return result; } diff --git a/userspace/digwatch/rules.cpp b/userspace/digwatch/rules.cpp index 4bbe9088..0b50c9ef 100644 --- a/userspace/digwatch/rules.cpp +++ b/userspace/digwatch/rules.cpp @@ -15,13 +15,11 @@ const static struct luaL_reg ll_digwatch [] = {NULL,NULL} }; -digwatch_rules::digwatch_rules(sinsp* inspector, string lua_main_filename, string lua_dir) +digwatch_rules::digwatch_rules(sinsp* inspector, lua_State *ls, string lua_main_filename, string lua_dir) { g_inspector = inspector; - // Initialize Lua interpreter - m_ls = lua_open(); - luaL_openlibs(m_ls); + m_ls = ls; m_lua_parser = new lua_parser(inspector, m_ls); diff --git a/userspace/digwatch/rules.h b/userspace/digwatch/rules.h index bdec045a..60b15e81 100644 --- a/userspace/digwatch/rules.h +++ b/userspace/digwatch/rules.h @@ -8,7 +8,7 @@ class sinsp_evt_formatter; class digwatch_rules { public: - digwatch_rules(sinsp* inspector, string lua_main_filename, string lua_dir); + digwatch_rules(sinsp* inspector, lua_State *ls, string lua_main_filename, string lua_dir); ~digwatch_rules(); void load_rules(string rules_filename); sinsp_filter* get_filter(); From a9d0268390ff96d01e5701ce5674df58a774bfc6 Mon Sep 17 00:00:00 2001 From: Henri DF Date: Tue, 23 Feb 2016 18:55:20 -0800 Subject: [PATCH 12/12] Move format handling into own class --- userspace/digwatch/CMakeLists.txt | 2 +- userspace/digwatch/digwatch.cpp | 11 ++++-- userspace/digwatch/formats.cpp | 57 +++++++++++++++++++++++++++++++ userspace/digwatch/formats.h | 19 +++++++++++ userspace/digwatch/rules.cpp | 42 ----------------------- userspace/digwatch/rules.h | 6 ---- 6 files changed, 85 insertions(+), 52 deletions(-) create mode 100644 userspace/digwatch/formats.cpp create mode 100644 userspace/digwatch/formats.h diff --git a/userspace/digwatch/CMakeLists.txt b/userspace/digwatch/CMakeLists.txt index 09d3655d..4b679be0 100644 --- a/userspace/digwatch/CMakeLists.txt +++ b/userspace/digwatch/CMakeLists.txt @@ -10,7 +10,7 @@ include_directories(${PROJECT_SOURCE_DIR}/../sysdig/userspace/libscap) include_directories(${PROJECT_SOURCE_DIR}/../sysdig/userspace/libsinsp) include_directories("${PROJECT_BINARY_DIR}/userspace/digwatch") -add_executable(digwatch rules.cpp digwatch.cpp) +add_executable(digwatch formats.cpp rules.cpp digwatch.cpp) target_link_libraries(digwatch sinsp) diff --git a/userspace/digwatch/digwatch.cpp b/userspace/digwatch/digwatch.cpp index d58c522a..88f3b7d6 100644 --- a/userspace/digwatch/digwatch.cpp +++ b/userspace/digwatch/digwatch.cpp @@ -18,6 +18,7 @@ extern "C" { #include #include #include "rules.h" +#include "formats.h" #include "digwatch.h" #include "utils.h" @@ -55,7 +56,8 @@ static void usage() captureinfo do_inspect(sinsp* inspector, uint64_t cnt, int duration_to_tot, - digwatch_rules* rules) + digwatch_rules* rules, + digwatch_formats* formats) { captureinfo retval; int32_t res; @@ -115,7 +117,7 @@ captureinfo do_inspect(sinsp* inspector, continue; } - formatter = rules->lookup_formatter(ev->get_check_id()); + formatter = formats->lookup_formatter(ev->get_check_id()); if (!formatter) { throw sinsp_exception("Error: No formatter for event with id %d " + to_string(ev->get_check_id())); @@ -142,6 +144,7 @@ int digwatch_init(int argc, char **argv) int result; sinsp* inspector = NULL; digwatch_rules* rules = NULL; + digwatch_formats* formats = NULL; int op; uint64_t cnt = -1; sinsp_evt::param_fmt event_buffer_format = sinsp_evt::PF_NORMAL; @@ -265,6 +268,7 @@ int digwatch_init(int argc, char **argv) luaL_openlibs(ls); rules = new digwatch_rules(inspector, ls, lua_main_filename, lua_dir); + formats = new digwatch_formats(inspector, ls); rules->load_rules(rules_file); inspector->set_filter(rules->get_filter()); @@ -273,7 +277,8 @@ int digwatch_init(int argc, char **argv) cinfo = do_inspect(inspector, cnt, duration_to_tot, - rules); + rules, + formats); inspector->close(); } diff --git a/userspace/digwatch/formats.cpp b/userspace/digwatch/formats.cpp new file mode 100644 index 00000000..531c54e5 --- /dev/null +++ b/userspace/digwatch/formats.cpp @@ -0,0 +1,57 @@ +#include "formats.h" + +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} + +std::map g_format_map; +sinsp* g_inspector; + +const static struct luaL_reg ll_digwatch [] = +{ + {"set_formatter", &digwatch_formats::set_formatter}, + {NULL,NULL} +}; + +digwatch_formats::digwatch_formats(sinsp* inspector, lua_State *ls) +{ + g_inspector = inspector; + + m_ls = ls; + + luaL_openlib(m_ls, "digwatch", ll_digwatch, 0); +} + +int digwatch_formats::set_formatter (lua_State *ls) { + uint32_t index = luaL_checkinteger(ls, 1); + string format = luaL_checkstring(ls, 2); + + try + { + if(format == "" || format == "default") + { + 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) + { + string err = "invalid output format " + format; + fprintf(stderr, "%s\n", err.c_str()); + throw sinsp_exception("set_formatter error"); + } + + return 0; +} + +sinsp_evt_formatter* digwatch_formats::lookup_formatter(uint32_t index) +{ + return g_format_map[index]; +} + + diff --git a/userspace/digwatch/formats.h b/userspace/digwatch/formats.h new file mode 100644 index 00000000..7cb84c61 --- /dev/null +++ b/userspace/digwatch/formats.h @@ -0,0 +1,19 @@ +#pragma once + +#include "sinsp.h" +#include "lua_parser.h" + +class sinsp_evt_formatter; + +class digwatch_formats +{ + public: + digwatch_formats(sinsp* inspector, lua_State *ls); + + // set_formatter(index, format_string) + static int set_formatter(lua_State *ls); + sinsp_evt_formatter* lookup_formatter(uint32_t index); + + private: + lua_State* m_ls; +}; diff --git a/userspace/digwatch/rules.cpp b/userspace/digwatch/rules.cpp index 0b50c9ef..97fcda16 100644 --- a/userspace/digwatch/rules.cpp +++ b/userspace/digwatch/rules.cpp @@ -6,59 +6,17 @@ extern "C" { #include "lauxlib.h" } -std::map g_format_map; -sinsp* g_inspector; - -const static struct luaL_reg ll_digwatch [] = -{ - {"set_formatter", &digwatch_rules::set_formatter}, - {NULL,NULL} -}; digwatch_rules::digwatch_rules(sinsp* inspector, lua_State *ls, string lua_main_filename, string lua_dir) { - g_inspector = inspector; - m_ls = ls; m_lua_parser = new lua_parser(inspector, m_ls); - luaL_openlib(m_ls, "digwatch", ll_digwatch, 0); - add_lua_path(lua_dir); load_compiler(lua_main_filename); } -int digwatch_rules::set_formatter (lua_State *ls) { - uint32_t index = luaL_checkinteger(ls, 1); - string format = luaL_checkstring(ls, 2); - - try - { - if(format == "" || format == "default") - { - 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) - { - string err = "invalid output format " + format; - fprintf(stderr, "%s\n", err.c_str()); - throw sinsp_exception("set_formatter error"); - } - - return 0; -} - -sinsp_evt_formatter* digwatch_rules::lookup_formatter(uint32_t index) -{ - return g_format_map[index]; -} - void digwatch_rules::add_lua_path(string path) { path += "?.lua"; diff --git a/userspace/digwatch/rules.h b/userspace/digwatch/rules.h index 60b15e81..91e7adb2 100644 --- a/userspace/digwatch/rules.h +++ b/userspace/digwatch/rules.h @@ -3,8 +3,6 @@ #include "sinsp.h" #include "lua_parser.h" -class sinsp_evt_formatter; - class digwatch_rules { public: @@ -13,10 +11,6 @@ class digwatch_rules void load_rules(string rules_filename); sinsp_filter* get_filter(); - // set_formatter(index, format_string) - static int set_formatter(lua_State *ls); - sinsp_evt_formatter* lookup_formatter(uint32_t index); - private: void add_lua_path(string path); void load_compiler(string lua_main_filename);