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
pull/13339/head
Jason Ish 1 year ago committed by Victor Julien
parent 9046f30731
commit 278a9c3806

@ -16,6 +16,7 @@ environment without access to additional modules.
flowvar
hashlib
http
log
packetlib
rule
smtp

@ -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``.

@ -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

@ -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
~~~~~~~~~

@ -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

@ -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 \

@ -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 },

@ -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;

@ -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;
}

@ -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 <lua.h>
int SCLuaLoadLogLib(lua_State *L);
#endif /* SURICATA_UTIL_LUA_LOG_H */
Loading…
Cancel
Save