From c798b5d282e7c5c1d407c803ef5771b57aafdf3d Mon Sep 17 00:00:00 2001 From: Thierry FOURNIER Date: Tue, 17 Mar 2015 01:09:57 +0100 Subject: [PATCH] MINOR: lua: add log functions Thispatch adds global log function. Each log message is writed on the stderr and is sent to the default syslog server. These two actions are done according the configuration. --- doc/lua-api/index.rst | 189 ++++++++++++++++++++++++++++++++++++++++++ src/hlua.c | 178 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 367 insertions(+) diff --git a/doc/lua-api/index.rst b/doc/lua-api/index.rst index 7e5277841..cd47479c0 100644 --- a/doc/lua-api/index.rst +++ b/doc/lua-api/index.rst @@ -119,6 +119,114 @@ Core class The "core" class is static, t is not possible to create a new object of this type. +.. js:attribute:: core.emerg + + This attribute is an integer, it contains the value of the loglevel "emergency" (0). + +.. js:attribute:: core.alert + + This attribute is an integer, it contains the value of the loglevel "alert" (1). + +.. js:attribute:: core.crit + + This attribute is an integer, it contains the value of the loglevel "critical" (2). + +.. js:attribute:: core.err + + This attribute is an integer, it contains the value of the loglevel "error" (3). + +.. js:attribute:: core.warning + + This attribute is an integer, it contains the value of the loglevel "warning" (4). + +.. js:attribute:: core.notice + + This attribute is an integer, it contains the value of the loglevel "notice" (5). + +.. js:attribute:: core.info + + This attribute is an integer, it contains the value of the loglevel "info" (6). + +.. js:attribute:: core.debug + + This attribute is an integer, it contains the value of the loglevel "debug" (7). + +.. js:function:: core.log(loglevel, msg) + + **context**: body, init, task, action, sample-fetch, converter + + This fucntion sends a log. The log is sent, according with the HAProxy + configuration file, on the default syslog server if it is configured and on + the stderr if it is allowed. + + :param integer loglevel: Is the log level asociated with the message. It is a + number between 0 and 7. + :param string msg: The log content. + :see: core.emerg, core.alert, core.crit, core.err, core.warning, core.notice, + core.info, core.debug (log level definitions) + :see: code.Debug + :see: core.Info + :see: core.Warning + :see: core.Alert + +.. js:function:: core.Debug(msg) + + **context**: body, init, task, action, sample-fetch, converter + + :param string msg: The log content. + :see: log + + Does the same job than: + +.. code-block:: lua + + function Debug(msg) + core.log(core.debug, msg) + end +.. + +.. js:function:: core.Info(msg) + + **context**: body, init, task, action, sample-fetch, converter + + :param string msg: The log content. + :see: log + +.. code-block:: lua + + function Info(msg) + core.log(core.info, msg) + end +.. + +.. js:function:: core.Warning(msg) + + **context**: body, init, task, action, sample-fetch, converter + + :param string msg: The log content. + :see: log + +.. code-block:: lua + + function Warning(msg) + core.log(core.warning, msg) + end +.. + +.. js:function:: core.Alert(msg) + + **context**: body, init, task, action, sample-fetch, converter + + :param string msg: The log content. + :see: log + +.. code-block:: lua + + function Alert(msg) + core.log(core.alert, msg) + end +.. + .. js:function:: core.add_acl(filename, key) **context**: init, task, action, sample-fetch, converter @@ -644,6 +752,87 @@ TXN class This attribute contains an HTTP class object. It is avalaible only if the proxy has the "mode http" enabled. +.. js:function:: TXN.log(TXN, loglevel, msg) + + This function sends a log. The log is sent, according with the HAProxy + configuration file, on the default syslog server if it is configured and on + the stderr if it is allowed. + + :param class_txn txn: The class txn object containing the data. + :param integer loglevel: Is the log level asociated with the message. It is a + number between 0 and 7. + :param string msg: The log content. + :see: core.emerg, core.alert, core.crit, core.err, core.warning, core.notice, + core.info, core.debug (log level definitions) + :see: TXN.deflog + :see: TXN.Debug + :see: TXN.Info + :see: TXN.Warning + :see: TXN.Alert + +.. js:function:: TXN.deflog(TXN, msg) + + Sends a log line with the default loglevel for the proxy ssociated with the + transaction. + + :param class_txn txn: The class txn object containing the data. + :param string msg: The log content. + :see: TXN.log + +.. js:function:: TXN.Debug(txn, msg) + + :param class_txn txn: The class txn object containing the data. + :param string msg: The log content. + :see: TXN.log + + Does the same job than: + +.. code-block:: lua + + function Debug(txn, msg) + TXN.log(txn, core.debug, msg) + end +.. + +.. js:function:: TXN.Info(txn, msg) + + :param class_txn txn: The class txn object containing the data. + :param string msg: The log content. + :see: TXN.log + +.. code-block:: lua + + function Debug(txn, msg) + TXN.log(txn, core.info, msg) + end +.. + +.. js:function:: TXN.Warning(txn, msg) + + :param class_txn txn: The class txn object containing the data. + :param string msg: The log content. + :see: TXN.log + +.. code-block:: lua + + function Debug(txn, msg) + TXN.log(txn, core.warning, msg) + end +.. + +.. js:function:: TXN.Alert(txn, msg) + + :param class_txn txn: The class txn object containing the data. + :param string msg: The log content. + :see: TXN.log + +.. code-block:: lua + + function Debug(txn, msg) + TXN.log(txn, core.alert, msg) + end +.. + .. js:function:: TXN.get_priv(txn) Return Lua data stored in the current transaction (with the `TXN.set_priv()`) diff --git a/src/hlua.c b/src/hlua.c index b6f53a9dd..c6a4447d9 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -1,5 +1,7 @@ #include +#include + #include #include #include @@ -732,6 +734,36 @@ static inline void hlua_sethlua(struct hlua *hlua) *hlua_store = hlua; } +/* This function is used to send logs. It try to send on screen (stderr) + * and on the default syslog server. + */ +static inline void hlua_sendlog(struct proxy *px, int level, const char *msg) +{ + struct tm tm; + char *p; + + /* Cleanup the log message. */ + p = trash.str; + for (; *msg != '\0'; msg++, p++) { + if (p >= trash.str + trash.size - 1) + return; + if (isprint(*msg)) + *p = *msg; + else + *p = '.'; + } + *p = '\0'; + + send_log(px, level, "%s", trash.str); + if (!(global.mode & MODE_QUIET) || (global.mode & (MODE_VERBOSE | MODE_STARTING))) { + get_localtime(date.tv_sec, &tm); + fprintf(stderr, "[%s] %03d/%02d%02d%02d (%d) : %s\n", + log_levels[level], tm.tm_yday, tm.tm_hour, tm.tm_min, tm.tm_sec, + (int)getpid(), trash.str); + fflush(stderr); + } +} + /* This function just ensure that the yield will be always * returned with a timeout and permit to set some flags */ @@ -3349,6 +3381,85 @@ static int hlua_txn_new(lua_State *L, struct session *s, struct proxy *p, void * return 1; } +__LJMP static int hlua_txn_deflog(lua_State *L) +{ + const char *msg; + struct hlua_txn *htxn; + + MAY_LJMP(check_args(L, 2, "deflog")); + htxn = MAY_LJMP(hlua_checktxn(L, 1)); + msg = MAY_LJMP(luaL_checkstring(L, 2)); + + hlua_sendlog(htxn->s->be, htxn->s->logs.level, msg); + return 0; +} + +__LJMP static int hlua_txn_log(lua_State *L) +{ + int level; + const char *msg; + struct hlua_txn *htxn; + + MAY_LJMP(check_args(L, 3, "log")); + htxn = MAY_LJMP(hlua_checktxn(L, 1)); + level = MAY_LJMP(luaL_checkinteger(L, 2)); + msg = MAY_LJMP(luaL_checkstring(L, 3)); + + if (level < 0 || level >= NB_LOG_LEVELS) + WILL_LJMP(luaL_argerror(L, 1, "Invalid loglevel.")); + + hlua_sendlog(htxn->s->be, level, msg); + return 0; +} + +__LJMP static int hlua_txn_log_debug(lua_State *L) +{ + const char *msg; + struct hlua_txn *htxn; + + MAY_LJMP(check_args(L, 2, "Debug")); + htxn = MAY_LJMP(hlua_checktxn(L, 1)); + msg = MAY_LJMP(luaL_checkstring(L, 2)); + hlua_sendlog(htxn->s->be, LOG_DEBUG, msg); + return 0; +} + +__LJMP static int hlua_txn_log_info(lua_State *L) +{ + const char *msg; + struct hlua_txn *htxn; + + MAY_LJMP(check_args(L, 2, "Info")); + htxn = MAY_LJMP(hlua_checktxn(L, 1)); + msg = MAY_LJMP(luaL_checkstring(L, 2)); + hlua_sendlog(htxn->s->be, LOG_INFO, msg); + return 0; +} + +__LJMP static int hlua_txn_log_warning(lua_State *L) +{ + const char *msg; + struct hlua_txn *htxn; + + MAY_LJMP(check_args(L, 2, "Warning")); + htxn = MAY_LJMP(hlua_checktxn(L, 1)); + msg = MAY_LJMP(luaL_checkstring(L, 2)); + hlua_sendlog(htxn->s->be, LOG_WARNING, msg); + return 0; +} + +__LJMP static int hlua_txn_log_alert(lua_State *L) +{ + const char *msg; + struct hlua_txn *htxn; + + MAY_LJMP(check_args(L, 2, "Alert")); + htxn = MAY_LJMP(hlua_checktxn(L, 1)); + msg = MAY_LJMP(luaL_checkstring(L, 2)); + hlua_sendlog(htxn->s->be, LOG_ALERT, msg); + return 0; +} + __LJMP static int hlua_txn_set_loglevel(lua_State *L) { struct hlua_txn *htxn; @@ -3422,6 +3533,62 @@ __LJMP static int hlua_txn_close(lua_State *L) return 0; } +__LJMP static int hlua_log(lua_State *L) +{ + int level; + const char *msg; + + MAY_LJMP(check_args(L, 2, "log")); + level = MAY_LJMP(luaL_checkinteger(L, 1)); + msg = MAY_LJMP(luaL_checkstring(L, 2)); + + if (level < 0 || level >= NB_LOG_LEVELS) + WILL_LJMP(luaL_argerror(L, 1, "Invalid loglevel.")); + + hlua_sendlog(NULL, level, msg); + return 0; +} + +__LJMP static int hlua_log_debug(lua_State *L) +{ + const char *msg; + + MAY_LJMP(check_args(L, 1, "debug")); + msg = MAY_LJMP(luaL_checkstring(L, 1)); + hlua_sendlog(NULL, LOG_DEBUG, msg); + return 0; +} + +__LJMP static int hlua_log_info(lua_State *L) +{ + const char *msg; + + MAY_LJMP(check_args(L, 1, "info")); + msg = MAY_LJMP(luaL_checkstring(L, 1)); + hlua_sendlog(NULL, LOG_INFO, msg); + return 0; +} + +__LJMP static int hlua_log_warning(lua_State *L) +{ + const char *msg; + + MAY_LJMP(check_args(L, 1, "warning")); + msg = MAY_LJMP(luaL_checkstring(L, 1)); + hlua_sendlog(NULL, LOG_WARNING, msg); + return 0; +} + +__LJMP static int hlua_log_alert(lua_State *L) +{ + const char *msg; + + MAY_LJMP(check_args(L, 1, "alert")); + msg = MAY_LJMP(luaL_checkstring(L, 1)); + hlua_sendlog(NULL, LOG_ALERT, msg); + return 0; +} + __LJMP static int hlua_sleep_yield(lua_State *L, int status, lua_KContext ctx) { int wakeup_ms = lua_tointeger(L, -1); @@ -4429,6 +4596,11 @@ void hlua_init(void) hlua_class_function(gL.T, "set_map", hlua_set_map); hlua_class_function(gL.T, "del_map", hlua_del_map); hlua_class_function(gL.T, "tcp", hlua_socket_new); + hlua_class_function(gL.T, "log", hlua_log); + hlua_class_function(gL.T, "Debug", hlua_log_debug); + hlua_class_function(gL.T, "Info", hlua_log_info); + hlua_class_function(gL.T, "Warning", hlua_log_warning); + hlua_class_function(gL.T, "Alert", hlua_log_alert); lua_setglobal(gL.T, "core"); @@ -4619,6 +4791,12 @@ void hlua_init(void) hlua_class_function(gL.T, "set_loglevel",hlua_txn_set_loglevel); hlua_class_function(gL.T, "set_tos", hlua_txn_set_tos); hlua_class_function(gL.T, "set_mark", hlua_txn_set_mark); + hlua_class_function(gL.T, "deflog", hlua_txn_deflog); + hlua_class_function(gL.T, "log", hlua_txn_log); + hlua_class_function(gL.T, "Debug", hlua_txn_log_debug); + hlua_class_function(gL.T, "Info", hlua_txn_log_info); + hlua_class_function(gL.T, "Warning", hlua_txn_log_warning); + hlua_class_function(gL.T, "Alert", hlua_txn_log_alert); lua_settable(gL.T, -3);