From 278a9c380636202aceac8eedea4d8e9198fd871f Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Fri, 30 May 2025 11:02:44 -0600 Subject: [PATCH] lua: convert log functions to suricata.log lib Convert the Lua global functions for logging (SCLogInfo, etc) to a Lua lib names "suricata.log". Ticket: #7727 --- doc/userguide/lua/libs/index.rst | 1 + doc/userguide/lua/libs/log.rst | 92 +++++++++++++++++++++++++++ doc/userguide/lua/libs/packetlib.rst | 4 +- doc/userguide/lua/lua-functions.rst | 11 ---- doc/userguide/output/lua-output.rst | 6 +- src/Makefile.am | 2 + src/util-lua-builtins.c | 2 + src/util-lua-common.c | 95 ---------------------------- src/util-lua-log.c | 93 +++++++++++++++++++++++++++ src/util-lua-log.h | 25 ++++++++ 10 files changed, 222 insertions(+), 109 deletions(-) create mode 100644 doc/userguide/lua/libs/log.rst create mode 100644 src/util-lua-log.c create mode 100644 src/util-lua-log.h diff --git a/doc/userguide/lua/libs/index.rst b/doc/userguide/lua/libs/index.rst index b79492abdb..0778b63440 100644 --- a/doc/userguide/lua/libs/index.rst +++ b/doc/userguide/lua/libs/index.rst @@ -16,6 +16,7 @@ environment without access to additional modules. flowvar hashlib http + log packetlib rule smtp diff --git a/doc/userguide/lua/libs/log.rst b/doc/userguide/lua/libs/log.rst new file mode 100644 index 0000000000..bf547c6dbc --- /dev/null +++ b/doc/userguide/lua/libs/log.rst @@ -0,0 +1,92 @@ +Log +### + +The ``suricata.log`` Lua library exposes the Suricata application +logging functions to Lua scripts. These are equivalant to +``SCLogNotice``, ``SCLogError``, etc, in the Suricata source. + +In Suricata, the logging priority order is: + +* Error +* Warning +* Notice +* Info +* Perf +* Config +* Debug + +.. note:: Debug logging will only work if Suricata was compiled with + ``--enable-debug``. + +Setup +***** + +To use the logging functions, first require the module:: + + local logger = require("suricata.log") + +Functions +********* + +``info`` +======== + +Log an informational message:: + + logger.info("Processing HTTP request") + +This is equivalent to ``SCLogInfo``. + +``notice`` +========== + +Log a notice message:: + + logger.notice("Unusual pattern detected") + +This is equivalent to ``SCLogNotice``. + +``warning`` +=========== + +Log a warning message:: + + logger.warning("Connection limit approaching") + +This is equivalent to ``SCLogWarning``. + +``error`` +========= + +Log an error message:: + + logger.error("Failed to parse data") + +This is equivalent to ``SCLogError``. + +``debug`` +========= + +Log a debug message (only visible when debug logger.ing is enabled):: + + logger.debug("Variable value: " .. tostring(value)) + +This is equivalent to ``SCLogDebug``. + +``config`` +========== + +Log a configuration-related message:: + + logger.config("Loading configuration from " .. filename) + +This is equivalent to ``SCLogConfig``. + +``perf`` +======== + +Log a performance-related message:: + + logger.perf("Processing took " .. elapsed .. " seconds") + +This is equivalent to ``SCLogPerf``. diff --git a/doc/userguide/lua/libs/packetlib.rst b/doc/userguide/lua/libs/packetlib.rst index 8961a11310..8924dba3fa 100644 --- a/doc/userguide/lua/libs/packetlib.rst +++ b/doc/userguide/lua/libs/packetlib.rst @@ -160,6 +160,8 @@ If it is found, issue a notice log with packet details. :: + local logger = require("suricata.log") + function match (args) p = packet.get() payload = p:payload() @@ -168,7 +170,7 @@ If it is found, issue a notice log with packet details. for line in payload:gmatch("([^\r\n]*)[\r\n]+") do if line == "GET /index.html HTTP/1.0" then ipver, srcip, dstip, proto, sp, dp = p:tuple() - SCLogNotice(string.format("%s %s->%s %d->%d (pcap_cnt:%d) match! %s", ts, srcip, dstip, sp, dp, p:pcap_cnt(), line)); + logger.notice(string.format("%s %s->%s %d->%d (pcap_cnt:%d) match! %s", ts, srcip, dstip, sp, dp, p:pcap_cnt(), line)); return 1 end end diff --git a/doc/userguide/lua/lua-functions.rst b/doc/userguide/lua/lua-functions.rst index 1bbbd541c0..dce63ced6d 100644 --- a/doc/userguide/lua/lua-functions.rst +++ b/doc/userguide/lua/lua-functions.rst @@ -314,17 +314,6 @@ SCThreadInfo It gives: tid (integer), tname (string), tgroup (string) -SCLogError, SCLogWarning, SCLogNotice, SCLogInfo, SCLogDebug -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Print a message. It will go into the outputs defined in the -yaml. Whether it will be printed depends on the log level. - -Example: - -:: - - SCLogError("some error message") SCLogPath ~~~~~~~~~ diff --git a/doc/userguide/output/lua-output.rst b/doc/userguide/output/lua-output.rst index 9401d94e5e..d21ae7de76 100644 --- a/doc/userguide/output/lua-output.rst +++ b/doc/userguide/output/lua-output.rst @@ -27,6 +27,8 @@ Example: :: + local logger = require("suricata.log") + function init (args) local needs = {} needs["protocol"] = "http" @@ -36,7 +38,7 @@ Example: function setup (args) filename = SCLogPath() .. "/" .. name file = assert(io.open(filename, "a")) - SCLogInfo("HTTP Log Filename " .. filename) + logger.info("HTTP Log Filename " .. filename) http = 0 end @@ -71,7 +73,7 @@ Example: end function deinit (args) - SCLogInfo ("HTTP transactions logged: " .. http); + logger.info ("HTTP transactions logged: " .. http); file:close(file) end diff --git a/src/Makefile.am b/src/Makefile.am index 4b10a970cc..4501243b92 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -547,6 +547,7 @@ noinst_HEADERS = \ util-lua-hashlib.h \ util-lua-http.h \ util-lua-ja3.h \ + util-lua-log.h \ util-lua-packetlib.h \ util-lua-rule.h \ util-lua-sandbox.h \ @@ -1124,6 +1125,7 @@ libsuricata_c_a_SOURCES = \ util-lua-hashlib.c \ util-lua-http.c \ util-lua-ja3.c \ + util-lua-log.c \ util-lua-packetlib.c \ util-lua-rule.c \ util-lua-sandbox.c \ diff --git a/src/util-lua-builtins.c b/src/util-lua-builtins.c index a14101da91..5b45ab7130 100644 --- a/src/util-lua-builtins.c +++ b/src/util-lua-builtins.c @@ -33,6 +33,7 @@ #include "util-lua-rule.h" #include "util-lua-ja3.h" #include "util-lua-filelib.h" +#include "util-lua-log.h" #include "lauxlib.h" @@ -48,6 +49,7 @@ static const luaL_Reg builtins[] = { { "suricata.hashlib", SCLuaLoadHashlib }, { "suricata.http", SCLuaLoadHttpLib }, { "suricata.ja3", SCLuaLoadJa3Lib }, + { "suricata.log", SCLuaLoadLogLib }, { "suricata.packet", LuaLoadPacketLib }, { "suricata.rule", SCLuaLoadRuleLib }, { "suricata.smtp", SCLuaLoadSmtpLib }, diff --git a/src/util-lua-common.c b/src/util-lua-common.c index 4082c0e1cc..33498b088f 100644 --- a/src/util-lua-common.c +++ b/src/util-lua-common.c @@ -24,37 +24,17 @@ */ #include "suricata-common.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" #include "threads.h" #include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" #include "output.h" -#include "app-layer-htp.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" #include "util-conf.h" #include "lua.h" -#include "lualib.h" -#include "lauxlib.h" #include "util-lua.h" #include "util-lua-common.h" -#include "action-globals.h" int LuaCallbackError(lua_State *luastate, const char *msg) { @@ -142,70 +122,6 @@ static int LuaCallbackLogPath(lua_State *luastate) return LuaPushStringBuffer(luastate, (const uint8_t *)ld, strlen(ld)); } -static int LuaCallbackLogDebug(lua_State *luastate) -{ - const char *msg = LuaGetStringArgument(luastate, 1); - if (msg == NULL) - return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); - SCLogDebug("%s", msg); - return 0; -} - -static int LuaCallbackLogInfo(lua_State *luastate) -{ - const char *msg = LuaGetStringArgument(luastate, 1); - if (msg == NULL) - return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); - - lua_Debug ar; - lua_getstack(luastate, 1, &ar); - lua_getinfo(luastate, "nSl", &ar); - const char *funcname = ar.name ? ar.name : ar.what; - SCLogInfoRaw(ar.short_src, funcname, ar.currentline, "%s", msg); - return 0; -} - -static int LuaCallbackLogNotice(lua_State *luastate) -{ - const char *msg = LuaGetStringArgument(luastate, 1); - if (msg == NULL) - return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); - - lua_Debug ar; - lua_getstack(luastate, 1, &ar); - lua_getinfo(luastate, "nSl", &ar); - const char *funcname = ar.name ? ar.name : ar.what; - SCLogNoticeRaw(ar.short_src, funcname, ar.currentline, "%s", msg); - return 0; -} - -static int LuaCallbackLogWarning(lua_State *luastate) -{ - const char *msg = LuaGetStringArgument(luastate, 1); - if (msg == NULL) - return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); - - lua_Debug ar; - lua_getstack(luastate, 1, &ar); - lua_getinfo(luastate, "nSl", &ar); - const char *funcname = ar.name ? ar.name : ar.what; - SCLogWarningRaw(ar.short_src, funcname, ar.currentline, "%s", msg); - return 0; -} - -static int LuaCallbackLogError(lua_State *luastate) -{ - const char *msg = LuaGetStringArgument(luastate, 1); - if (msg == NULL) - return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); - lua_Debug ar; - lua_getstack(luastate, 1, &ar); - lua_getinfo(luastate, "nSl", &ar); - const char *funcname = ar.name ? ar.name : ar.what; - SCLogErrorRaw(ar.short_src, funcname, ar.currentline, "%s", msg); - return 0; -} - /** \internal * \brief fill lua stack with thread info * \param luastate the lua state @@ -245,17 +161,6 @@ int LuaRegisterFunctions(lua_State *luastate) lua_pushcfunction(luastate, LuaCallbackLogPath); lua_setglobal(luastate, "SCLogPath"); - lua_pushcfunction(luastate, LuaCallbackLogDebug); - lua_setglobal(luastate, "SCLogDebug"); - lua_pushcfunction(luastate, LuaCallbackLogInfo); - lua_setglobal(luastate, "SCLogInfo"); - lua_pushcfunction(luastate, LuaCallbackLogNotice); - lua_setglobal(luastate, "SCLogNotice"); - lua_pushcfunction(luastate, LuaCallbackLogWarning); - lua_setglobal(luastate, "SCLogWarning"); - lua_pushcfunction(luastate, LuaCallbackLogError); - lua_setglobal(luastate, "SCLogError"); - lua_pushcfunction(luastate, LuaCallbackThreadInfo); lua_setglobal(luastate, "SCThreadInfo"); return 0; diff --git a/src/util-lua-log.c b/src/util-lua-log.c new file mode 100644 index 0000000000..4fed9f7d2c --- /dev/null +++ b/src/util-lua-log.c @@ -0,0 +1,93 @@ +/* Copyright (C) 2025 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * 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 + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include "suricata-common.h" +#include "util-lua-log.h" +#include "util-lua.h" +#include "util-debug.h" + +#include "lauxlib.h" + +static int LuaLogInfo(lua_State *L) +{ + const char *msg = luaL_checkstring(L, 1); + SCLogInfo("%s", msg); + return 0; +} + +static int LuaLogNotice(lua_State *L) +{ + const char *msg = luaL_checkstring(L, 1); + SCLogNotice("%s", msg); + return 0; +} + +static int LuaLogWarning(lua_State *L) +{ + const char *msg = luaL_checkstring(L, 1); + SCLogWarning("%s", msg); + return 0; +} + +static int LuaLogError(lua_State *L) +{ + const char *msg = luaL_checkstring(L, 1); + SCLogError("%s", msg); + return 0; +} + +static int LuaLogDebug(lua_State *L) +{ +#ifdef DEBUG + const char *msg = luaL_checkstring(L, 1); + SCLogDebug("%s", msg); +#endif + return 0; +} + +static int LuaLogConfig(lua_State *L) +{ + const char *msg = luaL_checkstring(L, 1); + SCLogConfig("%s", msg); + return 0; +} + +static int LuaLogPerf(lua_State *L) +{ + const char *msg = luaL_checkstring(L, 1); + SCLogPerf("%s", msg); + return 0; +} + +static const struct luaL_Reg loglib[] = { + // clang-format off + { "info", LuaLogInfo }, + { "notice", LuaLogNotice }, + { "warning", LuaLogWarning }, + { "error", LuaLogError }, + { "debug", LuaLogDebug }, + { "config", LuaLogConfig }, + { "perf", LuaLogPerf }, + { NULL, NULL } + // clang-format on +}; + +int SCLuaLoadLogLib(lua_State *L) +{ + luaL_newlib(L, loglib); + return 1; +} diff --git a/src/util-lua-log.h b/src/util-lua-log.h new file mode 100644 index 0000000000..476f36f20e --- /dev/null +++ b/src/util-lua-log.h @@ -0,0 +1,25 @@ +/* Copyright (C) 2025 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * 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 + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef SURICATA_UTIL_LUA_LOG_H +#define SURICATA_UTIL_LUA_LOG_H + +#include + +int SCLuaLoadLogLib(lua_State *L); + +#endif /* SURICATA_UTIL_LUA_LOG_H */ -- 2.47.2