Rework loading of Lua and rules files

This commit is contained in:
Henri DF 2016-02-20 16:21:56 -08:00
parent 9b89116a26
commit 9fef5a7b29
5 changed files with 121 additions and 30 deletions

View File

@ -15,4 +15,5 @@ add_executable(digwatch rules.cpp digwatch.cpp)
target_link_libraries(digwatch sinsp) target_link_libraries(digwatch sinsp)
set(DIGWATCH_LUA_MAIN "rule_loader.lua")
configure_file(config_digwatch.h.in config_digwatch.h) configure_file(config_digwatch.h.in config_digwatch.h)

View File

@ -3,3 +3,5 @@
#define DIGWATCH_VERSION "${DIGWATCH_VERSION}" #define DIGWATCH_VERSION "${DIGWATCH_VERSION}"
#define DIGWATCH_INSTALLATION_DIR "${CMAKE_INSTALL_PREFIX}" #define DIGWATCH_INSTALLATION_DIR "${CMAKE_INSTALL_PREFIX}"
#define DIGWATCH_LUA_MAIN "${DIGWATCH_LUA_MAIN}"

View File

@ -6,16 +6,21 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <algorithm> #include <algorithm>
#include <unistd.h>
#include <getopt.h>
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#include <sinsp.h> #include <sinsp.h>
#include <config_digwatch.h>
#include "rules.h" #include "rules.h"
#include "digwatch.h" #include "digwatch.h"
#include "utils.h" #include "utils.h"
#include <unistd.h>
#include <getopt.h>
static void usage();
// //
// Program help // Program help
@ -23,15 +28,16 @@ static void usage();
static void usage() static void usage()
{ {
printf( printf(
"Usage: digwatch [options] [-p <output_format>] [filter]\n\n" "Usage: digwatch [options] [-p <output_format>] rules_filename\n\n"
"Options:\n" "Options:\n"
" -h, --help Print this page\n" " -h, --help Print this page\n"
" -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" " -M <num_seconds> Stop collecting after <num_seconds> reached.\n"
" -N Don't convert port numbers to names.\n" " -N Don't convert port numbers to names.\n"
" -n <num>, --numevents=<num>\n" " -n <num>, --numevents=<num>\n"
" Stop capturing after <num> events\n" " Stop capturing after <num> events\n"
" -u <filename>, --user-parser <filename>\n"
" Name of lua file containing parser\n"
" -r <readfile>, --read=<readfile>\n" " -r <readfile>, --read=<readfile>\n"
" Read the events from <readfile>.\n" " Read the events from <readfile>.\n"
" --unbuffered Turn off output buffering. This causes every single line\n" " --unbuffered Turn off output buffering. This causes every single line\n"
@ -133,13 +139,14 @@ int digwatch_init(int argc, char **argv)
captureinfo cinfo; captureinfo cinfo;
string output_format; string output_format;
int long_index = 0; int long_index = 0;
string user_parser; string lua_main_filename;
string lua_dir = DIGWATCH_INSTALLATION_DIR;
static struct option long_options[] = static struct option long_options[] =
{ {
{"help", no_argument, 0, 'h' }, {"help", no_argument, 0, 'h' },
{"numevents", required_argument, 0, 'n' }, {"numevents", required_argument, 0, 'n' },
{"user-parser", required_argument, 0, 'u' }, {"main-lua", required_argument, 0, 'u' },
{"readfile", required_argument, 0, 'r' }, {"readfile", required_argument, 0, 'r' },
{"unbuffered", no_argument, 0, 0 }, {"unbuffered", no_argument, 0, 0 },
{0, 0, 0, 0} {0, 0, 0, 0}
@ -156,7 +163,7 @@ int digwatch_init(int argc, char **argv)
// Parse the args // Parse the args
// //
while((op = getopt_long(argc, argv, while((op = getopt_long(argc, argv,
"hM:Nn:r:u:", "hm:M:Nn:r:",
long_options, &long_index)) != -1) long_options, &long_index)) != -1)
{ {
switch(op) switch(op)
@ -165,6 +172,9 @@ int digwatch_init(int argc, char **argv)
usage(); usage();
result = EXIT_SUCCESS; result = EXIT_SUCCESS;
goto exit; goto exit;
case 'm':
lua_main_filename = optarg;
break;
case 'M': case 'M':
duration_to_tot = atoi(optarg); duration_to_tot = atoi(optarg);
if(duration_to_tot <= 0) if(duration_to_tot <= 0)
@ -190,9 +200,6 @@ int digwatch_init(int argc, char **argv)
throw sinsp_exception(string("invalid event count ") + optarg); throw sinsp_exception(string("invalid event count ") + optarg);
} }
break; break;
case 'u':
user_parser = optarg;
break;
case '?': case '?':
result = EXIT_FAILURE; result = EXIT_FAILURE;
goto exit; goto exit;
@ -204,20 +211,17 @@ int digwatch_init(int argc, char **argv)
inspector->set_buffer_format(event_buffer_format); inspector->set_buffer_format(event_buffer_format);
string filter; string rules_file;
//
// the filter is at the end of the command line
//
if(optind < argc) if(optind < argc)
{ {
#ifdef HAS_FILTERING #ifdef HAS_FILTERING
for(int32_t j = optind ; j < argc; j++) for(int32_t j = optind ; j < argc; j++)
{ {
filter += argv[j]; rules_file += argv[j];
if(j < argc - 1) if(j < argc - 1)
{ {
filter += " "; rules_file += " ";
} }
} }
@ -228,13 +232,33 @@ int digwatch_init(int argc, char **argv)
#endif #endif
} }
if (rules_file.size() == 0) {
usage();
result = EXIT_FAILURE;
goto exit;
}
// //
// Create the event formatter // Create the event formatter
// //
sinsp_evt_formatter formatter(inspector, output_format); sinsp_evt_formatter formatter(inspector, output_format);
rules = new digwatch_rules(inspector, user_parser); trim(lua_main_filename);
if (lua_main_filename.size() == 0)
{
lua_main_filename = DIGWATCH_LUA_MAIN;
}
char* env_lua_dir = getenv("DIGWATCH_LUA_DIR");
if (env_lua_dir)
{
lua_dir = string(env_lua_dir);
}
rules = new digwatch_rules(inspector, lua_main_filename, lua_dir);
rules->load_rules(rules_file);
inspector->set_filter(rules->get_filter()); inspector->set_filter(rules->get_filter());
inspector->open(""); inspector->open("");
@ -252,7 +276,7 @@ int digwatch_init(int argc, char **argv)
} }
catch(...) catch(...)
{ {
printf("Exeception\n"); printf("Exception\n");
result = EXIT_FAILURE; result = EXIT_FAILURE;
} }

View File

@ -6,18 +6,43 @@ extern "C" {
#include "lauxlib.h" #include "lauxlib.h"
} }
digwatch_rules::digwatch_rules(sinsp* inspector, string compiler_filename) digwatch_rules::digwatch_rules(sinsp* inspector, string lua_main_filename, string lua_dir)
{ {
m_lua_parser = new lua_parser(inspector); // Initialize Lua interpreter
m_ls = m_lua_parser->m_ls; m_ls = lua_open();
luaL_openlibs(m_ls);
trim(compiler_filename); m_lua_parser = new lua_parser(inspector, m_ls);
add_lua_path(lua_dir);
load_compiler(lua_main_filename);
}
void digwatch_rules::add_lua_path(string path)
{
path += "?.lua";
lua_getglobal(m_ls, "package");
lua_getfield(m_ls, -1, "path");
string cur_path = lua_tostring(m_ls, -1 );
cur_path += ';';
cur_path.append(path.c_str());
lua_pop(m_ls, 1);
lua_pushstring(m_ls, cur_path.c_str());
lua_setfield(m_ls, -2, "path");
lua_pop(m_ls, 1);
}
void digwatch_rules::load_compiler(string lua_main_filename)
{
ifstream is; ifstream is;
is.open(compiler_filename); is.open(lua_main_filename);
if(!is.is_open()) if(!is.is_open())
{ {
throw sinsp_exception("can't open file " + compiler_filename); throw sinsp_exception("can't open file " + lua_main_filename);
} }
string scriptstr((istreambuf_iterator<char>(is)), string scriptstr((istreambuf_iterator<char>(is)),
@ -29,10 +54,44 @@ digwatch_rules::digwatch_rules(sinsp* inspector, string compiler_filename)
if(luaL_loadstring(m_ls, scriptstr.c_str()) || lua_pcall(m_ls, 0, 0, 0)) if(luaL_loadstring(m_ls, scriptstr.c_str()) || lua_pcall(m_ls, 0, 0, 0))
{ {
throw sinsp_exception("Failed to load script " + throw sinsp_exception("Failed to load script " +
compiler_filename + ": " + lua_tostring(m_ls, -1)); lua_main_filename + ": " + lua_tostring(m_ls, -1));
} }
} }
void digwatch_rules::load_rules(string rules_filename)
{
ifstream is;
is.open(rules_filename);
if(!is.is_open())
{
throw sinsp_exception("can't open file " + rules_filename);
}
lua_getglobal(m_ls, m_lua_compiler_cb.c_str());
if(lua_isfunction(m_ls, -1))
{
lua_pop(m_ls, 1);
} else {
throw sinsp_exception("No function " + m_lua_compiler_cb + " found in lua compiler module");
}
std::string line;
while (std::getline(is, line))
{
lua_getglobal(m_ls, m_lua_compiler_cb.c_str());
lua_pushstring(m_ls, line.c_str());
if(lua_pcall(m_ls, 1, 0, 0) != 0)
{
const char* lerr = lua_tostring(m_ls, -1);
string err = "Error loading rule: " + string(lerr);
throw sinsp_exception(err);
}
}
}
sinsp_filter* digwatch_rules::get_filter() sinsp_filter* digwatch_rules::get_filter()
{ {
return m_lua_parser->get_filter(); return m_lua_parser->get_filter();

View File

@ -6,12 +6,17 @@
class digwatch_rules class digwatch_rules
{ {
public: public:
digwatch_rules(sinsp* inspector, string compiler_filename); digwatch_rules(sinsp* inspector, string lua_main_filename, string lua_dir);
~digwatch_rules(); ~digwatch_rules();
void load(string rules_filename); void load_rules(string rules_filename);
sinsp_filter* get_filter(); sinsp_filter* get_filter();
private: private:
void add_lua_path(string path);
void load_compiler(string lua_main_filename);
lua_parser* m_lua_parser; lua_parser* m_lua_parser;
lua_State* m_ls; lua_State* m_ls;
string m_lua_compiler_cb = "load_rules";
string m_lua_;
}; };