@cryptotaxi247 / netdata-1 / commits / 9cb6e7f41

add ACLK stats per cloud query type (#10602)

* add stats per cloud query type

Timotej S committed Feb 26, 2021 at 14:24 UTC 9cb6e7f4107db983a490da87383ba703ec38a840
5 files changed +117 -14
aclk/legacy/aclk_query.c
+1
@@ -62,6 +62,7 @@ static void aclk_query_free(struct aclk_query *this_query)
62 freez(this_query->query);
63 if(this_query->data && this_query->cmd == ACLK_CMD_CLOUD_QUERY_2) {
64 struct aclk_cloud_req_v2 *del = (struct aclk_cloud_req_v2 *)this_query->data;
65 + freez(del->query_endpoint);
66 freez(del->data);
67 freez(del);
68 }
aclk/legacy/aclk_query.h
+1
@@ -31,6 +31,7 @@ struct aclk_query_threads {
31 struct aclk_cloud_req_v2 {
32 char *data;
33 RRDHOST *host;
34 + char *query_endpoint;
35 };
36
37 void *aclk_query_main_thread(void *ptr);
aclk/legacy/aclk_rx_msgs.c
+29 -7
@@ -25,7 +25,7 @@ static inline int aclk_extract_v2_data(char *payload, char **data)
25 #define STRNCMP_CONSTANT_PREFIX(str, const_pref) strncmp(str, const_pref, strlen(const_pref))
26 static inline int aclk_v2_payload_get_query(struct aclk_cloud_req_v2 *cloud_req, struct aclk_request *req)
27 {
28 - const char *start, *end, *ptr;
28 + const char *start, *end, *ptr, *query_type;
29 char uuid_str[UUID_STR_LEN];
30 uuid_t uuid;
31
@@ -66,6 +66,8 @@ static inline int aclk_v2_payload_get_query(struct aclk_cloud_req_v2 *cloud_req,
66 error("Only accepting requests that start with \"%s\" from CLOUD.", ACLK_CLOUD_REQ_V2_PREFIX);
67 return 1;
68 }
69 + ptr += strlen(ACLK_CLOUD_REQ_V2_PREFIX);
70 + query_type = ptr;
71
72 if(!(end = strstr(ptr, " HTTP/1.1\x0D\x0A"))) {
73 errno = 0;
@@ -73,6 +75,11 @@ static inline int aclk_v2_payload_get_query(struct aclk_cloud_req_v2 *cloud_req,
75 return 1;
76 }
77
78 + if(!(ptr = strchr(ptr, '?')) || ptr > end)
79 + ptr = end;
80 + cloud_req->query_endpoint = mallocz((ptr - query_type) + 1);
81 + strncpyz(cloud_req->query_endpoint, query_type, ptr - query_type);
82 +
83 req->payload = mallocz((end - start) + 1);
84 strncpyz(req->payload, start, end - start);
85
@@ -122,6 +129,13 @@ static int aclk_handle_cloud_request_v1(struct aclk_request *cloud_to_agent, cha
129 if (unlikely(aclk_queue_query(cloud_to_agent->callback_topic, NULL, cloud_to_agent->msg_id, cloud_to_agent->payload, 0, 0, ACLK_CMD_CLOUD)))
130 debug(D_ACLK, "ACLK failed to queue incoming \"http\" message");
131
132 + if (aclk_stats_enabled) {
133 + ACLK_STATS_LOCK;
134 + aclk_metrics_per_sample.cloud_req_v1++;
135 + aclk_metrics_per_sample.cloud_req_ok++;
136 + ACLK_STATS_UNLOCK;
137 + }
138 +
139 return 0;
140 }
141
@@ -131,6 +145,7 @@ static int aclk_handle_cloud_request_v2(struct aclk_request *cloud_to_agent, cha
145
146 struct aclk_cloud_req_v2 *cloud_req;
147 char *data;
148 + int stat_idx;
149
150 errno = 0;
151 if (cloud_to_agent->version < ACLK_V_COMPRESSION) {
@@ -165,6 +180,10 @@ static int aclk_handle_cloud_request_v2(struct aclk_request *cloud_to_agent, cha
180 goto cleanup;
181 }
182
183 + // we do this here due to cloud_req being taken over by query thread
184 + // which if crazy quick can free it after aclk_queue_query
185 + stat_idx = aclk_cloud_req_type_to_idx(cloud_req->query_endpoint);
186 +
187 // aclk_queue_query takes ownership of data pointer
188 if (unlikely(aclk_queue_query(
189 cloud_to_agent->callback_topic, cloud_req, cloud_to_agent->msg_id, cloud_to_agent->payload, 0, 0,
@@ -173,8 +192,17 @@ static int aclk_handle_cloud_request_v2(struct aclk_request *cloud_to_agent, cha
192 goto cleanup;
193 }
194
195 + if (aclk_stats_enabled) {
196 + ACLK_STATS_LOCK;
197 + aclk_metrics_per_sample.cloud_req_v2++;
198 + aclk_metrics_per_sample.cloud_req_ok++;
199 + aclk_metrics_per_sample.cloud_req_by_type[stat_idx]++;
200 + ACLK_STATS_UNLOCK;
201 + }
202 +
203 return 0;
204 cleanup:
205 + freez(cloud_req->query_endpoint);
206 freez(cloud_req->data);
207 freez(cloud_req);
208 return 1;
@@ -289,12 +317,6 @@ int aclk_handle_cloud_message(char *payload)
317 struct aclk_request cloud_to_agent;
318 memset(&cloud_to_agent, 0, sizeof(struct aclk_request));
319
292 - if (aclk_stats_enabled) {
293 - ACLK_STATS_LOCK;
294 - aclk_metrics_per_sample.cloud_req_recvd++;
295 - ACLK_STATS_UNLOCK;
296 - }
297 -
320 if (unlikely(!payload)) {
321 errno = 0;
322 error("ACLK incoming message is empty");
aclk/legacy/aclk_stats.c
+75 -6
@@ -162,7 +162,7 @@ static void aclk_stats_read_q(struct aclk_metrics_per_sample *per_sample)
162 static void aclk_stats_cloud_req(struct aclk_metrics_per_sample *per_sample)
163 {
164 static RRDSET *st = NULL;
165 - static RRDDIM *rd_rq_rcvd = NULL;
165 + static RRDDIM *rd_rq_ok = NULL;
166 static RRDDIM *rd_rq_err = NULL;
167
168 if (unlikely(!st)) {
@@ -170,17 +170,82 @@ static void aclk_stats_cloud_req(struct aclk_metrics_per_sample *per_sample)
170 "netdata", "aclk_cloud_req", NULL, "aclk", NULL, "Requests received from cloud", "req/s",
171 "netdata", "stats", 200005, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
172
173 - rd_rq_rcvd = rrddim_add(st, "received", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
174 - rd_rq_err = rrddim_add(st, "malformed", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
173 + rd_rq_ok = rrddim_add(st, "accepted", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
174 + rd_rq_err = rrddim_add(st, "rejected", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
175 } else
176 rrdset_next(st);
177
178 - rrddim_set_by_pointer(st, rd_rq_rcvd, per_sample->cloud_req_recvd - per_sample->cloud_req_err);
178 + rrddim_set_by_pointer(st, rd_rq_ok, per_sample->cloud_req_ok);
179 rrddim_set_by_pointer(st, rd_rq_err, per_sample->cloud_req_err);
180
181 rrdset_done(st);
182 }
183
184 +static void aclk_stats_cloud_req_version(struct aclk_metrics_per_sample *per_sample)
185 +{
186 + static RRDSET *st = NULL;
187 + static RRDDIM *rd_rq_v1 = NULL;
188 + static RRDDIM *rd_rq_v2 = NULL;
189 +
190 + if (unlikely(!st)) {
191 + st = rrdset_create_localhost(
192 + "netdata", "aclk_cloud_req_version", NULL, "aclk", NULL, "Requests received from cloud by their version", "req/s",
193 + "netdata", "stats", 200006, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
194 +
195 + rd_rq_v1 = rrddim_add(st, "v1", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
196 + rd_rq_v2 = rrddim_add(st, "v2+", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
197 + } else
198 + rrdset_next(st);
199 +
200 + rrddim_set_by_pointer(st, rd_rq_v1, per_sample->cloud_req_v1);
201 + rrddim_set_by_pointer(st, rd_rq_v2, per_sample->cloud_req_v2);
202 +
203 + rrdset_done(st);
204 +}
205 +
206 +static char *cloud_req_type_names[ACLK_STATS_CLOUD_REQ_TYPE_CNT] = {
207 + "other",
208 + "info",
209 + "data",
210 + "alarms",
211 + "alarm_log",
212 + "chart",
213 + "charts"
214 + // if you change update:
215 + // #define ACLK_STATS_CLOUD_REQ_TYPE_CNT 7
216 +};
217 +
218 +int aclk_cloud_req_type_to_idx(const char *name)
219 +{
220 + for (int i = 1; i < ACLK_STATS_CLOUD_REQ_TYPE_CNT; i++)
221 + if (!strcmp(cloud_req_type_names[i], name))
222 + return i;
223 + return 0;
224 +}
225 +
226 +static void aclk_stats_cloud_req_cmd(struct aclk_metrics_per_sample *per_sample)
227 +{
228 + static RRDSET *st;
229 + static int initialized = 0;
230 + static RRDDIM *rd_rq_types[ACLK_STATS_CLOUD_REQ_TYPE_CNT];
231 +
232 + if (unlikely(!initialized)) {
233 + initialized = 1;
234 + st = rrdset_create_localhost(
235 + "netdata", "aclk_cloud_req_cmd", NULL, "aclk", NULL, "Requests received from cloud by their type (api endpoint queried)", "req/s",
236 + "netdata", "stats", 200007, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
237 +
238 + for (int i = 0; i < ACLK_STATS_CLOUD_REQ_TYPE_CNT; i++)
239 + rd_rq_types[i] = rrddim_add(st, cloud_req_type_names[i], NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
240 + } else
241 + rrdset_next(st);
242 +
243 + for (int i = 0; i < ACLK_STATS_CLOUD_REQ_TYPE_CNT; i++)
244 + rrddim_set_by_pointer(st, rd_rq_types[i], per_sample->cloud_req_by_type[i]);
245 +
246 + rrdset_done(st);
247 +}
248 +
249 #define MAX_DIM_NAME 16
250 static void aclk_stats_query_threads(uint32_t *queries_per_thread)
251 {
@@ -191,7 +256,7 @@ static void aclk_stats_query_threads(uint32_t *queries_per_thread)
256 if (unlikely(!st)) {
257 st = rrdset_create_localhost(
258 "netdata", "aclk_query_threads", NULL, "aclk", NULL, "Queries Processed Per Thread", "req/s",
194 - "netdata", "stats", 200007, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
259 + "netdata", "stats", 200008, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
260
261 for (int i = 0; i < query_thread_count; i++) {
262 if (snprintf(dim_name, MAX_DIM_NAME, "Query %d", i) < 0)
@@ -244,7 +309,7 @@ static void aclk_stats_cpu_threads(void)
309
310 aclk_cpu_data[i].st = rrdset_create_localhost(
311 "netdata", id, NULL, "aclk", NULL, title, "milliseconds/s",
247 - "netdata", "stats", 200008 + i, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
312 + "netdata", "stats", 200020 + i, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
313
314 aclk_cpu_data[i].user = rrddim_add(aclk_cpu_data[i].st, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
315 aclk_cpu_data[i].system = rrddim_add(aclk_cpu_data[i].st, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
@@ -317,6 +382,10 @@ void *aclk_stats_main_thread(void *ptr)
382 aclk_stats_read_q(&per_sample);
383
384 aclk_stats_cloud_req(&per_sample);
385 + aclk_stats_cloud_req_version(&per_sample);
386 +
387 + aclk_stats_cloud_req_cmd(&per_sample);
388 +
389 aclk_stats_query_threads(aclk_queries_per_thread_sample);
390
391 aclk_stats_cpu_threads();
aclk/legacy/aclk_stats.h
+11 -1
@@ -55,6 +55,11 @@ extern struct aclk_mat_metrics {
55
56 void aclk_metric_mat_update(struct aclk_metric_mat_data *metric, usec_t measurement);
57
58 +#define ACLK_STATS_CLOUD_REQ_TYPE_CNT 7
59 +// if you change update cloud_req_type_names
60 +
61 +int aclk_cloud_req_type_to_idx(const char *name);
62 +
63 // reset to 0 on every sample
64 extern struct aclk_metrics_per_sample {
65 /* in the unlikely event of ACLK disconnecting
@@ -72,9 +77,14 @@ extern struct aclk_metrics_per_sample {
77 volatile uint32_t read_q_added;
78 volatile uint32_t read_q_consumed;
79
75 - volatile uint32_t cloud_req_recvd;
80 + volatile uint32_t cloud_req_ok;
81 volatile uint32_t cloud_req_err;
82
83 + volatile uint16_t cloud_req_v1;
84 + volatile uint16_t cloud_req_v2;
85 +
86 + volatile uint16_t cloud_req_by_type[ACLK_STATS_CLOUD_REQ_TYPE_CNT];
87 +
88 #ifdef NETDATA_INTERNAL_CHECKS
89 struct aclk_metric_mat_data latency;
90 #endif