summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorAndrew Clayton <a.clayton@nginx.com>2024-06-28 21:09:37 +0100
committerAndrew Clayton <a.clayton@nginx.com>2024-07-12 16:44:54 +0100
commit707f4ef821f82eb772728f687e41afc9d6945f98 (patch)
tree80b98453af013e255637706214e4c4e764c72ed2 /src
parent55041ef9607c073bc5e1b431ec271e9c23200cb1 (diff)
downloadunit-707f4ef821f82eb772728f687e41afc9d6945f98.tar.gz
unit-707f4ef821f82eb772728f687e41afc9d6945f98.tar.bz2
status: Show list of loaded language modules
When querying the '/status' node in the control API, display the list of currently loaded modules. So we now get something like { "modules": { "python": [ { "version": "3.12.3", "lib": "/opt/unit/modules/python.unit.so" }, { "version": "3.12.1", "lib": "/opt/unit/modules/python-3.12.1.unit.so" } ], "wasm": { "version": "0.1", "lib": "/opt/unit/modules/wasm.unit.so" }, "wasm-wasi-component": { "version": "0.1", "lib": "/opt/unit/modules/wasm_wasi_component.unit.so" } }, ... } This can be useful for debugging to show exactly what modules Unit has loaded _and_ from where. Closes: https://github.com/nginx/unit/issues/1343 Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
Diffstat (limited to 'src')
-rw-r--r--src/nxt_status.c102
1 files changed, 94 insertions, 8 deletions
diff --git a/src/nxt_status.c b/src/nxt_status.c
index 957bc34e..b48ec743 100644
--- a/src/nxt_status.c
+++ b/src/nxt_status.c
@@ -6,18 +6,27 @@
#include <nxt_main.h>
#include <nxt_conf.h>
#include <nxt_status.h>
+#include <nxt_application.h>
nxt_conf_value_t *
nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp)
{
- size_t i;
- uint32_t idx = 0;
- nxt_str_t name;
- nxt_int_t ret;
- nxt_status_app_t *app;
- nxt_conf_value_t *status, *obj, *apps, *app_obj;
-
+ size_t i, nr_langs;
+ uint16_t lang_cnts[NXT_APP_UNKNOWN] = { 1 };
+ uint32_t idx = 0;
+ nxt_str_t name;
+ nxt_int_t ret;
+ nxt_array_t *langs;
+ nxt_thread_t *thr;
+ nxt_app_type_t type, prev_type;
+ nxt_status_app_t *app;
+ nxt_conf_value_t *status, *obj, *mods, *apps, *app_obj, *mod_obj;
+ nxt_app_lang_module_t *modules;
+
+ static const nxt_str_t modules_str = nxt_string("modules");
+ static const nxt_str_t version_str = nxt_string("version");
+ static const nxt_str_t lib_str = nxt_string("lib");
static const nxt_str_t conns_str = nxt_string("connections");
static const nxt_str_t acc_str = nxt_string("accepted");
static const nxt_str_t active_str = nxt_string("active");
@@ -30,11 +39,88 @@ nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp)
static const nxt_str_t run_str = nxt_string("running");
static const nxt_str_t start_str = nxt_string("starting");
- status = nxt_conf_create_object(mp, 3);
+ status = nxt_conf_create_object(mp, 4);
if (nxt_slow_path(status == NULL)) {
return NULL;
}
+ thr = nxt_thread();
+ langs = thr->runtime->languages;
+
+ modules = langs->elts;
+ /*
+ * We need to count the number of unique languages to correctly
+ * allocate the below mods object.
+ *
+ * We also need to count how many of each language.
+ *
+ * Start by skipping past NXT_APP_EXTERNAL which is always the
+ * first entry.
+ */
+ for (i = 1, nr_langs = 0, prev_type = NXT_APP_UNKNOWN; i < langs->nelts;
+ i++)
+ {
+ type = modules[i].type;
+
+ lang_cnts[type]++;
+
+ if (type == prev_type) {
+ continue;
+ }
+
+ nr_langs++;
+ prev_type = type;
+ }
+
+ mods = nxt_conf_create_object(mp, nr_langs);
+ if (nxt_slow_path(mods == NULL)) {
+ return NULL;
+ }
+
+ nxt_conf_set_member(status, &modules_str, mods, idx++);
+
+ i = 1;
+ obj = mod_obj = NULL;
+ prev_type = NXT_APP_UNKNOWN;
+ for (size_t l = 0, a = 0; i < langs->nelts; i++) {
+ nxt_str_t item, mod_name;
+
+ type = modules[i].type;
+ if (type != prev_type) {
+ a = 0;
+
+ if (lang_cnts[type] == 1) {
+ mod_obj = nxt_conf_create_object(mp, 2);
+ obj = mod_obj;
+ } else {
+ mod_obj = nxt_conf_create_array(mp, lang_cnts[type]);
+ }
+
+ if (nxt_slow_path(mod_obj == NULL)) {
+ return NULL;
+ }
+
+ mod_name.start = (u_char *)modules[i].name;
+ mod_name.length = strlen(modules[i].name);
+ nxt_conf_set_member(mods, &mod_name, mod_obj, l++);
+ }
+
+ if (lang_cnts[type] > 1) {
+ obj = nxt_conf_create_object(mp, 2);
+ nxt_conf_set_element(mod_obj, a++, obj);
+ }
+
+ item.start = modules[i].version;
+ item.length = nxt_strlen(modules[i].version);
+ nxt_conf_set_member_string(obj, &version_str, &item, 0);
+
+ item.start = (u_char *)modules[i].file;
+ item.length = strlen(modules[i].file);
+ nxt_conf_set_member_string(obj, &lib_str, &item, 1);
+
+ prev_type = type;
+ }
+
obj = nxt_conf_create_object(mp, 4);
if (nxt_slow_path(obj == NULL)) {
return NULL;