master
c 180 lines 8.02 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "jsonwrap.h"
4 #include "jsonwrap-internal.h"
5
6 static void rrdset_rrdcalc_entries_v2(BUFFER *wb, RRDINSTANCE_ACQUIRED *ria) {
7 RRDSET *st = rrdinstance_acquired_rrdset(ria);
8 if(st) {
9 rw_spinlock_read_lock(&st->alerts.spinlock);
10 if(st->alerts.base) {
11 buffer_json_member_add_object(wb, "alerts");
12 for(RRDCALC *rc = st->alerts.base; rc ;rc = rc->next) {
13 if(rc->status < RRDCALC_STATUS_CLEAR)
14 continue;
15
16 buffer_json_member_add_object(wb, string2str(rc->config.name));
17 buffer_json_member_add_string(wb, JSKEY(status), rrdcalc_status2string(rc->status));
18 buffer_json_member_add_double(wb, JSKEY(value), rc->value);
19 buffer_json_member_add_string(wb, JSKEY(units), string2str(rc->config.units));
20 buffer_json_object_close(wb);
21 }
22 buffer_json_object_close(wb);
23 }
24 rw_spinlock_read_unlock(&st->alerts.spinlock);
25 }
26 }
27
28 void query_target_detailed_objects_tree(BUFFER *wb, RRDR *r, RRDR_OPTIONS options) {
29 QUERY_TARGET *qt = r->internal.qt;
30 buffer_json_member_add_object(wb, "nodes");
31
32 time_t now_s = now_realtime_sec();
33 RRDHOST *last_host = NULL;
34 RRDCONTEXT_ACQUIRED *last_rca = NULL;
35 RRDINSTANCE_ACQUIRED *last_ria = NULL;
36
37 size_t h = 0, c = 0, i = 0, m = 0, q = 0;
38 for(; h < qt->nodes.used ; h++) {
39 QUERY_NODE *qn = query_node(qt, h);
40 RRDHOST *host = qn->rrdhost;
41
42 for( ;c < qt->contexts.used ;c++) {
43 QUERY_CONTEXT *qc = query_context(qt, c);
44 RRDCONTEXT_ACQUIRED *rca = qc->rca;
45 if(!rrdcontext_acquired_belongs_to_host(rca, host)) break;
46
47 for( ;i < qt->instances.used ;i++) {
48 QUERY_INSTANCE *qi = query_instance(qt, i);
49 RRDINSTANCE_ACQUIRED *ria = qi->ria;
50 if(!rrdinstance_acquired_belongs_to_context(ria, rca)) break;
51
52 for( ; m < qt->dimensions.used ; m++) {
53 QUERY_DIMENSION *qd = query_dimension(qt, m);
54 RRDMETRIC_ACQUIRED *rma = qd->rma;
55 if(!rrdmetric_acquired_belongs_to_instance(rma, ria)) break;
56
57 QUERY_METRIC *qm = NULL;
58 bool queried = false;
59 for( ; q < qt->query.used ;q++) {
60 QUERY_METRIC *tqm = query_metric(qt, q);
61 QUERY_DIMENSION *tqd = query_dimension(qt, tqm->link.query_dimension_id);
62 if(tqd->rma != rma) break;
63
64 queried = tqm->status & RRDR_DIMENSION_QUERIED;
65 qm = tqm;
66 }
67
68 if(!queried & !(options & RRDR_OPTION_ALL_DIMENSIONS))
69 continue;
70
71 if(host != last_host) {
72 if(last_host) {
73 if(last_rca) {
74 if(last_ria) {
75 buffer_json_object_close(wb); // dimensions
76 buffer_json_object_close(wb); // instance
77 last_ria = NULL;
78 }
79 buffer_json_object_close(wb); // instances
80 buffer_json_object_close(wb); // context
81 last_rca = NULL;
82 }
83 buffer_json_object_close(wb); // contexts
84 buffer_json_object_close(wb); // host
85 }
86
87 buffer_json_member_add_object(wb, host->machine_guid);
88 if(qn->node_id[0])
89 buffer_json_member_add_string(wb, JSKEY(node_id), qn->node_id);
90 buffer_json_member_add_uint64(wb, JSKEY(node_index), qn->slot);
91 buffer_json_member_add_string(wb, JSKEY(hostname), rrdhost_hostname(host));
92 buffer_json_member_add_object(wb, "contexts");
93
94 last_host = host;
95 }
96
97 if(rca != last_rca) {
98 if(last_rca) {
99 if(last_ria) {
100 buffer_json_object_close(wb); // dimensions
101 buffer_json_object_close(wb); // instance
102 last_ria = NULL;
103 }
104 buffer_json_object_close(wb); // instances
105 buffer_json_object_close(wb); // context
106 last_rca = NULL;
107 }
108
109 buffer_json_member_add_object(wb, rrdcontext_acquired_id(rca));
110 buffer_json_member_add_object(wb, "instances");
111
112 last_rca = rca;
113 }
114
115 if(ria != last_ria) {
116 if(last_ria) {
117 buffer_json_object_close(wb); // dimensions
118 buffer_json_object_close(wb); // instance
119 last_ria = NULL;
120 }
121
122 buffer_json_member_add_object(wb, rrdinstance_acquired_id(ria));
123 buffer_json_member_add_string(wb, JSKEY(name), rrdinstance_acquired_name(ria));
124 buffer_json_member_add_time_t(wb, JSKEY(update_every), rrdinstance_acquired_update_every(ria));
125 RRDLABELS *labels = rrdinstance_acquired_labels(ria);
126 if(labels) {
127 buffer_json_member_add_object(wb, "labels");
128 rrdlabels_to_buffer_json_members(labels, wb);
129 buffer_json_object_close(wb);
130 }
131 rrdset_rrdcalc_entries_v2(wb, ria);
132 buffer_json_member_add_object(wb, "dimensions");
133
134 last_ria = ria;
135 }
136
137 buffer_json_member_add_object(wb, rrdmetric_acquired_id(rma));
138 {
139 buffer_json_member_add_string(wb, JSKEY(name), rrdmetric_acquired_name(rma));
140 buffer_json_member_add_uint64(wb, JSKEY(queried), queried ? 1 : 0);
141 time_t first_entry_s = rrdmetric_acquired_first_entry(rma);
142 time_t last_entry_s = rrdmetric_acquired_last_entry(rma);
143 buffer_json_member_add_time_t_formatted(wb, JSKEY(first_entry), first_entry_s, options & RRDR_OPTION_RFC3339);
144 buffer_json_member_add_time_t_formatted(wb, JSKEY(last_entry), last_entry_s ? last_entry_s : now_s, options & RRDR_OPTION_RFC3339);
145
146 if(qm) {
147 if(qm->status & RRDR_DIMENSION_GROUPED) {
148 // buffer_json_member_add_string(wb, "grouped_as_id", string2str(qm->grouped_as.id));
149 buffer_json_member_add_string(wb, "as", string2str(qm->grouped_as.name));
150 }
151
152 query_target_points_statistics(wb, qt, &qm->query_points);
153
154 if(options & RRDR_OPTION_DEBUG)
155 jsonwrap_query_metric_plan(wb, qm, options);
156 }
157 }
158 buffer_json_object_close(wb); // metric
159 }
160 }
161 }
162 }
163
164 if(last_host) {
165 if(last_rca) {
166 if(last_ria) {
167 buffer_json_object_close(wb); // dimensions
168 buffer_json_object_close(wb); // instance
169 last_ria = NULL;
170 }
171 buffer_json_object_close(wb); // instances
172 buffer_json_object_close(wb); // context
173 last_rca = NULL;
174 }
175 buffer_json_object_close(wb); // contexts
176 buffer_json_object_close(wb); // host
177 last_host = NULL;
178 }
179 buffer_json_object_close(wb); // hosts
180 }