Coverage Report

Created: 2025-07-18 06:06

/src/unit/src/nxt_status.c
Line
Count
Source (jump to first uncovered line)
1
2
/*
3
 * Copyright (C) NGINX, Inc.
4
 */
5
6
#include <nxt_main.h>
7
#include <nxt_conf.h>
8
#include <nxt_status.h>
9
#include <nxt_application.h>
10
11
12
nxt_conf_value_t *
13
nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp)
14
0
{
15
0
    size_t                 i, nr_langs;
16
0
    uint16_t               lang_cnts[NXT_APP_UNKNOWN] = { 1 };
17
0
    uint32_t               idx = 0;
18
0
    nxt_str_t              name;
19
0
    nxt_int_t              ret;
20
0
    nxt_array_t            *langs;
21
0
    nxt_thread_t           *thr;
22
0
    nxt_app_type_t         type, prev_type;
23
0
    nxt_status_app_t       *app;
24
0
    nxt_conf_value_t       *status, *obj, *mods, *apps, *app_obj, *mod_obj;
25
0
    nxt_app_lang_module_t  *modules;
26
27
0
    static const nxt_str_t  modules_str = nxt_string("modules");
28
0
    static const nxt_str_t  version_str = nxt_string("version");
29
0
    static const nxt_str_t  lib_str = nxt_string("lib");
30
0
    static const nxt_str_t  conns_str = nxt_string("connections");
31
0
    static const nxt_str_t  acc_str = nxt_string("accepted");
32
0
    static const nxt_str_t  active_str = nxt_string("active");
33
0
    static const nxt_str_t  idle_str = nxt_string("idle");
34
0
    static const nxt_str_t  closed_str = nxt_string("closed");
35
0
    static const nxt_str_t  reqs_str = nxt_string("requests");
36
0
    static const nxt_str_t  total_str = nxt_string("total");
37
0
    static const nxt_str_t  apps_str = nxt_string("applications");
38
0
    static const nxt_str_t  procs_str = nxt_string("processes");
39
0
    static const nxt_str_t  run_str = nxt_string("running");
40
0
    static const nxt_str_t  start_str = nxt_string("starting");
41
42
0
    status = nxt_conf_create_object(mp, 4);
43
0
    if (nxt_slow_path(status == NULL)) {
44
0
        return NULL;
45
0
    }
46
47
0
    thr = nxt_thread();
48
0
    langs = thr->runtime->languages;
49
50
0
    modules = langs->elts;
51
    /*
52
     * We need to count the number of unique languages to correctly
53
     * allocate the below mods object.
54
     *
55
     * We also need to count how many of each language.
56
     *
57
     * Start by skipping past NXT_APP_EXTERNAL which is always the
58
     * first entry.
59
     */
60
0
    for (i = 1, nr_langs = 0, prev_type = NXT_APP_UNKNOWN; i < langs->nelts;
61
0
         i++)
62
0
    {
63
0
        type = modules[i].type;
64
65
0
        lang_cnts[type]++;
66
67
0
        if (type == prev_type) {
68
0
            continue;
69
0
        }
70
71
0
        nr_langs++;
72
0
        prev_type = type;
73
0
    }
74
75
0
    mods = nxt_conf_create_object(mp, nr_langs);
76
0
    if (nxt_slow_path(mods == NULL)) {
77
0
        return NULL;
78
0
    }
79
80
0
    nxt_conf_set_member(status, &modules_str, mods, idx++);
81
82
0
    i = 1;
83
0
    obj = mod_obj = NULL;
84
0
    prev_type = NXT_APP_UNKNOWN;
85
0
    for (size_t l = 0, a = 0; i < langs->nelts; i++) {
86
0
        nxt_str_t  item, mod_name;
87
88
0
        type = modules[i].type;
89
0
        if (type != prev_type) {
90
0
            a = 0;
91
92
0
            if (lang_cnts[type] == 1) {
93
0
                mod_obj = nxt_conf_create_object(mp, 2);
94
0
                obj = mod_obj;
95
0
            } else {
96
0
                mod_obj = nxt_conf_create_array(mp, lang_cnts[type]);
97
0
            }
98
99
0
            if (nxt_slow_path(mod_obj == NULL)) {
100
0
                return NULL;
101
0
            }
102
103
0
            mod_name.start = (u_char *)modules[i].name;
104
0
            mod_name.length = strlen(modules[i].name);
105
0
            nxt_conf_set_member(mods, &mod_name, mod_obj, l++);
106
0
        }
107
108
0
        if (lang_cnts[type] > 1) {
109
0
            obj = nxt_conf_create_object(mp, 2);
110
0
            if (nxt_slow_path(obj == NULL)) {
111
0
                return NULL;
112
0
            }
113
114
0
            nxt_conf_set_element(mod_obj, a++, obj);
115
0
        }
116
117
0
        item.start = modules[i].version;
118
0
        item.length = nxt_strlen(modules[i].version);
119
0
        nxt_conf_set_member_string(obj, &version_str, &item, 0);
120
121
0
        item.start = (u_char *)modules[i].file;
122
0
        item.length = strlen(modules[i].file);
123
0
        nxt_conf_set_member_string(obj, &lib_str, &item, 1);
124
125
0
        prev_type = type;
126
0
    }
127
128
0
    obj = nxt_conf_create_object(mp, 4);
129
0
    if (nxt_slow_path(obj == NULL)) {
130
0
        return NULL;
131
0
    }
132
133
0
    nxt_conf_set_member(status, &conns_str, obj, idx++);
134
135
0
    nxt_conf_set_member_integer(obj, &acc_str, report->accepted_conns, 0);
136
0
    nxt_conf_set_member_integer(obj, &active_str, report->accepted_conns
137
0
                                                  - report->closed_conns
138
0
                                                  - report->idle_conns, 1);
139
0
    nxt_conf_set_member_integer(obj, &idle_str, report->idle_conns, 2);
140
0
    nxt_conf_set_member_integer(obj, &closed_str, report->closed_conns, 3);
141
142
0
    obj = nxt_conf_create_object(mp, 1);
143
0
    if (nxt_slow_path(obj == NULL)) {
144
0
        return NULL;
145
0
    }
146
147
0
    nxt_conf_set_member(status, &reqs_str, obj, idx++);
148
149
0
    nxt_conf_set_member_integer(obj, &total_str, report->requests, 0);
150
151
0
    apps = nxt_conf_create_object(mp, report->apps_count);
152
0
    if (nxt_slow_path(apps == NULL)) {
153
0
        return NULL;
154
0
    }
155
156
0
    nxt_conf_set_member(status, &apps_str, apps, idx++);
157
158
0
    for (i = 0; i < report->apps_count; i++) {
159
0
        app = &report->apps[i];
160
161
0
        app_obj = nxt_conf_create_object(mp, 2);
162
0
        if (nxt_slow_path(app_obj == NULL)) {
163
0
            return NULL;
164
0
        }
165
166
0
        name.length = app->name.length;
167
0
        name.start = nxt_pointer_to(report, (uintptr_t) app->name.start);
168
169
0
        ret = nxt_conf_set_member_dup(apps, mp, &name, app_obj, i);
170
0
        if (nxt_slow_path(ret != NXT_OK)) {
171
0
            return NULL;
172
0
        }
173
174
0
        obj = nxt_conf_create_object(mp, 3);
175
0
        if (nxt_slow_path(obj == NULL)) {
176
0
            return NULL;
177
0
        }
178
179
0
        nxt_conf_set_member(app_obj, &procs_str, obj, 0);
180
181
0
        nxt_conf_set_member_integer(obj, &run_str, app->processes, 0);
182
0
        nxt_conf_set_member_integer(obj, &start_str, app->pending_processes, 1);
183
0
        nxt_conf_set_member_integer(obj, &idle_str, app->idle_processes, 2);
184
185
0
        obj = nxt_conf_create_object(mp, 1);
186
0
        if (nxt_slow_path(obj == NULL)) {
187
0
            return NULL;
188
0
        }
189
190
0
        nxt_conf_set_member(app_obj, &reqs_str, obj, 1);
191
192
0
        nxt_conf_set_member_integer(obj, &active_str, app->active_requests, 0);
193
0
    }
194
195
0
    return status;
196
0
}