[njs] Added generic logger callback.

Dmitry Volyntsev xeioex at nginx.com
Tue Jul 26 01:41:26 UTC 2022


details:   https://hg.nginx.org/njs/rev/14426cb84197
branches:  
changeset: 1917:14426cb84197
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Mon Jul 25 18:40:24 2022 -0700
description:
Added generic logger callback.

This allows for a host environment to control when and
how internal NJS messages are logged.

diffstat:

 nginx/ngx_http_js_module.c   |   1 +
 nginx/ngx_js.c               |  15 +++++++++++++++
 nginx/ngx_js.h               |   2 ++
 nginx/ngx_stream_js_module.c |   1 +
 src/njs.h                    |  19 +++++++++++++++++++
 src/njs_shell.c              |  38 +++++++++++++++++++++++++++-----------
 src/njs_vm.c                 |  26 ++++++++++++++++++++++++++
 7 files changed, 91 insertions(+), 11 deletions(-)

diffs (274 lines):

diff -r 4b8d8237f598 -r 14426cb84197 nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.c	Thu Jul 21 18:33:20 2022 -0700
+++ b/nginx/ngx_http_js_module.c	Mon Jul 25 18:40:24 2022 -0700
@@ -783,6 +783,7 @@ static njs_vm_ops_t ngx_http_js_ops = {
     ngx_http_js_set_timer,
     ngx_http_js_clear_timer,
     NULL,
+    ngx_js_logger,
 };
 
 
diff -r 4b8d8237f598 -r 14426cb84197 nginx/ngx_js.c
--- a/nginx/ngx_js.c	Thu Jul 21 18:33:20 2022 -0700
+++ b/nginx/ngx_js.c	Mon Jul 25 18:40:24 2022 -0700
@@ -318,3 +318,18 @@ ngx_js_ext_log(njs_vm_t *vm, njs_value_t
 }
 
 
