ntopng/attic/AlertCheckLuaEngine.cpp
2021-12-28 15:59:13 +01:00

215 lines
5.8 KiB
C++

/*
*
* (C) 2019 - ntop.org
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "ntop_includes.h"
/* ****************************************** */
AlertCheckLuaEngine::AlertCheckLuaEngine(AlertEntity alert_entity, ScriptPeriodicity script_periodicity,
NetworkInterface *_iface, lua_State *vm) : LuaEngine(vm) {
const char *lua_file = NULL;
iface = _iface;
tps = Utils::gettickspersec();
script_ok = false;
reset_stats();
p = script_periodicity;
switch(alert_entity) {
case alert_entity_network:
lua_file = "network.lua";
break;
case alert_entity_interface:
lua_file = "interface.lua";
break;
case alert_entity_snmp_device:
lua_file = "snmp_device.lua";
break;
case alert_entity_system:
lua_file = "system.lua";
break;
case alert_entity_flow:
ntop->getTrace()->traceEvent(TRACE_ERROR, "Unexpected entity 'flow'");
break;
case alert_entity_host:
ntop->getTrace()->traceEvent(TRACE_ERROR, "Unexpected entity 'host'");
break;
default:
/* Example: lua_file = "generic.lua" to handle a generic entity */
break;
}
if(lua_file) {
snprintf(script_path, sizeof(script_path),
"%s/callbacks/%s/%s",
ntop->getPrefs()->get_scripts_dir(),
iface ? "interface" : "system",
lua_file);
ntop->fixPath(script_path);
if(load_script(script_path, iface) < 0)
return;
/* Execute the script so that the "setup" function will be exposed */
if(lua_pcall(L, 0, 0, 0)) {
ntop->getTrace()->traceEvent(TRACE_WARNING, "Script failure[%s] [%s]", script_path, lua_tostring(L, -1));
return;
}
lua_getglobal(L, "setup"); /* Called function */
lua_pushstring(L, Utils::periodicityToScriptName(p)); /* push 1st argument */
if(lua_pcall(L, 1 /* 1 argument */, 0, 0)) {
ntop->getTrace()->traceEvent(TRACE_WARNING, "Script failure[%s] [%s]", script_path, lua_tostring(L, -1));
return;
}
script_ok = true;
} else {
/* Possibly handle a generic entity */
script_path[0] = '\0';
}
}
/* ****************************************** */
AlertCheckLuaEngine::~AlertCheckLuaEngine() {
#if 0
float elapsed_time = (float)total_ticks / tps;
ntop->getTrace()->traceEvent(TRACE_WARNING, "[elapsed time: %.4f sec][num calls: %u][calls/sec: %.4f][%s][clocks/sec: %llu]", elapsed_time, num_calls, num_calls / elapsed_time, script_path, tps);
#endif
if(script_ok) {
lua_getglobal(L, "teardown"); /* Called function */
if(lua_isfunction(L, -1)) {
lua_pushstring(L, Utils::periodicityToScriptName(p)); /* push 1st argument */
pcall(1 /* 1 argument */, 0);
}
}
}
/* ****************************************** */
void AlertCheckLuaEngine::reset_stats() {
num_calls = 0;
total_ticks = 0;
}
/* ****************************************** */
void AlertCheckLuaEngine::lua_stats(const char *key, lua_State *vm) {
if(vm) {
lua_newtable(vm);
lua_newtable(vm);
float elapsed_time = (float)total_ticks / tps;
lua_push_uint64_table_entry(vm, "num_calls", (u_int64_t)num_calls);
lua_push_float_table_entry(vm, "tot_duration_ms", elapsed_time * 1000);
lua_stats_detail(vm);
lua_pushstring(vm, "stats");
lua_insert(vm, -2);
lua_settable(vm, -3);
lua_pushstring(vm, key);
lua_insert(vm, -2);
lua_settable(vm, -3);
}
}
/* ****************************************** */
ScriptPeriodicity AlertCheckLuaEngine::getPeriodicity() const {
return p;
}
/* ****************************************** */
const char * AlertCheckLuaEngine::getGranularity() const {
return Utils::periodicityToScriptName(p);
}
/* ****************************************** */
bool AlertCheckLuaEngine::pcall(int num_args, int num_results) {
ticks t_begin;
if(!script_ok) {
/* Remove possibly pushed values on the lua stack to avoid overflow */
lua_settop(L, 0);
return(false);
}
t_begin = Utils::getticks();
if(lua_pcall(L, num_args, num_results, 0)) {
ntop->getTrace()->traceEvent(TRACE_WARNING, "Script failure[%s] [%s]", script_path, lua_tostring(L, -1));
return(false);
}
num_calls++;
total_ticks += Utils::getticks() - t_begin;
return(true);
}
/* ****************************************** */
#ifdef TEST_CHECK_ENGINE
AfterShutdownAction afterShutdownAction = after_shutdown_nop;
int main() {
const int num_runs = 1000;
ntop = new (std::nothrow) Ntop((char*)"test");
Prefs *prefs = new (std::nothrow) Prefs(ntop);
ntop->registerPrefs(prefs, false);
NetworkInterface *iface = new (std::nothrow) PcapInterface("lo");
ntop->registerInterface(iface);
/* Calls interface.lua for interface lo */
AlertCheckLuaEngine *engine = new (std::nothrow) AlertCheckLuaEngine(alert_entity_interface, minute_script, iface);
lua_State *L = engine->getState();
/* Tip: try with a mix of lua compilation/runtime errors in interface.lua/required modules
* to ensure that no crash occurs in any situation. */
for(int i=0; i<num_runs; i++) {
//printf("Run: %d/%d\n", i+1, num_runs);
engine->reset_stats();
lua_getglobal(L, USER_SCRIPTS_RUN_CALLBACK);
lua_pushstring(L, engine->getGranularity());
engine->pcall(1 /* num args */, 0);
}
delete engine;
delete ntop;
}
#endif