Merge pull request #6 from draios/cleanups

Cleanups
This commit is contained in:
Henri DF 2016-02-24 10:33:11 -08:00
commit ffac848c89
5 changed files with 100 additions and 181 deletions

View File

@ -19,7 +19,6 @@ extern "C" {
#include <config_digwatch.h>
#include "rules.h"
#include "formats.h"
#include "digwatch.h"
#include "utils.h"
@ -35,10 +34,7 @@ static void usage()
" -m <filename>, --main-lua <filename>\n"
" Name of lua compiler main file\n"
" (default: rules_loader.lua)\n"
" -M <num_seconds> Stop collecting after <num_seconds> reached.\n"
" -N Don't convert port numbers to names.\n"
" -n <num>, --numevents=<num>\n"
" Stop capturing after <num> events\n"
" -r <readfile>, --read=<readfile>\n"
" Read the events from <readfile>.\n"
" --unbuffered Turn off output buffering. This causes every single line\n"
@ -53,42 +49,20 @@ static void usage()
//
// Event processing loop
//
captureinfo do_inspect(sinsp* inspector,
uint64_t cnt,
int duration_to_tot,
void do_inspect(sinsp* inspector,
digwatch_rules* rules,
digwatch_formats* formats)
{
captureinfo retval;
int32_t res;
sinsp_evt* ev;
string line;
int duration_start = 0;
sinsp_evt_formatter* formatter;
//
// Loop through the events
//
duration_start = ((double)clock()) / CLOCKS_PER_SEC;
while(1)
{
if(duration_to_tot > 0)
{
int duration_tot = ((double)clock()) / CLOCKS_PER_SEC - duration_start;
if(duration_tot >= duration_to_tot)
{
break;
}
}
if(retval.m_nevts == cnt)
{
//
// End of capture, either because the user stopped it, or because
// we reached the event count specified with -n.
//
break;
}
res = inspector->next(&ev);
if(res == SCAP_TIMEOUT)
@ -109,8 +83,6 @@ captureinfo do_inspect(sinsp* inspector,
throw sinsp_exception(inspector->getlasterr().c_str());
}
retval.m_nevts++;
if(!inspector->is_debug_enabled() &&
ev->get_category() & EC_INTERNAL)
{
@ -132,8 +104,6 @@ captureinfo do_inspect(sinsp* inspector,
}
return retval;
}
//
@ -146,10 +116,7 @@ int digwatch_init(int argc, char **argv)
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;
int duration_to_tot = 0;
captureinfo cinfo;
int long_index = 0;
string lua_main_filename;
string lua_dir = DIGWATCH_INSTALLATION_DIR;
@ -158,7 +125,6 @@ int digwatch_init(int argc, char **argv)
static struct option long_options[] =
{
{"help", no_argument, 0, 'h' },
{"numevents", required_argument, 0, 'n' },
{"main-lua", required_argument, 0, 'u' },
{"readfile", required_argument, 0, 'r' },
{"unbuffered", no_argument, 0, 0 },
@ -174,7 +140,7 @@ int digwatch_init(int argc, char **argv)
// Parse the args
//
while((op = getopt_long(argc, argv,
"hm:M:Nn:r:",
"hm:Nr:",
long_options, &long_index)) != -1)
{
switch(op)
@ -186,31 +152,9 @@ int digwatch_init(int argc, char **argv)
case 'm':
lua_main_filename = optarg;
break;
case 'M':
duration_to_tot = atoi(optarg);
if(duration_to_tot <= 0)
{
throw sinsp_exception(string("invalid duration") + optarg);
}
break;
case 'N':
inspector->set_hostname_and_port_resolution_mode(false);
break;
case 'n':
try
{
cnt = sinsp_numparser::parseu64(optarg);
}
catch(...)
{
throw sinsp_exception("can't parse the -n argument, make sure it's a number");
}
if(cnt <= 0)
{
throw sinsp_exception(string("invalid event count ") + optarg);
}
break;
case '?':
result = EXIT_FAILURE;
goto exit;
@ -274,9 +218,7 @@ int digwatch_init(int argc, char **argv)
inspector->set_filter(rules->get_filter());
inspector->open("");
cinfo = do_inspect(inspector,
cnt,
duration_to_tot,
do_inspect(inspector,
rules,
formats);

View File

@ -1,41 +0,0 @@
/*
Copyright (C) 2013-2014 Draios inc.
This file is part of sysdig.
sysdig is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
sysdig is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with sysdig. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifdef HAS_CAPTURE
#include "../../driver/driver_config.h"
#endif // HAS_CAPTURE
//
// Capture results
//
class captureinfo
{
public:
captureinfo()
{
m_nevts = 0;
m_time = 0;
}
uint64_t m_nevts;
uint64_t m_time;
};

View File

@ -338,7 +338,7 @@ end
definition uses another macro).
--]]
function expand_macros(node, defs, changed)
function expand_macros(ast, defs, changed)
function copy(obj)
if type(obj) ~= 'table' then return obj end
@ -347,110 +347,127 @@ function expand_macros(node, defs, changed)
return res
end
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
error("Undefined macro '".. node.value.value .. "' used in filter.")
if (ast.type == "Rule") then
macros = expand_macros(ast.filter, defs, changed)
elseif ast.type == "Filter" then
if (ast.value.type == "Macro") then
if (defs[ast.value.value] == nil) then
error("Undefined macro '".. ast.value.value .. "' used in filter.")
end
node.value = copy(defs[node.value.value])
ast.value = copy(defs[ast.value.value])
changed = true
return changed
end
return expand_macros(node.value, defs, changed)
return expand_macros(ast.value, defs, changed)
elseif node.type == "BinaryBoolOp" then
elseif ast.type == "BinaryBoolOp" then
if (node.left.type == "Macro") then
if (defs[node.left.value] == nil) then
error("Undefined macro '".. node.left.value .. "' used in filter.")
if (ast.left.type == "Macro") then
if (defs[ast.left.value] == nil) then
error("Undefined macro '".. ast.left.value .. "' used in filter.")
end
node.left = copy(defs[node.left.value])
ast.left = copy(defs[ast.left.value])
changed = true
end
if (node.right.type == "Macro") then
if (defs[node.right.value] == nil) then
error("Undefined macro ".. node.right.value .. "used in filter.")
if (ast.right.type == "Macro") then
if (defs[ast.right.value] == nil) then
error("Undefined macro ".. ast.right.value .. "used in filter.")
end
node.right = copy(defs[node.right.value])
ast.right = copy(defs[ast.right.value])
changed = true
end
local changed_left = expand_macros(node.left, defs, false)
local changed_right = expand_macros(node.right, defs, false)
local changed_left = expand_macros(ast.left, defs, false)
local changed_right = expand_macros(ast.right, defs, false)
return changed or changed_left or changed_right
elseif node.type == "UnaryBoolOp" then
if (node.argument.type == "Macro") then
if (defs[node.argument.value] == nil) then
error("Undefined macro ".. node.argument.value .. "used in filter.")
elseif ast.type == "UnaryBoolOp" then
if (ast.argument.type == "Macro") then
if (defs[ast.argument.value] == nil) then
error("Undefined macro ".. ast.argument.value .. "used in filter.")
end
node.argument = copy(defs[node.argument.value])
ast.argument = copy(defs[ast.argument.value])
changed = true
end
return expand_macros(node.argument, defs, changed)
return expand_macros(ast.argument, defs, changed)
end
return changed
end
function get_macros(node, set)
if (node.type == "Macro") then
set[node.value] = true
function get_macros(ast, set)
if (ast.type == "Macro") then
set[ast.value] = true
return set
end
if node.type == "Filter" then
return get_macros(node.value, set)
if ast.type == "Filter" then
return get_macros(ast.value, set)
end
if node.type == "BinaryBoolOp" then
local left = get_macros(node.left, {})
local right = get_macros(node.right, {})
if ast.type == "BinaryBoolOp" then
local left = get_macros(ast.left, {})
local right = get_macros(ast.right, {})
for m, _ in pairs(left) do set[m] = true end
for m, _ in pairs(right) do set[m] = true end
return set
end
if node.type == "UnaryBoolOp" then
return get_macros(node.argument, set)
if ast.type == "UnaryBoolOp" then
return get_macros(ast.argument, set)
end
return set
end
function print_ast(node, level)
local t = node.type
function check_macros(ast)
local macros
if (ast.type == "Rule") then
macros = get_macros(ast.filter, {})
elseif (ast.type == "MacroDef") then
macros = get_macros(ast.value, {})
else
error ("Unexpected type: "..t)
end
for m, _ in pairs(macros) do
if macros[m] == nil then
error ("Undefined macro '"..m.."' used in '"..line.."'")
end
end
end
function print_ast(ast, level)
local t = ast.type
level = level or 0
local prefix = string.rep(" ", level*2)
level = level + 1
if t == "Rule" then
print_ast(node.filter, level)
if (node.output) then
print(prefix.."| "..node.output.value)
print_ast(ast.filter, level)
if (ast.output) then
print(prefix.."| "..ast.output.value)
end
elseif t == "Filter" then
print_ast(node.value, level)
print_ast(ast.value, level)
elseif t == "BinaryBoolOp" or t == "BinaryRelOp" then
print(prefix..node.operator)
print_ast(node.left, level)
print_ast(node.right, level)
print(prefix..ast.operator)
print_ast(ast.left, level)
print_ast(ast.right, level)
elseif t == "UnaryRelOp" or t == "UnaryBoolOp" then
print (prefix..node.operator)
print_ast(node.argument, level)
print (prefix..ast.operator)
print_ast(ast.argument, level)
elseif t == "List" then
print(prefix.. "List: ")
for i, v in ipairs(node.elements) do
for i, v in ipairs(ast.elements) do
print_ast(v, level)
end
elseif t == "FieldName" or t == "Number" or t == "String" or t == "BareString" or t == "Macro" then
print (prefix..t.." "..node.value)
print (prefix..t.." "..ast.value)
elseif t == "MacroDef" then
-- don't print for now
@ -491,20 +508,8 @@ function compiler.compile_line(line, macro_defs)
return {}
end
local macros
if (ast.type == "Rule") then
macros = get_macros(ast.filter, {})
elseif (ast.type == "MacroDef") then
macros = get_macros(ast.value, {})
else
error ("Unexpected type: "..t)
end
for m, _ in pairs(macros) do
if macros[m] == nil then
error ("Undefined macro '"..m.."' used in '"..line.."'")
end
end
-- check that any macros used have already been defined
check_macros(ast)
if (ast.type == "MacroDef") then
-- Parsed line is a macro definition, so update our dictionary of macros and

View File

@ -7,15 +7,18 @@
local compiler = require "compiler"
local function mark_check_nodes(ast, index)
--[[
Traverse AST, adding the passed-in 'index' to each node that contains a relational expression
--]]
local function mark_relational_nodes(ast, index)
local t = ast.type
if t == "BinaryBoolOp" then
mark_check_nodes(ast.left, index)
mark_check_nodes(ast.right, index)
mark_relational_nodes(ast.left, index)
mark_relational_nodes(ast.right, index)
elseif t == "UnaryBoolOp" then
mark_check_nodes(ast.argument, index)
mark_relational_nodes(ast.argument, index)
elseif t == "BinaryRelOp" then
ast.index = index
@ -95,11 +98,20 @@ function load_rule(r)
error ("Unexpected type in load_rule: "..line_ast.type)
end
-- Register a formatter with the output string from this rule
digwatch.set_formatter(state.n_rules, line_ast.output.value)
mark_check_nodes(line_ast.filter.value, state.n_rules)
-- Store the index of this formatter in each relational expression that
-- this rule contains.
-- This index will eventually be stamped in events passing this rule, and
-- we'll use it later to determine which output to display when we get an
-- event.
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.
if (state.filter_ast == nil) then
state.filter_ast = line_ast.filter.value
else

View File

@ -2,13 +2,13 @@
function error_exit_good
{
echo "Error: '$1' did not parse" 1>&2
echo "Error: '$1' did not compiler" 1>&2
exit 1
}
function error_exit_bad
{
echo "Error: incorrect filter '$1' parsed ok" 1>&2
echo "Error: incorrect filter '$1' compiler ok" 1>&2
exit 1
}
@ -72,6 +72,7 @@ good "a : evt.dir=>"
good "inbound: (syscall.type=listen and evt.dir='>') or (syscall.type=accept and evt.dir='<')"
bad "a:"
bad "a : b | bla"
bad "b and d"
echo