diff --git a/digwatch.yaml b/digwatch.yaml index cab5e194..402358d5 100644 --- a/digwatch.yaml +++ b/digwatch.yaml @@ -1,5 +1,8 @@ rules_file: /etc/digwatch_rules.conf -json_output: true +json_output: false + +log_stderr: true +log_syslog: true syslog_output: enabled: false diff --git a/userspace/digwatch/CMakeLists.txt b/userspace/digwatch/CMakeLists.txt index eb6dfc8a..3a94017d 100644 --- a/userspace/digwatch/CMakeLists.txt +++ b/userspace/digwatch/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories("${YAMLCPP_INCLUDE_DIR}") include_directories("${LPEG_SRC}") include_directories(${DRAIOS_DEPENDENCIES_DIR}/yaml-${DRAIOS_YAML_VERSION}/target/include) -add_executable(digwatch configuration.cpp formats.cpp fields.cpp rules.cpp syslog.cpp digwatch.cpp) +add_executable(digwatch configuration.cpp formats.cpp fields.cpp rules.cpp logger.cpp digwatch.cpp) target_link_libraries(digwatch sinsp) target_link_libraries(digwatch diff --git a/userspace/digwatch/configuration.cpp b/userspace/digwatch/configuration.cpp index 3fc8a602..b6044c9c 100644 --- a/userspace/digwatch/configuration.cpp +++ b/userspace/digwatch/configuration.cpp @@ -1,6 +1,7 @@ #include "configuration.h" #include "config_digwatch.h" #include "sinsp.h" +#include "logger.h" using namespace std; @@ -53,4 +54,7 @@ void digwatch_configuration::init(string conf_filename) { throw sinsp_exception("Error reading config file (" + m_config_file + "): No outputs configured. Please configure at least one output file output enabled but no filename in configuration block"); } + + digwatch_logger::log_stderr = m_config->get_scalar("log_stderr", false); + digwatch_logger::log_syslog = m_config->get_scalar("log_syslog", true); } diff --git a/userspace/digwatch/digwatch.cpp b/userspace/digwatch/digwatch.cpp index b2ac05de..4163843b 100644 --- a/userspace/digwatch/digwatch.cpp +++ b/userspace/digwatch/digwatch.cpp @@ -23,17 +23,10 @@ extern "C" { #include "rules.h" #include "formats.h" #include "fields.h" -#include "syslog.h" +#include "logger.h" #include "utils.h" #include -static bool g_terminate = false; - -static void signal_callback(int signal) -{ - g_terminate = true; -} - std::vector valid_output_names {"stdout", "syslog"}; @@ -49,7 +42,7 @@ static void usage() " -c Configuration file (default " DIGWATCH_SOURCE_CONF_FILE ", " DIGWATCH_INSTALL_CONF_FILE ")\n" " -o Output type (options are 'stdout', 'syslog', default is 'stdout')\n" " -e Read the events from (in .scap format) instead of tapping into live.\n" - " -r Rules configuration file (defaults to value set in configuration file, or /etc/digwatch_rules.conf).\n" + " -r Rules file (defaults to value set in configuration file, or /etc/digwatch_rules.conf).\n" "\n" ); } @@ -74,11 +67,6 @@ void do_inspect(sinsp* inspector, while(1) { - if(g_terminate) - { - break; - } - res = inspector->next(&ev); if(res == SCAP_TIMEOUT) @@ -266,7 +254,7 @@ int digwatch_init(int argc, char **argv) conf_stream = new ifstream(conf_filename); if (!conf_stream->good()) { - fprintf(stderr, "Could not find configuration file at %s \n", conf_filename.c_str()); + digwatch_logger::log(LOG_ERR, "Could not find configuration file at " + conf_filename + ". Exiting \n"); result = EXIT_FAILURE; goto exit; } @@ -295,34 +283,20 @@ int digwatch_init(int argc, char **argv) digwatch_configuration config; if (conf_filename.size()) { - cout << "Using configuration file " + conf_filename + "\n"; config.init(conf_filename); + // log after config init because config determines where logs go + digwatch_logger::log(LOG_INFO, "Digwatch initialized with configuration file " + conf_filename + "\n"); } else { - cout << "No configuration file found, proceeding with defaults\n"; config.init(); + digwatch_logger::log(LOG_INFO, "Digwatch initialized. No configuration file found, proceeding with defaults\n"); } if (rules_filename.size()) { config.m_rules_filename = rules_filename; } - cout << "Using rules file " + config.m_rules_filename + "\n"; - - if(signal(SIGINT, signal_callback) == SIG_ERR) - { - fprintf(stderr, "An error occurred while setting SIGINT signal handler.\n"); - result = EXIT_FAILURE; - goto exit; - } - - if(signal(SIGTERM, signal_callback) == SIG_ERR) - { - fprintf(stderr, "An error occurred while setting SIGTERM signal handler.\n"); - result = EXIT_FAILURE; - goto exit; - } lua_main_filename = lua_dir + DIGWATCH_LUA_MAIN; if (!std::ifstream(lua_main_filename)) @@ -331,9 +305,9 @@ int digwatch_init(int argc, char **argv) lua_main_filename = lua_dir + DIGWATCH_LUA_MAIN; if (!std::ifstream(lua_main_filename)) { - fprintf(stderr, "Could not find Digwatch Lua libraries (tried %s, %s). \n", - DIGWATCH_LUA_DIR DIGWATCH_LUA_MAIN, - lua_main_filename.c_str()); + digwatch_logger::log(LOG_ERR, "Could not find Digwatch Lua libraries (tried " + + string(DIGWATCH_LUA_DIR DIGWATCH_LUA_MAIN) + ", " + + lua_main_filename + "). Exiting \n"); result = EXIT_FAILURE; goto exit; } @@ -350,10 +324,11 @@ int digwatch_init(int argc, char **argv) digwatch_formats::init(inspector, ls); digwatch_fields::init(inspector, ls); - digwatch_syslog::init(ls); + digwatch_logger::init(ls); rules->load_rules(config.m_rules_filename); inspector->set_filter(rules->get_filter()); + digwatch_logger::log(LOG_INFO, "Parsed rules from file " + config.m_rules_filename + "\n"); inspector->set_hostname_and_port_resolution_mode(false); @@ -386,7 +361,7 @@ int digwatch_init(int argc, char **argv) { if(system("modprobe " PROBE_NAME " > /dev/null 2> /dev/null")) { - fprintf(stderr, "Unable to load the driver\n"); + digwatch_logger::log(LOG_ERR, "Unable to load the driver. Exiting\n"); } inspector->open(); } @@ -399,12 +374,14 @@ int digwatch_init(int argc, char **argv) } catch(sinsp_exception& e) { - cerr << e.what() << endl; + digwatch_logger::log(LOG_ERR, "Runtime error: " + string(e.what()) + ". Exiting\n"); + result = EXIT_FAILURE; } catch(...) { - printf("Error, exiting.\n"); + digwatch_logger::log(LOG_ERR, "Unexpected error, Exiting\n"); + result = EXIT_FAILURE; } diff --git a/userspace/digwatch/formats.cpp b/userspace/digwatch/formats.cpp index bf9113e0..a2bfb961 100644 --- a/userspace/digwatch/formats.cpp +++ b/userspace/digwatch/formats.cpp @@ -1,4 +1,5 @@ #include "formats.h" +#include "logger.h" sinsp* digwatch_formats::s_inspector = NULL; @@ -27,8 +28,8 @@ int digwatch_formats::formatter(lua_State *ls) } catch(sinsp_exception& e) { - string err = "invalid output format " + format; - fprintf(stderr, "%s\n", err.c_str()); + digwatch_logger::log(LOG_ERR, "Invalid output format '" + format + "'.\n"); + throw sinsp_exception("set_formatter error"); } @@ -42,8 +43,7 @@ int digwatch_formats::format_event (lua_State *ls) string line; if (!lua_islightuserdata(ls, -1) || !lua_islightuserdata(ls, -2)) { - string err = "invalid arguments passed to format_event() "; - fprintf(stderr, "%s\n", err.c_str()); + digwatch_logger::log(LOG_ERR, "Invalid arguments passed to format_event()\n"); throw sinsp_exception("format_event error"); } sinsp_evt* evt = (sinsp_evt*)lua_topointer(ls, 1); diff --git a/userspace/digwatch/logger.cpp b/userspace/digwatch/logger.cpp new file mode 100644 index 00000000..f09af8c6 --- /dev/null +++ b/userspace/digwatch/logger.cpp @@ -0,0 +1,49 @@ +#include +#include "logger.h" +#include "chisel_api.h" +#include "filterchecks.h" + + + +const static struct luaL_reg ll_digwatch [] = +{ + {"syslog", &digwatch_logger::syslog}, + {NULL,NULL} +}; + + +void digwatch_logger::init(lua_State *ls) +{ + luaL_openlib(ls, "digwatch", ll_digwatch, 0); +} + +int digwatch_logger::syslog(lua_State *ls) { + int priority = luaL_checknumber(ls, 1); + + if (priority > LOG_DEBUG) { + return luaL_argerror(ls, 1, "digwatch.syslog: priority must be a number between 0 and 7"); + } + + const char *msg = luaL_checkstring(ls, 2); + ::syslog(priority, "%s", msg); + + return 0; +} + +bool digwatch_logger::log_stderr; +bool digwatch_logger::log_syslog; + +void digwatch_logger::log(int priority, const string msg) { + if (digwatch_logger::log_syslog) { + ::syslog(priority, "%s", msg.c_str()); + } + + if (digwatch_logger::log_stderr) { + std::time_t result = std::time(nullptr); + string tstr = std::asctime(std::localtime(&result)); + tstr = tstr.substr(0, 24);// remove trailling newline + fprintf(stderr, "%s: %s", tstr.c_str(), msg.c_str()); + } +} + + diff --git a/userspace/digwatch/syslog.h b/userspace/digwatch/logger.h similarity index 62% rename from userspace/digwatch/syslog.h rename to userspace/digwatch/logger.h index 54dccc17..5043aedf 100644 --- a/userspace/digwatch/syslog.h +++ b/userspace/digwatch/logger.h @@ -1,6 +1,7 @@ #pragma once #include "sinsp.h" +#include extern "C" { #include "lua.h" @@ -8,11 +9,16 @@ extern "C" { #include "lauxlib.h" } -class digwatch_syslog +class digwatch_logger { public: static void init(lua_State *ls); // value = digwatch.syslog(level, message) static int syslog(lua_State *ls); + + static void log(int priority, const string msg); + + static bool log_stderr; + static bool log_syslog; }; diff --git a/userspace/digwatch/syslog.cpp b/userspace/digwatch/syslog.cpp deleted file mode 100644 index 8d811651..00000000 --- a/userspace/digwatch/syslog.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "syslog.h" -#include "chisel_api.h" -#include "filterchecks.h" - -#include - - -const static struct luaL_reg ll_digwatch [] = -{ - {"syslog", &digwatch_syslog::syslog}, - {NULL,NULL} -}; - - -void digwatch_syslog::init(lua_State *ls) -{ - luaL_openlib(ls, "digwatch", ll_digwatch, 0); -} - -int digwatch_syslog::syslog(lua_State *ls) { - int priority = luaL_checknumber(ls, 1); - - if (priority > LOG_DEBUG) { - return luaL_argerror(ls, 1, "digwatch.syslog: priority must be a number between 0 and 7"); - } - - const char *msg = luaL_checkstring(ls, 2); - ::syslog(priority, "%s", msg); - - return 0; -} -