LCOV - code coverage report
Current view: top level - home/build/openresty-1.13.6.1/build/ngx_lua-0.10.11/src - ngx_http_lua_log.c (source / functions) Hit Total Coverage
Test: coverage ngix Lines: 27 183 14.8 %
Date: 2020-03-03 04:25:50 Functions: 2 9 22.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : /*
       3             :  * Copyright (C) Xiaozhe Wang (chaoslawful)
       4             :  * Copyright (C) Yichun Zhang (agentzh)
       5             :  */
       6             : 
       7             : 
       8             : #ifndef DDEBUG
       9             : #define DDEBUG 0
      10             : #endif
      11             : #include "ddebug.h"
      12             : 
      13             : 
      14             : #include "ngx_http_lua_log.h"
      15             : #include "ngx_http_lua_util.h"
      16             : #include "ngx_http_lua_log_ringbuf.h"
      17             : 
      18             : 
      19             : static int ngx_http_lua_print(lua_State *L);
      20             : static int ngx_http_lua_ngx_log(lua_State *L);
      21             : static int log_wrapper(ngx_log_t *log, const char *ident,
      22             :     ngx_uint_t level, lua_State *L);
      23             : static void ngx_http_lua_inject_log_consts(lua_State *L);
      24             : 
      25             : 
      26             : /**
      27             :  * Wrapper of nginx log functionality. Take a log level param and varargs of
      28             :  * log message params.
      29             :  *
      30             :  * @param L Lua state pointer
      31             :  * @retval always 0 (don't return values to Lua)
      32             :  * */
      33             : int
      34           0 : ngx_http_lua_ngx_log(lua_State *L)
      35             : {
      36             :     ngx_log_t                   *log;
      37             :     ngx_http_request_t          *r;
      38             :     const char                  *msg;
      39             :     int                          level;
      40             : 
      41           0 :     r = ngx_http_lua_get_req(L);
      42             : 
      43           0 :     if (r && r->connection && r->connection->log) {
      44           0 :         log = r->connection->log;
      45             : 
      46             :     } else {
      47           0 :         log = ngx_cycle->log;
      48             :     }
      49             : 
      50           0 :     level = luaL_checkint(L, 1);
      51           0 :     if (level < NGX_LOG_STDERR || level > NGX_LOG_DEBUG) {
      52           0 :         msg = lua_pushfstring(L, "bad log level: %d", level);
      53           0 :         return luaL_argerror(L, 1, msg);
      54             :     }
      55             : 
      56             :     /* remove log-level param from stack */
      57           0 :     lua_remove(L, 1);
      58             : 
      59           0 :     return log_wrapper(log, "[lua] ", (ngx_uint_t) level, L);
      60             : }
      61             : 
      62             : 
      63             : /**
      64             :  * Override Lua print function, output message to nginx error logs. Equal to
      65             :  * ngx.log(ngx.NOTICE, ...).
      66             :  *
      67             :  * @param L Lua state pointer
      68             :  * @retval always 0 (don't return values to Lua)
      69             :  * */
      70             : int
      71           0 : ngx_http_lua_print(lua_State *L)
      72             : {
      73             :     ngx_log_t                   *log;
      74             :     ngx_http_request_t          *r;
      75             : 
      76           0 :     r = ngx_http_lua_get_req(L);
      77             : 
      78           0 :     if (r && r->connection && r->connection->log) {
      79           0 :         log = r->connection->log;
      80             : 
      81             :     } else {
      82           0 :         log = ngx_cycle->log;
      83             :     }
      84             : 
      85           0 :     return log_wrapper(log, "[lua] ", NGX_LOG_NOTICE, L);
      86             : }
      87             : 
      88             : 
      89             : static int
      90           0 : log_wrapper(ngx_log_t *log, const char *ident, ngx_uint_t level,
      91             :     lua_State *L)
      92             : {
      93             :     u_char              *buf;
      94             :     u_char              *p, *q;
      95             :     ngx_str_t            name;
      96             :     int                  nargs, i;
      97             :     size_t               size, len;
      98           0 :     size_t               src_len = 0;
      99             :     int                  type;
     100             :     const char          *msg;
     101             :     lua_Debug            ar;
     102             : 
     103           0 :     if (level > log->log_level) {
     104           0 :         return 0;
     105             :     }
     106             : 
     107             : #if 1
     108             :     /* add debug info */
     109             : 
     110           0 :     lua_getstack(L, 1, &ar);
     111           0 :     lua_getinfo(L, "Snl", &ar);
     112             : 
     113             :     /* get the basename of the Lua source file path, stored in q */
     114           0 :     name.data = (u_char *) ar.short_src;
     115           0 :     if (name.data == NULL) {
     116           0 :         name.len = 0;
     117             : 
     118             :     } else {
     119           0 :         p = name.data;
     120           0 :         while (*p != '\0') {
     121           0 :             if (*p == '/' || *p == '\\') {
     122           0 :                 name.data = p + 1;
     123             :             }
     124           0 :             p++;
     125             :         }
     126             : 
     127           0 :         name.len = p - name.data;
     128             :     }
     129             : 
     130             : #endif
     131             : 
     132           0 :     nargs = lua_gettop(L);
     133             : 
     134           0 :     size = name.len + NGX_INT_T_LEN + sizeof(":: ") - 1;
     135             : 
     136           0 :     if (*ar.namewhat != '\0' && *ar.what == 'L') {
     137           0 :         src_len = ngx_strlen(ar.name);
     138           0 :         size += src_len + sizeof("(): ") - 1;
     139             :     }
     140             : 
     141           0 :     for (i = 1; i <= nargs; i++) {
     142           0 :         type = lua_type(L, i);
     143           0 :         switch (type) {
     144           0 :             case LUA_TNUMBER:
     145             :             case LUA_TSTRING:
     146           0 :                 lua_tolstring(L, i, &len);
     147           0 :                 size += len;
     148           0 :                 break;
     149             : 
     150           0 :             case LUA_TNIL:
     151           0 :                 size += sizeof("nil") - 1;
     152           0 :                 break;
     153             : 
     154           0 :             case LUA_TBOOLEAN:
     155           0 :                 if (lua_toboolean(L, i)) {
     156           0 :                     size += sizeof("true") - 1;
     157             : 
     158             :                 } else {
     159           0 :                     size += sizeof("false") - 1;
     160             :                 }
     161             : 
     162           0 :                 break;
     163             : 
     164           0 :             case LUA_TTABLE:
     165           0 :                 if (!luaL_callmeta(L, i, "__tostring")) {
     166           0 :                     return luaL_argerror(L, i, "expected table to have "
     167             :                                          "__tostring metamethod");
     168             :                 }
     169             : 
     170           0 :                 lua_tolstring(L, -1, &len);
     171           0 :                 size += len;
     172           0 :                 break;
     173             : 
     174           0 :             case LUA_TLIGHTUSERDATA:
     175           0 :                 if (lua_touserdata(L, i) == NULL) {
     176           0 :                     size += sizeof("null") - 1;
     177           0 :                     break;
     178             :                 }
     179             : 
     180           0 :                 continue;
     181             : 
     182           0 :             default:
     183           0 :                 msg = lua_pushfstring(L, "string, number, boolean, or nil "
     184             :                                       "expected, got %s",
     185             :                                       lua_typename(L, type));
     186           0 :                 return luaL_argerror(L, i, msg);
     187             :         }
     188             :     }
     189             : 
     190           0 :     buf = lua_newuserdata(L, size);
     191             : 
     192           0 :     p = ngx_copy(buf, name.data, name.len);
     193             : 
     194           0 :     *p++ = ':';
     195             : 
     196           0 :     p = ngx_snprintf(p, NGX_INT_T_LEN, "%d",
     197           0 :                      ar.currentline ? ar.currentline : ar.linedefined);
     198             : 
     199           0 :     *p++ = ':'; *p++ = ' ';
     200             : 
     201           0 :     if (*ar.namewhat != '\0' && *ar.what == 'L') {
     202           0 :         p = ngx_copy(p, ar.name, src_len);
     203           0 :         *p++ = '(';
     204           0 :         *p++ = ')';
     205           0 :         *p++ = ':';
     206           0 :         *p++ = ' ';
     207             :     }
     208             : 
     209           0 :     for (i = 1; i <= nargs; i++) {
     210           0 :         type = lua_type(L, i);
     211           0 :         switch (type) {
     212           0 :             case LUA_TNUMBER:
     213             :             case LUA_TSTRING:
     214           0 :                 q = (u_char *) lua_tolstring(L, i, &len);
     215           0 :                 p = ngx_copy(p, q, len);
     216           0 :                 break;
     217             : 
     218           0 :             case LUA_TNIL:
     219           0 :                 *p++ = 'n';
     220           0 :                 *p++ = 'i';
     221           0 :                 *p++ = 'l';
     222           0 :                 break;
     223             : 
     224           0 :             case LUA_TBOOLEAN:
     225           0 :                 if (lua_toboolean(L, i)) {
     226           0 :                     *p++ = 't';
     227           0 :                     *p++ = 'r';
     228           0 :                     *p++ = 'u';
     229           0 :                     *p++ = 'e';
     230             : 
     231             :                 } else {
     232           0 :                     *p++ = 'f';
     233           0 :                     *p++ = 'a';
     234           0 :                     *p++ = 'l';
     235           0 :                     *p++ = 's';
     236           0 :                     *p++ = 'e';
     237             :                 }
     238             : 
     239           0 :                 break;
     240             : 
     241           0 :             case LUA_TTABLE:
     242           0 :                 luaL_callmeta(L, i, "__tostring");
     243           0 :                 q = (u_char *) lua_tolstring(L, -1, &len);
     244           0 :                 p = ngx_copy(p, q, len);
     245           0 :                 break;
     246             : 
     247           0 :             case LUA_TLIGHTUSERDATA:
     248           0 :                 *p++ = 'n';
     249           0 :                 *p++ = 'u';
     250           0 :                 *p++ = 'l';
     251           0 :                 *p++ = 'l';
     252             : 
     253           0 :                 break;
     254             : 
     255           0 :             default:
     256           0 :                 return luaL_error(L, "impossible to reach here");
     257             :         }
     258             :     }
     259             : 
     260           0 :     if (p - buf > (off_t) size) {
     261           0 :         return luaL_error(L, "buffer error: %d > %d", (int) (p - buf),
     262             :                           (int) size);
     263             :     }
     264             : 
     265           0 :     ngx_log_error(level, log, 0, "%s%*s", ident, (size_t) (p - buf), buf);
     266             : 
     267           0 :     return 0;
     268             : }
     269             : 
     270             : 
     271             : void
     272          18 : ngx_http_lua_inject_log_api(lua_State *L)
     273             : {
     274          18 :     ngx_http_lua_inject_log_consts(L);
     275             : 
     276          18 :     lua_pushcfunction(L, ngx_http_lua_ngx_log);
     277          18 :     lua_setfield(L, -2, "log");
     278             : 
     279          18 :     lua_pushcfunction(L, ngx_http_lua_print);
     280          18 :     lua_setglobal(L, "print");
     281          18 : }
     282             : 
     283             : 
     284             : static void
     285          18 : ngx_http_lua_inject_log_consts(lua_State *L)
     286             : {
     287             :     /* {{{ nginx log level constants */
     288          18 :     lua_pushinteger(L, NGX_LOG_STDERR);
     289          18 :     lua_setfield(L, -2, "STDERR");
     290             : 
     291          18 :     lua_pushinteger(L, NGX_LOG_EMERG);
     292          18 :     lua_setfield(L, -2, "EMERG");
     293             : 
     294          18 :     lua_pushinteger(L, NGX_LOG_ALERT);
     295          18 :     lua_setfield(L, -2, "ALERT");
     296             : 
     297          18 :     lua_pushinteger(L, NGX_LOG_CRIT);
     298          18 :     lua_setfield(L, -2, "CRIT");
     299             : 
     300          18 :     lua_pushinteger(L, NGX_LOG_ERR);
     301          18 :     lua_setfield(L, -2, "ERR");
     302             : 
     303          18 :     lua_pushinteger(L, NGX_LOG_WARN);
     304          18 :     lua_setfield(L, -2, "WARN");
     305             : 
     306          18 :     lua_pushinteger(L, NGX_LOG_NOTICE);
     307          18 :     lua_setfield(L, -2, "NOTICE");
     308             : 
     309          18 :     lua_pushinteger(L, NGX_LOG_INFO);
     310          18 :     lua_setfield(L, -2, "INFO");
     311             : 
     312          18 :     lua_pushinteger(L, NGX_LOG_DEBUG);
     313          18 :     lua_setfield(L, -2, "DEBUG");
     314             :     /* }}} */
     315          18 : }
     316             : 
     317             : 
     318             : #ifdef HAVE_INTERCEPT_ERROR_LOG_PATCH
     319             : ngx_int_t
     320           0 : ngx_http_lua_capture_log_handler(ngx_log_t *log,
     321             :     ngx_uint_t level, u_char *buf, size_t n)
     322             : {
     323             :     ngx_http_lua_log_ringbuf_t  *ringbuf;
     324             : 
     325             :     dd("enter");
     326             : 
     327           0 :     ringbuf = (ngx_http_lua_log_ringbuf_t  *)
     328           0 :                     ngx_cycle->intercept_error_log_data;
     329             : 
     330           0 :     if (level > ringbuf->filter_level) {
     331           0 :         return NGX_OK;
     332             :     }
     333             : 
     334           0 :     ngx_http_lua_log_ringbuf_write(ringbuf, level, buf, n);
     335             : 
     336             :     dd("capture log: %s\n", buf);
     337             : 
     338           0 :     return NGX_OK;
     339             : }
     340             : #endif
     341             : 
     342             : 
     343             : #ifndef NGX_LUA_NO_FFI_API
     344             : int
     345           0 : ngx_http_lua_ffi_errlog_set_filter_level(int level, u_char *err, size_t *errlen)
     346             : {
     347             : #ifdef HAVE_INTERCEPT_ERROR_LOG_PATCH
     348             :     ngx_http_lua_log_ringbuf_t     *ringbuf;
     349             : 
     350           0 :     ringbuf = ngx_cycle->intercept_error_log_data;
     351             : 
     352           0 :     if (ringbuf == NULL) {
     353           0 :         *errlen = ngx_snprintf(err, *errlen,
     354             :                                "directive \"lua_capture_error_log\" is not set")
     355           0 :                   - err;
     356           0 :         return NGX_ERROR;
     357             :     }
     358             : 
     359           0 :     if (level > NGX_LOG_DEBUG || level < NGX_LOG_STDERR) {
     360           0 :         *errlen = ngx_snprintf(err, *errlen, "bad log level: %d", level)
     361           0 :                   - err;
     362           0 :         return NGX_ERROR;
     363             :     }
     364             : 
     365           0 :     ringbuf->filter_level = level;
     366           0 :     return NGX_OK;
     367             : #else
     368             :     *errlen = ngx_snprintf(err, *errlen,
     369             :                            "missing the capture error log patch for nginx")
     370             :               - err;
     371             :     return NGX_ERROR;
     372             : #endif
     373             : }
     374             : 
     375             : 
     376             : int
     377           0 : ngx_http_lua_ffi_errlog_get_msg(char **log, int *loglevel, u_char *err,
     378             :     size_t *errlen, double *log_time)
     379             : {
     380             : #ifdef HAVE_INTERCEPT_ERROR_LOG_PATCH
     381             :     ngx_uint_t           loglen;
     382             : 
     383             :     ngx_http_lua_log_ringbuf_t     *ringbuf;
     384             : 
     385           0 :     ringbuf = ngx_cycle->intercept_error_log_data;
     386             : 
     387           0 :     if (ringbuf == NULL) {
     388           0 :         *errlen = ngx_snprintf(err, *errlen,
     389             :                                "directive \"lua_capture_error_log\" is not set")
     390           0 :                   - err;
     391           0 :         return NGX_ERROR;
     392             :     }
     393             : 
     394           0 :     if (ringbuf->count == 0) {
     395           0 :         return NGX_DONE;
     396             :     }
     397             : 
     398           0 :     ngx_http_lua_log_ringbuf_read(ringbuf, loglevel, (void **) log, &loglen,
     399             :                                   log_time);
     400           0 :     return loglen;
     401             : #else
     402             :     *errlen = ngx_snprintf(err, *errlen,
     403             :                            "missing the capture error log patch for nginx")
     404             :               - err;
     405             :     return NGX_ERROR;
     406             : #endif
     407             : }
     408             : 
     409             : 
     410             : int
     411           0 : ngx_http_lua_ffi_errlog_get_sys_filter_level(ngx_http_request_t *r)
     412             : {
     413             :     ngx_log_t                   *log;
     414             :     int                          log_level;
     415             : 
     416           0 :     if (r && r->connection && r->connection->log) {
     417           0 :         log = r->connection->log;
     418             : 
     419             :     } else {
     420           0 :         log = ngx_cycle->log;
     421             :     }
     422             : 
     423           0 :     log_level = log->log_level;
     424           0 :     if (log_level == NGX_LOG_DEBUG_ALL) {
     425           0 :         log_level = NGX_LOG_DEBUG;
     426             :     }
     427             : 
     428           0 :     return log_level;
     429             : }
     430             : 
     431             : #endif
     432             : 
     433             : /* vi:set ft=c ts=4 sw=4 et fdm=marker: */

Generated by: LCOV version 1.13