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)
set(DIGWATCH_LUA_MAIN "rule_loader.lua")
configure_file(config_digwatch.h.in config_digwatch.h)

View File

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

View File

@ -6,16 +6,21 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <algorithm>
#include <unistd.h>
#include <getopt.h>
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#include <sinsp.h>
#include <config_digwatch.h>
#include "rules.h"
#include "digwatch.h"
#include "utils.h"
#include <unistd.h>
#include <getopt.h>
static void usage();
//
// Program help
@ -23,15 +28,16 @@ static void usage();
static void usage()
{
printf(
"Usage: digwatch [options] [-p <output_format>] [filter]\n\n"
"Usage: digwatch [options] [-p <output_format>] rules_filename\n\n"
"Options:\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"
" -N Don't convert port numbers to names.\n"
" -n <num>, --numevents=<num>\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"
" Read the events from <readfile>.\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;
string output_format;
int long_index = 0;
string user_parser;
string lua_main_filename;
string lua_dir = DIGWATCH_INSTALLATION_DIR;
static struct option long_options[] =
{
{"help", no_argument, 0, 'h' },
{"numevents", required_argument, 0, 'n' },
{"user-parser", required_argument, 0, 'u' },
{"main-lua", required_argument, 0, 'u' },
{"readfile", required_argument, 0, 'r' },
{"unbuffered", no_argument, 0, 0 },
{0, 0, 0, 0}
@ -156,7 +163,7 @@ int digwatch_init(int argc, char **argv)
// Parse the args
//
while((op = getopt_long(argc, argv,
"hM:Nn:r:u:",
"hm:M:Nn:r:",
long_options, &long_index)) != -1)
{
switch(op)
@ -165,6 +172,9 @@ int digwatch_init(int argc, char **argv)
usage();
result = EXIT_SUCCESS;
goto exit;
case 'm':
lua_main_filename = optarg;
break;
case 'M':
duration_to_tot = atoi(optarg);
if(duration_to_tot <= 0)
@ -190,9 +200,6 @@ int digwatch_init(int argc, char **argv)
throw sinsp_exception(string("invalid event count ") + optarg);
}
break;
case 'u':
user_parser = optarg;
break;
case '?':
result = EXIT_FAILURE;
goto exit;
@ -204,20 +211,17 @@ int digwatch_init(int argc, char **argv)
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)
{
#ifdef HAS_FILTERING
for(int32_t j = optind ; j < argc; j++)
{
filter += argv[j];
rules_file += argv[j];
if(j < argc - 1)
{
filter += " ";
rules_file += " ";
}
}
@ -228,13 +232,33 @@ int digwatch_init(int argc, char **argv)
#endif
}
if (rules_file.size() == 0) {
usage();
result = EXIT_FAILURE;
goto exit;
}
//
// Create the event formatter
//
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->open("");
@ -252,7 +276,7 @@ int digwatch_init(int argc, char **argv)
}
catch(...)
{
printf("Exeception\n");
printf("Exception\n");
result = EXIT_FAILURE;
}

View File

@ -6,18 +6,43 @@ extern "C" {
#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);
m_ls = m_lua_parser->m_ls;
// Initialize Lua interpreter
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;
is.open(compiler_filename);
is.open(lua_main_filename);
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)),
@ -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))
{
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()
{
return m_lua_parser->get_filter();

View File

@ -6,12 +6,17 @@
class digwatch_rules
{
public:
digwatch_rules(sinsp* inspector, string compiler_filename);
digwatch_rules(sinsp* inspector, string lua_main_filename, string lua_dir);
~digwatch_rules();
void load(string rules_filename);
void load_rules(string rules_filename);
sinsp_filter* get_filter();
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_compiler_cb = "load_rules";
string m_lua_;
};