| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #define PULSE_INTERNALS 1 |
| 4 | #include "pulse-queries.h" |
| 5 | #include "streaming/stream-replication-sender.h" |
| 6 | |
| 7 | static struct query_statistics { |
| 8 | PAD64(uint64_t) api_data_queries_made; |
| 9 | PAD64(uint64_t) api_data_db_points_read; |
| 10 | PAD64(uint64_t) api_data_result_points_generated; |
| 11 | |
| 12 | PAD64(uint64_t) api_weights_queries_made; |
| 13 | PAD64(uint64_t) api_weights_db_points_read; |
| 14 | PAD64(uint64_t) api_weights_result_points_generated; |
| 15 | |
| 16 | PAD64(uint64_t) api_badges_queries_made; |
| 17 | PAD64(uint64_t) api_badges_db_points_read; |
| 18 | PAD64(uint64_t) api_badges_result_points_generated; |
| 19 | |
| 20 | PAD64(uint64_t) health_queries_made; |
| 21 | PAD64(uint64_t) health_db_points_read; |
| 22 | PAD64(uint64_t) health_result_points_generated; |
| 23 | |
| 24 | PAD64(uint64_t) ml_queries_made; |
| 25 | PAD64(uint64_t) ml_db_points_read; |
| 26 | PAD64(uint64_t) ml_result_points_generated; |
| 27 | |
| 28 | PAD64(uint64_t) backfill_queries_made; |
| 29 | PAD64(uint64_t) backfill_db_points_read; |
| 30 | |
| 31 | PAD64(uint64_t) exporters_queries_made; |
| 32 | PAD64(uint64_t) exporters_db_points_read; |
| 33 | } query_statistics = { 0 }; |
| 34 | |
| 35 | ALWAYS_INLINE void pulse_queries_ml_query_completed(size_t points_read) { |
| 36 | __atomic_fetch_add(&query_statistics.ml_queries_made, 1, __ATOMIC_RELAXED); |
| 37 | __atomic_fetch_add(&query_statistics.ml_db_points_read, points_read, __ATOMIC_RELAXED); |
| 38 | } |
| 39 | |
| 40 | ALWAYS_INLINE void pulse_queries_exporters_query_completed(size_t points_read) { |
| 41 | __atomic_fetch_add(&query_statistics.exporters_queries_made, 1, __ATOMIC_RELAXED); |
| 42 | __atomic_fetch_add(&query_statistics.exporters_db_points_read, points_read, __ATOMIC_RELAXED); |
| 43 | } |
| 44 | |
| 45 | ALWAYS_INLINE void pulse_queries_backfill_query_completed(size_t points_read) { |
| 46 | __atomic_fetch_add(&query_statistics.backfill_queries_made, 1, __ATOMIC_RELAXED); |
| 47 | __atomic_fetch_add(&query_statistics.backfill_db_points_read, points_read, __ATOMIC_RELAXED); |
| 48 | } |
| 49 | |
| 50 | ALWAYS_INLINE void pulse_queries_rrdr_query_completed(size_t queries, uint64_t db_points_read, uint64_t result_points_generated, QUERY_SOURCE query_source) { |
| 51 | switch(query_source) { |
| 52 | case QUERY_SOURCE_API_DATA: |
| 53 | __atomic_fetch_add(&query_statistics.api_data_queries_made, queries, __ATOMIC_RELAXED); |
| 54 | __atomic_fetch_add(&query_statistics.api_data_db_points_read, db_points_read, __ATOMIC_RELAXED); |
| 55 | __atomic_fetch_add(&query_statistics.api_data_result_points_generated, result_points_generated, __ATOMIC_RELAXED); |
| 56 | break; |
| 57 | |
| 58 | case QUERY_SOURCE_ML: |
| 59 | __atomic_fetch_add(&query_statistics.ml_queries_made, queries, __ATOMIC_RELAXED); |
| 60 | __atomic_fetch_add(&query_statistics.ml_db_points_read, db_points_read, __ATOMIC_RELAXED); |
| 61 | __atomic_fetch_add(&query_statistics.ml_result_points_generated, result_points_generated, __ATOMIC_RELAXED); |
| 62 | break; |
| 63 | |
| 64 | case QUERY_SOURCE_API_WEIGHTS: |
| 65 | __atomic_fetch_add(&query_statistics.api_weights_queries_made, queries, __ATOMIC_RELAXED); |
| 66 | __atomic_fetch_add(&query_statistics.api_weights_db_points_read, db_points_read, __ATOMIC_RELAXED); |
| 67 | __atomic_fetch_add(&query_statistics.api_weights_result_points_generated, result_points_generated, __ATOMIC_RELAXED); |
| 68 | break; |
| 69 | |
| 70 | case QUERY_SOURCE_API_BADGE: |
| 71 | __atomic_fetch_add(&query_statistics.api_badges_queries_made, queries, __ATOMIC_RELAXED); |
| 72 | __atomic_fetch_add(&query_statistics.api_badges_db_points_read, db_points_read, __ATOMIC_RELAXED); |
| 73 | __atomic_fetch_add(&query_statistics.api_badges_result_points_generated, result_points_generated, __ATOMIC_RELAXED); |
| 74 | break; |
| 75 | |
| 76 | case QUERY_SOURCE_HEALTH: |
| 77 | __atomic_fetch_add(&query_statistics.health_queries_made, queries, __ATOMIC_RELAXED); |
| 78 | __atomic_fetch_add(&query_statistics.health_db_points_read, db_points_read, __ATOMIC_RELAXED); |
| 79 | __atomic_fetch_add(&query_statistics.health_result_points_generated, result_points_generated, __ATOMIC_RELAXED); |
| 80 | break; |
| 81 | |
| 82 | default: |
| 83 | case QUERY_SOURCE_UNITTEST: |
| 84 | case QUERY_SOURCE_UNKNOWN: |
| 85 | break; |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | static inline void pulse_queries_copy(struct query_statistics *gs) { |
| 90 | gs->api_data_queries_made = __atomic_load_n(&query_statistics.api_data_queries_made, __ATOMIC_RELAXED); |
| 91 | gs->api_data_db_points_read = __atomic_load_n(&query_statistics.api_data_db_points_read, __ATOMIC_RELAXED); |
| 92 | gs->api_data_result_points_generated = __atomic_load_n(&query_statistics.api_data_result_points_generated, __ATOMIC_RELAXED); |
| 93 | |
| 94 | gs->api_weights_queries_made = __atomic_load_n(&query_statistics.api_weights_queries_made, __ATOMIC_RELAXED); |
| 95 | gs->api_weights_db_points_read = __atomic_load_n(&query_statistics.api_weights_db_points_read, __ATOMIC_RELAXED); |
| 96 | gs->api_weights_result_points_generated = __atomic_load_n(&query_statistics.api_weights_result_points_generated, __ATOMIC_RELAXED); |
| 97 | |
| 98 | gs->api_badges_queries_made = __atomic_load_n(&query_statistics.api_badges_queries_made, __ATOMIC_RELAXED); |
| 99 | gs->api_badges_db_points_read = __atomic_load_n(&query_statistics.api_badges_db_points_read, __ATOMIC_RELAXED); |
| 100 | gs->api_badges_result_points_generated = __atomic_load_n(&query_statistics.api_badges_result_points_generated, __ATOMIC_RELAXED); |
| 101 | |
| 102 | gs->health_queries_made = __atomic_load_n(&query_statistics.health_queries_made, __ATOMIC_RELAXED); |
| 103 | gs->health_db_points_read = __atomic_load_n(&query_statistics.health_db_points_read, __ATOMIC_RELAXED); |
| 104 | gs->health_result_points_generated = __atomic_load_n(&query_statistics.health_result_points_generated, __ATOMIC_RELAXED); |
| 105 | |
| 106 | gs->ml_queries_made = __atomic_load_n(&query_statistics.ml_queries_made, __ATOMIC_RELAXED); |
| 107 | gs->ml_db_points_read = __atomic_load_n(&query_statistics.ml_db_points_read, __ATOMIC_RELAXED); |
| 108 | gs->ml_result_points_generated = __atomic_load_n(&query_statistics.ml_result_points_generated, __ATOMIC_RELAXED); |
| 109 | |
| 110 | gs->exporters_queries_made = __atomic_load_n(&query_statistics.exporters_queries_made, __ATOMIC_RELAXED); |
| 111 | gs->exporters_db_points_read = __atomic_load_n(&query_statistics.exporters_db_points_read, __ATOMIC_RELAXED); |
| 112 | gs->backfill_queries_made = __atomic_load_n(&query_statistics.backfill_queries_made, __ATOMIC_RELAXED); |
| 113 | gs->backfill_db_points_read = __atomic_load_n(&query_statistics.backfill_db_points_read, __ATOMIC_RELAXED); |
| 114 | } |
| 115 | |
| 116 | void pulse_queries_do(bool extended __maybe_unused) { |
| 117 | static struct query_statistics gs; |
| 118 | pulse_queries_copy(&gs); |
| 119 | |
| 120 | struct replication_query_statistics replication = replication_get_query_statistics(); |
| 121 | |
| 122 | { |
| 123 | static RRDSET *st_queries = NULL; |
| 124 | static RRDDIM *rd_api_data_queries = NULL; |
| 125 | static RRDDIM *rd_api_weights_queries = NULL; |
| 126 | static RRDDIM *rd_api_badges_queries = NULL; |
| 127 | static RRDDIM *rd_health_queries = NULL; |
| 128 | static RRDDIM *rd_ml_queries = NULL; |
| 129 | static RRDDIM *rd_exporters_queries = NULL; |
| 130 | static RRDDIM *rd_backfill_queries = NULL; |
| 131 | static RRDDIM *rd_replication_queries = NULL; |
| 132 | |
| 133 | if (unlikely(!st_queries)) { |
| 134 | st_queries = rrdset_create_localhost( |
| 135 | "netdata" |
| 136 | , "queries" |
| 137 | , NULL |
| 138 | , "Time-Series Queries" |
| 139 | , "netdata.db_queries" |
| 140 | , "Netdata Time-Series DB Queries" |
| 141 | , "queries/s" |
| 142 | , "netdata" |
| 143 | , "pulse" |
| 144 | , 131000 |
| 145 | , localhost->rrd_update_every |
| 146 | , RRDSET_TYPE_STACKED |
| 147 | ); |
| 148 | |
| 149 | rd_api_data_queries = rrddim_add(st_queries, "/api/vX/data", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 150 | rd_api_weights_queries = rrddim_add(st_queries, "/api/vX/weights", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 151 | rd_api_badges_queries = rrddim_add(st_queries, "/api/vX/badge", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 152 | rd_health_queries = rrddim_add(st_queries, "health", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 153 | rd_ml_queries = rrddim_add(st_queries, "ml", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 154 | rd_exporters_queries = rrddim_add(st_queries, "exporters", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 155 | rd_backfill_queries = rrddim_add(st_queries, "backfill", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 156 | rd_replication_queries = rrddim_add(st_queries, "replication", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 157 | } |
| 158 | |
| 159 | rrddim_set_by_pointer(st_queries, rd_api_data_queries, (collected_number)gs.api_data_queries_made); |
| 160 | rrddim_set_by_pointer(st_queries, rd_api_weights_queries, (collected_number)gs.api_weights_queries_made); |
| 161 | rrddim_set_by_pointer(st_queries, rd_api_badges_queries, (collected_number)gs.api_badges_queries_made); |
| 162 | rrddim_set_by_pointer(st_queries, rd_health_queries, (collected_number)gs.health_queries_made); |
| 163 | rrddim_set_by_pointer(st_queries, rd_ml_queries, (collected_number)gs.ml_queries_made); |
| 164 | rrddim_set_by_pointer(st_queries, rd_exporters_queries, (collected_number)gs.exporters_queries_made); |
| 165 | rrddim_set_by_pointer(st_queries, rd_backfill_queries, (collected_number)gs.backfill_queries_made); |
| 166 | rrddim_set_by_pointer(st_queries, rd_replication_queries, (collected_number)replication.queries_finished); |
| 167 | |
| 168 | rrdset_done(st_queries); |
| 169 | } |
| 170 | |
| 171 | { |
| 172 | static RRDSET *st_points_read = NULL; |
| 173 | static RRDDIM *rd_api_data_points_read = NULL; |
| 174 | static RRDDIM *rd_api_weights_points_read = NULL; |
| 175 | static RRDDIM *rd_api_badges_points_read = NULL; |
| 176 | static RRDDIM *rd_health_points_read = NULL; |
| 177 | static RRDDIM *rd_ml_points_read = NULL; |
| 178 | static RRDDIM *rd_exporters_points_read = NULL; |
| 179 | static RRDDIM *rd_backfill_points_read = NULL; |
| 180 | static RRDDIM *rd_replication_points_read = NULL; |
| 181 | |
| 182 | if (unlikely(!st_points_read)) { |
| 183 | st_points_read = rrdset_create_localhost( |
| 184 | "netdata" |
| 185 | , "db_samples_read" |
| 186 | , NULL |
| 187 | , "Time-Series Queries" |
| 188 | , NULL |
| 189 | , "Netdata Time-Series DB Samples Read" |
| 190 | , "samples/s" |
| 191 | , "netdata" |
| 192 | , "pulse" |
| 193 | , 131001 |
| 194 | , localhost->rrd_update_every |
| 195 | , RRDSET_TYPE_STACKED |
| 196 | ); |
| 197 | |
| 198 | rd_api_data_points_read = rrddim_add(st_points_read, "/api/vX/data", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 199 | rd_api_weights_points_read = rrddim_add(st_points_read, "/api/vX/weights", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 200 | rd_api_badges_points_read = rrddim_add(st_points_read, "/api/vX/badge", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 201 | rd_health_points_read = rrddim_add(st_points_read, "health", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 202 | rd_ml_points_read = rrddim_add(st_points_read, "ml", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 203 | rd_exporters_points_read = rrddim_add(st_points_read, "exporters", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 204 | rd_backfill_points_read = rrddim_add(st_points_read, "backfill", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 205 | rd_replication_points_read = rrddim_add(st_points_read, "replication", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 206 | } |
| 207 | |
| 208 | rrddim_set_by_pointer(st_points_read, rd_api_data_points_read, (collected_number)gs.api_data_db_points_read); |
| 209 | rrddim_set_by_pointer(st_points_read, rd_api_weights_points_read, (collected_number)gs.api_weights_db_points_read); |
| 210 | rrddim_set_by_pointer(st_points_read, rd_api_badges_points_read, (collected_number)gs.api_badges_db_points_read); |
| 211 | rrddim_set_by_pointer(st_points_read, rd_health_points_read, (collected_number)gs.health_db_points_read); |
| 212 | rrddim_set_by_pointer(st_points_read, rd_ml_points_read, (collected_number)gs.ml_db_points_read); |
| 213 | rrddim_set_by_pointer(st_points_read, rd_exporters_points_read, (collected_number)gs.exporters_db_points_read); |
| 214 | rrddim_set_by_pointer(st_points_read, rd_backfill_points_read, (collected_number)gs.backfill_db_points_read); |
| 215 | rrddim_set_by_pointer(st_points_read, rd_replication_points_read, (collected_number)replication.points_read); |
| 216 | |
| 217 | rrdset_done(st_points_read); |
| 218 | } |
| 219 | |
| 220 | if(gs.api_data_result_points_generated || replication.points_generated) { |
| 221 | static RRDSET *st_points_generated = NULL; |
| 222 | static RRDDIM *rd_api_data_points_generated = NULL; |
| 223 | static RRDDIM *rd_api_weights_points_generated = NULL; |
| 224 | static RRDDIM *rd_api_badges_points_generated = NULL; |
| 225 | static RRDDIM *rd_health_points_generated = NULL; |
| 226 | static RRDDIM *rd_ml_points_generated = NULL; |
| 227 | static RRDDIM *rd_replication_points_generated = NULL; |
| 228 | |
| 229 | if (unlikely(!st_points_generated)) { |
| 230 | st_points_generated = rrdset_create_localhost( |
| 231 | "netdata" |
| 232 | , "db_points_results" |
| 233 | , NULL |
| 234 | , "Time-Series Queries" |
| 235 | , NULL |
| 236 | , "Netdata Time-Series Points Generated" |
| 237 | , "points/s" |
| 238 | , "netdata" |
| 239 | , "pulse" |
| 240 | , 131002 |
| 241 | , localhost->rrd_update_every |
| 242 | , RRDSET_TYPE_STACKED |
| 243 | ); |
| 244 | |
| 245 | rd_api_data_points_generated = rrddim_add(st_points_generated, "/api/vX/data", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 246 | rd_api_weights_points_generated = rrddim_add(st_points_generated, "/api/vX/weights", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 247 | rd_api_badges_points_generated = rrddim_add(st_points_generated, "/api/vX/badge", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 248 | rd_health_points_generated = rrddim_add(st_points_generated, "health", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 249 | rd_ml_points_generated = rrddim_add(st_points_generated, "ml", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 250 | rd_replication_points_generated = rrddim_add(st_points_generated, "replication", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL); |
| 251 | } |
| 252 | |
| 253 | rrddim_set_by_pointer(st_points_generated, rd_api_data_points_generated, (collected_number)gs.api_data_result_points_generated); |
| 254 | rrddim_set_by_pointer(st_points_generated, rd_api_weights_points_generated, (collected_number)gs.api_weights_result_points_generated); |
| 255 | rrddim_set_by_pointer(st_points_generated, rd_api_badges_points_generated, (collected_number)gs.api_badges_result_points_generated); |
| 256 | rrddim_set_by_pointer(st_points_generated, rd_health_points_generated, (collected_number)gs.health_result_points_generated); |
| 257 | rrddim_set_by_pointer(st_points_generated, rd_ml_points_generated, (collected_number)gs.ml_result_points_generated); |
| 258 | rrddim_set_by_pointer(st_points_generated, rd_replication_points_generated, (collected_number)replication.points_generated); |
| 259 | |
| 260 | rrdset_done(st_points_generated); |
| 261 | } |
| 262 | } |