+void
+ngx_js_logger(njs_vm_t *vm, njs_external_ptr_t external, njs_log_level_t level,
+    const u_char *start, size_t length)
+{
+    ngx_connection_t    *c;
+    ngx_log_handler_pt   handler;
+
+    c = ngx_external_connection(vm, external);
+    handler = c->log->handler;
+    c->log->handler = NULL;
+
+    ngx_log_error((ngx_uint_t) level, c->log, 0, "js: %*s", length, start);
+
+    c->log->handler = handler;
+}
diff -r 4b8d8237f598 -r 14426cb84197 nginx/ngx_js.h
--- a/nginx/ngx_js.h	Thu Jul 21 18:33:20 2022 -0700
+++ b/nginx/ngx_js.h	Mon Jul 25 18:40:24 2022 -0700
@@ -68,6 +68,8 @@ ngx_int_t ngx_js_retval(njs_vm_t *vm, nj
 
 njs_int_t ngx_js_ext_log(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t level);
+void ngx_js_logger(njs_vm_t *vm, njs_external_ptr_t external,
+    njs_log_level_t level, const u_char *start, size_t length);
 
 njs_int_t ngx_js_ext_string(njs_vm_t *vm, njs_object_prop_t *prop,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
diff -r 4b8d8237f598 -r 14426cb84197 nginx/ngx_stream_js_module.c
--- a/nginx/ngx_stream_js_module.c	Thu Jul 21 18:33:20 2022 -0700
+++ b/nginx/ngx_stream_js_module.c	Mon Jul 25 18:40:24 2022 -0700
@@ -499,6 +499,7 @@ static njs_vm_ops_t ngx_stream_js_ops = 
     ngx_stream_js_set_timer,
     ngx_stream_js_clear_timer,
     NULL,
+    ngx_js_logger,
 };
 
 
diff -r 4b8d8237f598 -r 14426cb84197 src/njs.h
--- a/src/njs.h	Thu Jul 21 18:33:20 2022 -0700
+++ b/src/njs.h	Mon Jul 25 18:40:24 2022 -0700
@@ -45,6 +45,11 @@ typedef struct {
     uint64_t                        filler[2];
 } njs_opaque_value_t;
 
+typedef enum {
+    NJS_LOG_LEVEL_ERROR = 4,
+    NJS_LOG_LEVEL_WARN = 5,
+    NJS_LOG_LEVEL_INFO = 7,
+} njs_log_level_t;
 
 /* sizeof(njs_value_t) is 16 bytes. */
 #define njs_argument(args, n)                                                 \
@@ -69,6 +74,12 @@ extern const njs_value_t            njs_
 #define njs_vm_error(vm, fmt, ...)                                            \
     njs_vm_value_error_set(vm, njs_vm_retval(vm), fmt, ##__VA_ARGS__)
 
+#define njs_vm_log(vm, fmt, ...)  njs_vm_logger(vm, NJS_LOG_LEVEL_INFO, fmt,  \
+                                                ##__VA_ARGS__)
+#define njs_vm_warn(vm, fmt, ...)  njs_vm_logger(vm, NJS_LOG_LEVEL_WARN, fmt, \
+                                                ##__VA_ARGS__)
+#define njs_vm_err(vm, fmt, ...)  njs_vm_logger(vm, NJS_LOG_LEVEL_ERROR, fmt, \
+                                                ##__VA_ARGS__)
 
 /*
  * njs_prop_handler_t operates as a property getter/setter or delete handler.
@@ -187,12 +198,15 @@ typedef void (*njs_event_destructor_t)(n
     njs_host_event_t event);
 typedef njs_mod_t *(*njs_module_loader_t)(njs_vm_t *vm,
     njs_external_ptr_t external, njs_str_t *name);
+typedef void (*njs_logger_t)(njs_vm_t *vm, njs_external_ptr_t external,
+    njs_log_level_t level, const u_char *start, size_t length);
 
 
 typedef struct {
     njs_set_timer_t                 set_timer;
     njs_event_destructor_t          clear_timer;
     njs_module_loader_t             module_loader;
+    njs_logger_t                    logger;
 } njs_vm_ops_t;
 
 
@@ -221,6 +235,8 @@ typedef struct {
     char                            **argv;
     njs_uint_t                      argc;
 
+    njs_log_level_t                 log_level;
+
 #define NJS_VM_OPT_UNHANDLED_REJECTION_IGNORE   0
 #define NJS_VM_OPT_UNHANDLED_REJECTION_THROW    1
 
@@ -401,6 +417,9 @@ NJS_EXPORT void njs_vm_value_error_set(n
     const char *fmt, ...);
 NJS_EXPORT void njs_vm_memory_error(njs_vm_t *vm);
 
+NJS_EXPORT void njs_vm_logger(njs_vm_t *vm, njs_log_level_t level,
+    const char *fmt, ...);
+
 NJS_EXPORT void njs_value_undefined_set(njs_value_t *value);
 NJS_EXPORT void njs_value_null_set(njs_value_t *value);
 NJS_EXPORT void njs_value_invalid_set(njs_value_t *value);
diff -r 4b8d8237f598 -r 14426cb84197 src/njs_shell.c
--- a/src/njs_shell.c	Thu Jul 21 18:33:20 2022 -0700
+++ b/src/njs_shell.c	Mon Jul 25 18:40:24 2022 -0700
@@ -121,6 +121,8 @@ static njs_host_event_t njs_console_set_
 
 static void njs_console_clear_timer(njs_external_ptr_t external,
     njs_host_event_t event);
+static void njs_console_log(njs_vm_t *vm, njs_external_ptr_t external,
+    njs_log_level_t level, const u_char *start, size_t length);
 
 static njs_int_t njs_timelabel_hash_test(njs_lvlhsh_query_t *lhq, void *data);
 
@@ -207,6 +209,7 @@ static njs_vm_ops_t njs_console_ops = {
     njs_console_set_timer,
     njs_console_clear_timer,
     NULL,
+    njs_console_log,
 };
 
 
@@ -1204,14 +1207,14 @@ njs_ext_console_log(njs_vm_t *vm, njs_va
             return NJS_ERROR;
         }
 
-        njs_printf("%s", (n != 1) ? " " : "");
-        njs_print(msg.start, msg.length);
+        njs_vm_log(vm, "%s", (n != 1) ? " " : "");
+        njs_vm_log(vm, "%*s", msg.length, msg.start);
 
         n++;
     }
 
     if (nargs > 1) {
-        njs_printf("\n");
+        njs_vm_log(vm, "\n");
     }
 
     njs_set_undefined(&vm->retval);
@@ -1284,7 +1287,7 @@ njs_ext_console_time(njs_vm_t *vm, njs_v
             return NJS_ERROR;
         }
 
-        njs_printf("Timer \"%V\" already exists.\n", &name);
+        njs_vm_log(vm, "Timer \"%V\" already exists.\n", &name);
 
         label = lhq.value;
     }
@@ -1349,7 +1352,7 @@ njs_ext_console_time_end(njs_vm_t *vm, n
         ms = ns / 1000000;
         ns = ns % 1000000;
 
-        njs_printf("%V: %uL.%06uLms\n", &name, ms, ns);
+        njs_vm_log(vm, "%V: %uL.%06uLms\n", &name, ms, ns);
 
         /* GC: release. */
         njs_mp_free(vm->mem_pool, label);
@@ -1361,7 +1364,7 @@ njs_ext_console_time_end(njs_vm_t *vm, n
             return NJS_ERROR;
         }
 
-        njs_printf("Timer \"%V\" doesn’t exist.\n", &name);
+        njs_vm_log(vm, "Timer \"%V\" doesn’t exist.\n", &name);
     }
 
     njs_set_undefined(&vm->retval);
@@ -1380,14 +1383,14 @@ njs_console_set_timer(njs_external_ptr_t
     njs_console_t       *console;
     njs_lvlhsh_query_t  lhq;
 
+    console = external;
+    vm = console->vm;
+
     if (delay != 0) {
-        njs_stderror("njs_console_set_timer(): async timers unsupported\n");
+        njs_vm_err(vm, "njs_console_set_timer(): async timers unsupported\n");
         return NULL;
     }
 
-    console = external;
-    vm = console->vm;
-
     ev = njs_mp_alloc(vm->mem_pool, sizeof(njs_ev_t));
     if (njs_slow_path(ev == NULL)) {
         return NULL;
@@ -1441,13 +1444,26 @@ njs_console_clear_timer(njs_external_ptr
 
     ret = njs_lvlhsh_delete(&console->events, &lhq);
     if (ret != NJS_OK) {
-        njs_stderror("njs_lvlhsh_delete() failed\n");
+        njs_vm_err(vm, "njs_lvlhsh_delete() failed\n");
     }
 
     njs_mp_free(vm->mem_pool, ev);
 }
 
 
+static void
+njs_console_log(njs_vm_t *vm, njs_external_ptr_t external,
+    njs_log_level_t level, const u_char *start, size_t length)
+{
+    if (level == NJS_LOG_LEVEL_ERROR) {
+        njs_stderror("%*s", length, start);
+
+    } else {
+        njs_printf("%*s", length, start);
+    }
+}
+
+
 static njs_int_t
 njs_timelabel_hash_test(njs_lvlhsh_query_t *lhq, void *data)
 {
diff -r 4b8d8237f598 -r 14426cb84197 src/njs_vm.c
--- a/src/njs_vm.c	Thu Jul 21 18:33:20 2022 -0700
+++ b/src/njs_vm.c	Mon Jul 25 18:40:24 2022 -0700
@@ -23,6 +23,8 @@ void
 njs_vm_opt_init(njs_vm_opt_t *options)
 {
     njs_memzero(options, sizeof(njs_vm_opt_t));
+
+    options->log_level = NJS_LOG_LEVEL_INFO;
 }
 
 
@@ -881,6 +883,30 @@ njs_vm_memory_error(njs_vm_t *vm)
 }
 
 
+njs_noinline void
+njs_vm_logger(njs_vm_t *vm, njs_log_level_t level, const char *fmt, ...)
+{
+    u_char        *p;
+    va_list       args;
+    njs_logger_t  logger;
+    u_char        buf[NJS_MAX_ERROR_STR];
+
+    if (vm->options.ops == NULL) {
+        return;
+    }
+
+    logger = vm->options.ops->logger;
+
+    if (logger != NULL && vm->options.log_level >= level) {
+        va_start(args, fmt);
+        p = njs_vsprintf(buf, buf + sizeof(buf), fmt, args);
+        va_end(args);
+
+        logger(vm, vm->external, level, buf, p - buf);
+    }
+}
+
+
 njs_int_t
 njs_vm_value_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
 {


More information about the nginx-devel mailing list