@cryptotaxi247 / netdata-1 / commits / 0717c779c

Add a chart that groups anomaly rate by chart type. (#15856)

* Add a chart that groups anomaly rate by chart type. * Use type_anomaly_rate for context.

vkalintiris committed Aug 24, 2023 at 20:48 UTC 0717c779c3c0b21b2d3b6a87de5326affede8f34
4 files changed +87 -2
collectors/all.h
+2 -1
@@ -403,7 +403,8 @@
403 // [ml] charts
404 #define ML_CHART_PRIO_DIMENSIONS 39181
405 #define ML_CHART_PRIO_ANOMALY_RATE 39182
406 -#define ML_CHART_PRIO_DETECTOR_EVENTS 39183
406 +#define ML_CHART_PRIO_TYPE_ANOMALY_RATE 39183
407 +#define ML_CHART_PRIO_DETECTOR_EVENTS 39184
408
409 // [netdata.ml] charts
410 #define NETDATA_ML_CHART_RUNNING 890001
ml/ad_charts.cc
+51 -1
@@ -222,7 +222,7 @@ void ml_update_dimensions_chart(ml_host_t *host, const ml_machine_learning_stats
222
223 void ml_update_host_and_detection_rate_charts(ml_host_t *host, collected_number AnomalyRate) {
224 /*
225 - * Anomaly rate
225 + * Host anomaly rate
226 */
227 {
228 if (!host->anomaly_rate_rs) {
@@ -258,6 +258,56 @@ void ml_update_host_and_detection_rate_charts(ml_host_t *host, collected_number
258 rrdset_done(host->anomaly_rate_rs);
259 }
260
261 + /*
262 + * Type anomaly rate
263 + */
264 + {
265 + if (!host->type_anomaly_rate_rs) {
266 + char id_buf[1024];
267 + char name_buf[1024];
268 +
269 + snprintfz(id_buf, 1024, "type_anomaly_rate_on_%s", localhost->machine_guid);
270 + snprintfz(name_buf, 1024, "type_anomaly_rate_on_%s", rrdhost_hostname(localhost));
271 +
272 + host->type_anomaly_rate_rs = rrdset_create(
273 + host->rh,
274 + "anomaly_detection", // type
275 + id_buf, // id
276 + name_buf, // name
277 + "anomaly_rate", // family
278 + "anomaly_detection.type_anomaly_rate", // ctx
279 + "Percentage of anomalous dimensions by type", // title
280 + "percentage", // units
281 + NETDATA_ML_PLUGIN, // plugin
282 + NETDATA_ML_MODULE_DETECTION, // module
283 + ML_CHART_PRIO_TYPE_ANOMALY_RATE, // priority
284 + localhost->rrd_update_every, // update_every
285 + RRDSET_TYPE_LINE // chart_type
286 + );
287 +
288 + rrdset_flag_set(host->type_anomaly_rate_rs, RRDSET_FLAG_ANOMALY_DETECTION);
289 + }
290 +
291 + for (auto &entry : host->type_anomaly_rate) {
292 + ml_type_anomaly_rate_t &type_anomaly_rate = entry.second;
293 +
294 + if (!type_anomaly_rate.rd)
295 + type_anomaly_rate.rd = rrddim_add(host->type_anomaly_rate_rs, string2str(entry.first), NULL, 1, 100, RRD_ALGORITHM_ABSOLUTE);
296 +
297 + double ar = 0.0;
298 + size_t n = type_anomaly_rate.anomalous_dimensions + type_anomaly_rate.normal_dimensions;
299 + if (n)
300 + ar = static_cast<double>(type_anomaly_rate.anomalous_dimensions) / n;
301 +
302 + rrddim_set_by_pointer(host->type_anomaly_rate_rs, type_anomaly_rate.rd, ar * 10000.0);
303 +
304 + type_anomaly_rate.anomalous_dimensions = 0;
305 + type_anomaly_rate.normal_dimensions = 0;
306 + }
307 +
308 + rrdset_done(host->type_anomaly_rate_rs);
309 + }
310 +
311 /*
312 * Detector Events
313 */
ml/ml-private.h
+10
@@ -8,6 +8,7 @@
8
9 #include <vector>
10 #include <queue>
11 +#include <unordered_map>
12
13 typedef double calculated_number_t;
14 typedef dlib::matrix<calculated_number_t, 6, 1> DSample;
@@ -210,6 +211,12 @@ typedef struct {
211
212 void ml_chart_update_dimension(ml_chart_t *chart, ml_dimension_t *dim, bool is_anomalous);
213
214 +typedef struct {
215 + RRDDIM *rd;
216 + size_t normal_dimensions;
217 + size_t anomalous_dimensions;
218 +} ml_type_anomaly_rate_t;
219 +
220 typedef struct {
221 RRDHOST *rh;
222
@@ -255,6 +262,9 @@ typedef struct {
262 RRDSET *detector_events_rs;
263 RRDDIM *detector_events_above_threshold_rd;
264 RRDDIM *detector_events_new_anomaly_event_rd;
265 +
266 + RRDSET *type_anomaly_rate_rs;
267 + std::unordered_map<STRING *, ml_type_anomaly_rate_t> type_anomaly_rate;
268 } ml_host_t;
269
270 typedef struct {
ml/ml.cc
+24
@@ -1082,6 +1082,21 @@ ml_host_detect_once(ml_host_t *host)
1082
1083 host->mls.num_anomalous_dimensions += chart_mls.num_anomalous_dimensions;
1084 host->mls.num_normal_dimensions += chart_mls.num_normal_dimensions;
1085 +
1086 + STRING *key = rs->parts.type;
1087 + auto &um = host->type_anomaly_rate;
1088 + auto it = um.find(key);
1089 + if (it == um.end()) {
1090 + um[key] = ml_type_anomaly_rate_t {
1091 + .rd = NULL,
1092 + .normal_dimensions = 0,
1093 + .anomalous_dimensions = 0
1094 + };
1095 + it = um.find(key);
1096 + }
1097 +
1098 + it->second.anomalous_dimensions += chart_mls.num_anomalous_dimensions;
1099 + it->second.normal_dimensions += chart_mls.num_normal_dimensions;
1100 }
1101 rrdset_foreach_done(rsp);
1102
@@ -1095,6 +1110,15 @@ ml_host_detect_once(ml_host_t *host)
1110 netdata_mutex_unlock(&host->mutex);
1111 } else {
1112 host->host_anomaly_rate = 0.0;
1113 +
1114 + auto &um = host->type_anomaly_rate;
1115 + for (auto &entry: um) {
1116 + entry.second = ml_type_anomaly_rate_t {
1117 + .rd = NULL,
1118 + .normal_dimensions = 0,
1119 + .anomalous_dimensions = 0
1120 + };
1121 + }
1122 }
1123
1124 worker_is_busy(WORKER_JOB_DETECTION_DIM_CHART);