diff options
author | kaiwu <kaiwu2004@gmail.com> | 2025-03-01 12:42:23 +0800 |
---|---|---|
committer | kaiwu <kaiwu2004@gmail.com> | 2025-03-01 12:42:23 +0800 |
commit | 3f33461e4948bf05e60bdff35ec6c57a649c7860 (patch) | |
tree | 284c2ba95a41536ae1bff6bea710db0709a64739 /ngx_stream_lua-0.0.16/src/ngx_stream_lua_log.c | |
download | openresty-3f33461e4948bf05e60bdff35ec6c57a649c7860.tar.gz openresty-3f33461e4948bf05e60bdff35ec6c57a649c7860.zip |
openresty bundle
Diffstat (limited to 'ngx_stream_lua-0.0.16/src/ngx_stream_lua_log.c')
-rw-r--r-- | ngx_stream_lua-0.0.16/src/ngx_stream_lua_log.c | 463 |
1 files changed, 463 insertions, 0 deletions
diff --git a/ngx_stream_lua-0.0.16/src/ngx_stream_lua_log.c b/ngx_stream_lua-0.0.16/src/ngx_stream_lua_log.c new file mode 100644 index 0000000..c6e9c4c --- /dev/null +++ b/ngx_stream_lua-0.0.16/src/ngx_stream_lua_log.c @@ -0,0 +1,463 @@ + +/* + * !!! DO NOT EDIT DIRECTLY !!! + * This file was automatically generated from the following template: + * + * src/subsys/ngx_subsys_lua_log.c.tt2 + */ + + +/* + * Copyright (C) Xiaozhe Wang (chaoslawful) + * Copyright (C) Yichun Zhang (agentzh) + */ + + +#ifndef DDEBUG +#define DDEBUG 0 +#endif +#include "ddebug.h" + + +#include "ngx_stream_lua_log.h" +#include "ngx_stream_lua_util.h" + +#include "ngx_stream_lua_log_ringbuf.h" + + +static int ngx_stream_lua_print(lua_State *L); +static int ngx_stream_lua_ngx_log(lua_State *L); +static int log_wrapper(ngx_log_t *log, const char *ident, + ngx_uint_t level, lua_State *L); +static void ngx_stream_lua_inject_log_consts(lua_State *L); + + +/** + * Wrapper of nginx log functionality. Take a log level param and varargs of + * log message params. + * + * @param L Lua state pointer + * @retval always 0 (don't return values to Lua) + * */ +int +ngx_stream_lua_ngx_log(lua_State *L) +{ + ngx_log_t *log; + ngx_stream_lua_request_t *r; + const char *msg; + int level; + + r = ngx_stream_lua_get_req(L); + + if (r && r->connection && r->connection->log) { + log = r->connection->log; + + } else { + log = ngx_cycle->log; + } + + level = luaL_checkint(L, 1); + if (level < NGX_LOG_STDERR || level > NGX_LOG_DEBUG) { + msg = lua_pushfstring(L, "bad log level: %d", level); + return luaL_argerror(L, 1, msg); + } + + /* remove log-level param from stack */ + lua_remove(L, 1); + + return log_wrapper(log, "stream [lua] ", (ngx_uint_t) level, L); +} + + +/** + * Override Lua print function, output message to nginx error logs. Equal to + * ngx.log(ngx.NOTICE, ...). + * + * @param L Lua state pointer + * @retval always 0 (don't return values to Lua) + * */ +int +ngx_stream_lua_print(lua_State *L) +{ + ngx_log_t *log; + ngx_stream_lua_request_t *r; + + r = ngx_stream_lua_get_req(L); + + if (r && r->connection && r->connection->log) { + log = r->connection->log; + + } else { + log = ngx_cycle->log; + } + + return log_wrapper(log, "stream [lua] ", NGX_LOG_NOTICE, L); +} + + +static int +log_wrapper(ngx_log_t *log, const char *ident, ngx_uint_t level, + lua_State *L) +{ + u_char *buf; + u_char *p, *q; + ngx_str_t name; + int nargs, i; + size_t size, len; + size_t src_len = 0; + int type; + const char *msg; + lua_Debug ar; + + if (level > log->log_level) { + return 0; + } + +#if 1 + /* add debug info */ + + lua_getstack(L, 1, &ar); + lua_getinfo(L, "Snl", &ar); + + /* get the basename of the Lua source file path, stored in q */ + name.data = (u_char *) ar.short_src; + if (name.data == NULL) { + name.len = 0; + + } else { + p = name.data; + while (*p != '\0') { + if (*p == '/' || *p == '\\') { + name.data = p + 1; + } + p++; + } + + name.len = p - name.data; + } + +#endif + + nargs = lua_gettop(L); + + size = name.len + NGX_INT_T_LEN + sizeof(":: ") - 1; + + if (*ar.namewhat != '\0' && *ar.what == 'L') { + src_len = ngx_strlen(ar.name); + size += src_len + sizeof("(): ") - 1; + } + + for (i = 1; i <= nargs; i++) { + type = lua_type(L, i); + switch (type) { + case LUA_TNUMBER: + case LUA_TSTRING: + lua_tolstring(L, i, &len); + size += len; + break; + + case LUA_TNIL: + size += sizeof("nil") - 1; + break; + + case LUA_TBOOLEAN: + if (lua_toboolean(L, i)) { + size += sizeof("true") - 1; + + } else { + size += sizeof("false") - 1; + } + + break; + + case LUA_TTABLE: + if (!luaL_callmeta(L, i, "__tostring")) { + return luaL_argerror(L, i, "expected table to have " + "__tostring metamethod"); + } + + lua_tolstring(L, -1, &len); + size += len; + break; + + case LUA_TLIGHTUSERDATA: + if (lua_touserdata(L, i) == NULL) { + size += sizeof("null") - 1; + break; + } + + continue; + + default: + msg = lua_pushfstring(L, "string, number, boolean, or nil " + "expected, got %s", + lua_typename(L, type)); + return luaL_argerror(L, i, msg); + } + } + + buf = lua_newuserdata(L, size); + + p = ngx_copy(buf, name.data, name.len); + + *p++ = ':'; + + p = ngx_snprintf(p, NGX_INT_T_LEN, "%d", + ar.currentline > 0 ? ar.currentline : ar.linedefined); + + *p++ = ':'; *p++ = ' '; + + if (*ar.namewhat != '\0' && *ar.what == 'L') { + p = ngx_copy(p, ar.name, src_len); + *p++ = '('; + *p++ = ')'; + *p++ = ':'; + *p++ = ' '; + } + + for (i = 1; i <= nargs; i++) { + type = lua_type(L, i); + switch (type) { + case LUA_TNUMBER: + case LUA_TSTRING: + q = (u_char *) lua_tolstring(L, i, &len); + p = ngx_copy(p, q, len); + break; + + case LUA_TNIL: + *p++ = 'n'; + *p++ = 'i'; + *p++ = 'l'; + break; + + case LUA_TBOOLEAN: + if (lua_toboolean(L, i)) { + *p++ = 't'; + *p++ = 'r'; + *p++ = 'u'; + *p++ = 'e'; + + } else { + *p++ = 'f'; + *p++ = 'a'; + *p++ = 'l'; + *p++ = 's'; + *p++ = 'e'; + } + + break; + + case LUA_TTABLE: + luaL_callmeta(L, i, "__tostring"); + q = (u_char *) lua_tolstring(L, -1, &len); + p = ngx_copy(p, q, len); + break; + + case LUA_TLIGHTUSERDATA: + *p++ = 'n'; + *p++ = 'u'; + *p++ = 'l'; + *p++ = 'l'; + + break; + + default: + return luaL_error(L, "impossible to reach here"); + } + } + + if (p - buf > (off_t) size) { + return luaL_error(L, "buffer error: %d > %d", (int) (p - buf), + (int) size); + } + + ngx_log_error(level, log, 0, "%s%*s", ident, (size_t) (p - buf), buf); + + return 0; +} + + +void +ngx_stream_lua_inject_log_api(lua_State *L) +{ + ngx_stream_lua_inject_log_consts(L); + + lua_pushcfunction(L, ngx_stream_lua_ngx_log); + lua_setfield(L, -2, "log"); + + lua_pushcfunction(L, ngx_stream_lua_print); + lua_setglobal(L, "print"); +} + + +static void +ngx_stream_lua_inject_log_consts(lua_State *L) +{ + /* {{{ nginx log level constants */ + lua_pushinteger(L, NGX_LOG_STDERR); + lua_setfield(L, -2, "STDERR"); + + lua_pushinteger(L, NGX_LOG_EMERG); + lua_setfield(L, -2, "EMERG"); + + lua_pushinteger(L, NGX_LOG_ALERT); + lua_setfield(L, -2, "ALERT"); + + lua_pushinteger(L, NGX_LOG_CRIT); + lua_setfield(L, -2, "CRIT"); + + lua_pushinteger(L, NGX_LOG_ERR); + lua_setfield(L, -2, "ERR"); + + lua_pushinteger(L, NGX_LOG_WARN); + lua_setfield(L, -2, "WARN"); + + lua_pushinteger(L, NGX_LOG_NOTICE); + lua_setfield(L, -2, "NOTICE"); + + lua_pushinteger(L, NGX_LOG_INFO); + lua_setfield(L, -2, "INFO"); + + lua_pushinteger(L, NGX_LOG_DEBUG); + lua_setfield(L, -2, "DEBUG"); + /* }}} */ +} + + +#ifdef HAVE_INTERCEPT_ERROR_LOG_PATCH +ngx_int_t +ngx_stream_lua_capture_log_handler(ngx_log_t *log, + ngx_uint_t level, u_char *buf, size_t n) +{ + ngx_stream_lua_log_ringbuf_t *ringbuf; + + dd("enter"); + + ringbuf = (ngx_stream_lua_log_ringbuf_t *) + ngx_cycle->intercept_error_log_data; + + if (level > ringbuf->filter_level) { + return NGX_OK; + } + + ngx_stream_lua_log_ringbuf_write(ringbuf, level, buf, n); + + dd("capture log: %s\n", buf); + + return NGX_OK; +} +#endif + + +int +ngx_stream_lua_ffi_errlog_set_filter_level(int level, u_char *err, + size_t *errlen) +{ +#ifdef HAVE_INTERCEPT_ERROR_LOG_PATCH + ngx_stream_lua_log_ringbuf_t *ringbuf; + + ringbuf = ngx_cycle->intercept_error_log_data; + + if (ringbuf == NULL) { + *errlen = ngx_snprintf(err, *errlen, + "directive \"lua_capture_error_log\" is not set") + - err; + return NGX_ERROR; + } + + if (level > NGX_LOG_DEBUG || level < NGX_LOG_STDERR) { + *errlen = ngx_snprintf(err, *errlen, "bad log level: %d", level) + - err; + return NGX_ERROR; + } + + ringbuf->filter_level = level; + return NGX_OK; +#else + *errlen = ngx_snprintf(err, *errlen, + "missing the capture error log patch for nginx") + - err; + return NGX_ERROR; +#endif +} + + +int +ngx_stream_lua_ffi_errlog_get_msg(char **log, int *loglevel, u_char *err, + size_t *errlen, double *log_time) +{ +#ifdef HAVE_INTERCEPT_ERROR_LOG_PATCH + ngx_uint_t loglen; + + ngx_stream_lua_log_ringbuf_t *ringbuf; + + ringbuf = ngx_cycle->intercept_error_log_data; + + if (ringbuf == NULL) { + *errlen = ngx_snprintf(err, *errlen, + "directive \"lua_capture_error_log\" is not set") + - err; + return NGX_ERROR; + } + + if (ringbuf->count == 0) { + return NGX_DONE; + } + + ngx_stream_lua_log_ringbuf_read(ringbuf, loglevel, (void **) log, &loglen, + log_time); + return loglen; +#else + *errlen = ngx_snprintf(err, *errlen, + "missing the capture error log patch for nginx") + - err; + return NGX_ERROR; +#endif +} + + +int +ngx_stream_lua_ffi_errlog_get_sys_filter_level(ngx_stream_lua_request_t *r) +{ + ngx_log_t *log; + int log_level; + + if (r && r->connection && r->connection->log) { + log = r->connection->log; + + } else { + log = ngx_cycle->log; + } + + log_level = log->log_level; + if (log_level == NGX_LOG_DEBUG_ALL) { + log_level = NGX_LOG_DEBUG; + } + + return log_level; +} + + +int +ngx_stream_lua_ffi_raw_log(ngx_stream_lua_request_t *r, int level, u_char *s, + size_t s_len) +{ + ngx_log_t *log; + + if (level > NGX_LOG_DEBUG || level < NGX_LOG_STDERR) { + return NGX_ERROR; + } + + if (r && r->connection && r->connection->log) { + log = r->connection->log; + + } else { + log = ngx_cycle->log; + } + + ngx_log_error((unsigned) level, log, 0, "%*s", s_len, s); + + return NGX_OK; +} + +/* vi:set ft=c ts=4 sw=4 et fdm=marker: */ |