@cryptotaxi247 / netdata-1 / commits / c715423dc

Add ACLK-NG cloud request type charts (#11326)

- `netdata.aclk_cloud_req_http_type` will show a breakdown of HTTP query types, e.g. `/api/v1/data` vs. `/api/v1/chart` etc. - `netdata.aclk_cloud_req_type` will show a breakdown at a higher-level, e.g. `http` vs `alarm_update` vs `metadata_alarms` etc. This is based off of the entries found in `aclk/aclk_query.c#aclk_query_handlers`.

Uman Shahzad committed Jul 19, 2021 at 13:12 UTC c715423dc73a5f1452b7e5b126180c1335fdefc2
4 files changed +145 -2
aclk/aclk_query.c
+7
@@ -125,6 +125,13 @@ static int http_api_v2(struct aclk_query_thread *query_thr, aclk_query_t query)
125
126 mysep = strrchr(query->data.http_api_v2.query, '/');
127
128 + if (aclk_stats_enabled) {
129 + ACLK_STATS_LOCK;
130 + int stat_idx = aclk_cloud_req_http_type_to_idx(mysep ? mysep + 1 : "other");
131 + aclk_metrics_per_sample.cloud_req_http_by_type[stat_idx]++;
132 + ACLK_STATS_UNLOCK;
133 + }
134 +
135 // execute the query
136 w->tv_in = query->created_tv;
137 now_realtime_timeval(&w->tv_ready);
aclk/aclk_query_queue.c
+35
@@ -45,14 +45,49 @@ static inline int _aclk_queue_query(aclk_query_t query)
45
46 }
47
48 +// Gets a pointer to the metric associated with a particular query type.
49 +// NULL if the query type has no associated metric.
50 +static inline volatile uint32_t *aclk_stats_qmetric_for_qtype(aclk_query_type_t qtype) {
51 + switch (qtype) {
52 + case HTTP_API_V2:
53 + return &aclk_metrics_per_sample.cloud_req_type_http;
54 + case ALARM_STATE_UPDATE:
55 + return &aclk_metrics_per_sample.cloud_req_type_alarm_upd;
56 + case METADATA_INFO:
57 + return &aclk_metrics_per_sample.cloud_req_type_metadata_info;
58 + case METADATA_ALARMS:
59 + return &aclk_metrics_per_sample.cloud_req_type_metadata_alarms;
60 + case CHART_NEW:
61 + return &aclk_metrics_per_sample.cloud_req_type_chart_new;
62 + case CHART_DEL:
63 + return &aclk_metrics_per_sample.cloud_req_type_chart_del;
64 + case REGISTER_NODE:
65 + return &aclk_metrics_per_sample.cloud_req_type_register_node;
66 + case NODE_STATE_UPDATE:
67 + return &aclk_metrics_per_sample.cloud_req_type_node_upd;
68 + default:
69 + return NULL;
70 + }
71 +}
72 +
73 int aclk_queue_query(aclk_query_t query)
74 {
75 int ret = _aclk_queue_query(query);
76 if (!ret) {
77 + // local cache of query type before we wake up query thread, which may
78 + // free the query in a race.
79 + aclk_query_type_t qtype = query->type;
80 QUERY_THREAD_WAKEUP;
81 +
82 if (aclk_stats_enabled) {
83 + // get target query type metric before lock so we keep lock for
84 + // minimal time.
85 + volatile uint32_t *metric = aclk_stats_qmetric_for_qtype(qtype);
86 +
87 ACLK_STATS_LOCK;
88 aclk_metrics_per_sample.queries_queued++;
89 + if (metric)
90 + *metric += 1;
91 ACLK_STATS_UNLOCK;
92 }
93 }
aclk/aclk_stats.c
+85 -2
@@ -110,6 +110,86 @@ static void aclk_stats_cloud_req(struct aclk_metrics_per_sample *per_sample)
110 rrdset_done(st);
111 }
112
113 +static void aclk_stats_cloud_req_type(struct aclk_metrics_per_sample *per_sample)
114 +{
115 + static RRDSET *st = NULL;
116 + static RRDDIM *rd_type_http = NULL;
117 + static RRDDIM *rd_type_alarm_upd = NULL;
118 + static RRDDIM *rd_type_metadata_info = NULL;
119 + static RRDDIM *rd_type_metadata_alarms = NULL;
120 + static RRDDIM *rd_type_chart_new = NULL;
121 + static RRDDIM *rd_type_chart_del = NULL;
122 + static RRDDIM *rd_type_register_node = NULL;
123 + static RRDDIM *rd_type_node_upd = NULL;
124 +
125 + if (unlikely(!st)) {
126 + st = rrdset_create_localhost(
127 + "netdata", "aclk_cloud_req_type", NULL, "aclk", NULL, "Requests received from cloud by their type", "req/s",
128 + "netdata", "stats", 200006, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
129 +
130 + rd_type_http = rrddim_add(st, "http", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
131 + rd_type_alarm_upd = rrddim_add(st, "alarm update", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
132 + rd_type_metadata_info = rrddim_add(st, "info metadata", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
133 + rd_type_metadata_alarms = rrddim_add(st, "alarms metadata", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
134 + rd_type_chart_new = rrddim_add(st, "chart new", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
135 + rd_type_chart_del = rrddim_add(st, "chart delete", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
136 + rd_type_register_node = rrddim_add(st, "register node", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
137 + rd_type_node_upd = rrddim_add(st, "node update", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
138 + } else
139 + rrdset_next(st);
140 +
141 + rrddim_set_by_pointer(st, rd_type_http, per_sample->cloud_req_type_http);
142 + rrddim_set_by_pointer(st, rd_type_alarm_upd, per_sample->cloud_req_type_alarm_upd);
143 + rrddim_set_by_pointer(st, rd_type_metadata_info, per_sample->cloud_req_type_metadata_info);
144 + rrddim_set_by_pointer(st, rd_type_metadata_alarms, per_sample->cloud_req_type_metadata_alarms);
145 + rrddim_set_by_pointer(st, rd_type_chart_new, per_sample->cloud_req_type_chart_new);
146 + rrddim_set_by_pointer(st, rd_type_chart_del, per_sample->cloud_req_type_chart_del);
147 + rrddim_set_by_pointer(st, rd_type_register_node, per_sample->cloud_req_type_register_node);
148 + rrddim_set_by_pointer(st, rd_type_node_upd, per_sample->cloud_req_type_node_upd);
149 +
150 + rrdset_done(st);
151 +}
152 +
153 +static char *cloud_req_http_type_names[ACLK_STATS_CLOUD_HTTP_REQ_TYPE_CNT] = {
154 + "other",
155 + "info",
156 + "data",
157 + "alarms",
158 + "alarm_log",
159 + "chart",
160 + "charts"
161 + // if you change then update `ACLK_STATS_CLOUD_HTTP_REQ_TYPE_CNT`.
162 +};
163 +
164 +int aclk_cloud_req_http_type_to_idx(const char *name)
165 +{
166 + for (int i = 1; i < ACLK_STATS_CLOUD_HTTP_REQ_TYPE_CNT; i++)
167 + if (!strcmp(cloud_req_http_type_names[i], name))
168 + return i;
169 + return 0;
170 +}
171 +
172 +static void aclk_stats_cloud_req_http_type(struct aclk_metrics_per_sample *per_sample)
173 +{
174 + static RRDSET *st = NULL;
175 + static RRDDIM *rd_rq_types[ACLK_STATS_CLOUD_HTTP_REQ_TYPE_CNT];
176 +
177 + if (unlikely(!st)) {
178 + st = rrdset_create_localhost(
179 + "netdata", "aclk_cloud_req_http_type", NULL, "aclk", NULL, "Requests received from cloud via HTTP by their type", "req/s",
180 + "netdata", "stats", 200007, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
181 +
182 + for (int i = 0; i < ACLK_STATS_CLOUD_HTTP_REQ_TYPE_CNT; i++)
183 + rd_rq_types[i] = rrddim_add(st, cloud_req_http_type_names[i], NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
184 + } else
185 + rrdset_next(st);
186 +
187 + for (int i = 0; i < ACLK_STATS_CLOUD_HTTP_REQ_TYPE_CNT; i++)
188 + rrddim_set_by_pointer(st, rd_rq_types[i], per_sample->cloud_req_http_by_type[i]);
189 +
190 + rrdset_done(st);
191 +}
192 +
193 #define MAX_DIM_NAME 16
194 static void aclk_stats_query_threads(uint32_t *queries_per_thread)
195 {
@@ -120,7 +200,7 @@ static void aclk_stats_query_threads(uint32_t *queries_per_thread)
200 if (unlikely(!st)) {
201 st = rrdset_create_localhost(
202 "netdata", "aclk_query_threads", NULL, "aclk", NULL, "Queries Processed Per Thread", "req/s",
123 - "netdata", "stats", 200007, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
203 + "netdata", "stats", 200009, localhost->rrd_update_every, RRDSET_TYPE_STACKED);
204
205 for (int i = 0; i < query_thread_count; i++) {
206 if (snprintf(dim_name, MAX_DIM_NAME, "Query %d", i) < 0)
@@ -147,7 +227,7 @@ static void aclk_stats_query_time(struct aclk_metrics_per_sample *per_sample)
227 if (unlikely(!st)) {
228 st = rrdset_create_localhost(
229 "netdata", "aclk_query_time", NULL, "aclk", NULL, "Time it took to process cloud requested DB queries", "us",
150 - "netdata", "stats", 200006, localhost->rrd_update_every, RRDSET_TYPE_LINE);
230 + "netdata", "stats", 200008, localhost->rrd_update_every, RRDSET_TYPE_LINE);
231
232 rd_rq_avg = rrddim_add(st, "avg", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
233 rd_rq_max = rrddim_add(st, "max", NULL, 1, localhost->rrd_update_every, RRD_ALGORITHM_ABSOLUTE);
@@ -216,6 +296,9 @@ void *aclk_stats_main_thread(void *ptr)
296 #endif
297
298 aclk_stats_cloud_req(&per_sample);
299 + aclk_stats_cloud_req_type(&per_sample);
300 + aclk_stats_cloud_req_http_type(&per_sample);
301 +
302 aclk_stats_query_threads(aclk_queries_per_thread_sample);
303
304 aclk_stats_query_time(&per_sample);
aclk/aclk_stats.h
+18
@@ -13,6 +13,11 @@ extern netdata_mutex_t aclk_stats_mutex;
13 #define ACLK_STATS_LOCK netdata_mutex_lock(&aclk_stats_mutex)
14 #define ACLK_STATS_UNLOCK netdata_mutex_unlock(&aclk_stats_mutex)
15
16 +// if you change update `cloud_req_http_type_names`.
17 +#define ACLK_STATS_CLOUD_HTTP_REQ_TYPE_CNT 7
18 +
19 +int aclk_cloud_req_http_type_to_idx(const char *name);
20 +
21 struct aclk_stats_thread {
22 netdata_thread_t *thread;
23 int query_thread_count;
@@ -43,6 +48,19 @@ extern struct aclk_metrics_per_sample {
48 volatile uint32_t cloud_req_recvd;
49 volatile uint32_t cloud_req_err;
50
51 + // request types.
52 + volatile uint32_t cloud_req_type_http;
53 + volatile uint32_t cloud_req_type_alarm_upd;
54 + volatile uint32_t cloud_req_type_metadata_info;
55 + volatile uint32_t cloud_req_type_metadata_alarms;
56 + volatile uint32_t cloud_req_type_chart_new;
57 + volatile uint32_t cloud_req_type_chart_del;
58 + volatile uint32_t cloud_req_type_register_node;
59 + volatile uint32_t cloud_req_type_node_upd;
60 +
61 + // HTTP-specific request types.
62 + volatile uint32_t cloud_req_http_by_type[ACLK_STATS_CLOUD_HTTP_REQ_TYPE_CNT];
63 +
64 volatile uint32_t cloud_q_process_total;
65 volatile uint32_t cloud_q_process_count;
66 volatile uint32_t cloud_q_process_max;