| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #include "database/rrd.h" |
| 4 | #include "web/api/queries/rrdr.h" |
| 5 | #include "health_prototypes.h" |
| 6 | |
| 7 | #ifndef NETDATA_RRDCALC_H |
| 8 | #define NETDATA_RRDCALC_H 1 |
| 9 | |
| 10 | // calculated variables (defined in health configuration) |
| 11 | // These aggregate time-series data at fixed intervals |
| 12 | // (defined in their update_every member below) |
| 13 | // They increase the overhead of netdata. |
| 14 | // |
| 15 | // These calculations are stored under RRDHOST. |
| 16 | // Then are also linked to RRDSET (of course only when a |
| 17 | // matching chart is found). |
| 18 | |
| 19 | typedef enum rrdcalc_status { |
| 20 | RRDCALC_STATUS_REMOVED = -2, |
| 21 | RRDCALC_STATUS_UNDEFINED = -1, |
| 22 | RRDCALC_STATUS_UNINITIALIZED = 0, |
| 23 | RRDCALC_STATUS_CLEAR = 1, |
| 24 | RRDCALC_STATUS_RAISED = 2, // DO NOT CHANGE THESE NUMBERS |
| 25 | RRDCALC_STATUS_WARNING = 3, // DO NOT CHANGE THESE NUMBERS |
| 26 | RRDCALC_STATUS_CRITICAL = 4, // DO NOT CHANGE THESE NUMBERS |
| 27 | } RRDCALC_STATUS; |
| 28 | |
| 29 | typedef enum { |
| 30 | RRDCALC_FLAG_DB_ERROR = (1 << 0), |
| 31 | RRDCALC_FLAG_DB_NAN = (1 << 1), |
| 32 | // RRDCALC_FLAG_DB_STALE = (1 << 2), |
| 33 | RRDCALC_FLAG_CALC_ERROR = (1 << 3), |
| 34 | RRDCALC_FLAG_WARN_ERROR = (1 << 4), |
| 35 | RRDCALC_FLAG_CRIT_ERROR = (1 << 5), |
| 36 | RRDCALC_FLAG_RUNNABLE = (1 << 6), |
| 37 | RRDCALC_FLAG_DISABLED = (1 << 7), |
| 38 | RRDCALC_FLAG_SILENCED = (1 << 8), |
| 39 | RRDCALC_FLAG_RUN_ONCE = (1 << 9), |
| 40 | } RRDCALC_FLAGS; |
| 41 | void rrdcalc_flags_to_json_array(BUFFER *wb, const char *key, RRDCALC_FLAGS flags); |
| 42 | |
| 43 | #define RRDCALC_ALL_OPTIONS_EXCLUDING_THE_RRDR_ONES (RRDCALC_OPTION_NO_CLEAR_NOTIFICATION) |
| 44 | |
| 45 | struct rrdcalc { |
| 46 | uint32_t id; // the unique id of this alarm |
| 47 | uint32_t next_event_id; // the next event id that will be used for this alarm |
| 48 | |
| 49 | STRING *key; // the unique key in the host's rrdcalc_root_index |
| 50 | STRING *chart; // the chart id this should be linked to |
| 51 | |
| 52 | struct rrd_alert_config config; |
| 53 | |
| 54 | // ------------------------------------------------------------------------ |
| 55 | // runtime information |
| 56 | |
| 57 | STRING *summary; // the original summary field before any variable replacement |
| 58 | STRING *info; // the original info field before any variable replacement |
| 59 | |
| 60 | RRDCALC_STATUS old_status; // the old status of the alarm |
| 61 | RRDCALC_STATUS status; // the current status of the alarm |
| 62 | |
| 63 | NETDATA_DOUBLE value; // the current value of the alarm |
| 64 | NETDATA_DOUBLE old_value; // the previous value of the alarm |
| 65 | NETDATA_DOUBLE last_status_change_value; // the value at the last status change |
| 66 | |
| 67 | RRDCALC_FLAGS run_flags; // check RRDCALC_FLAG_* |
| 68 | |
| 69 | time_t last_updated; // the last update timestamp of the alarm |
| 70 | time_t next_update; // the next update timestamp of the alarm |
| 71 | time_t last_status_change; // the timestamp of the last time this alarm changed status |
| 72 | time_t last_repeat; // the last time the alarm got repeated |
| 73 | uint32_t times_repeat; // number of times the alarm got repeated |
| 74 | |
| 75 | time_t db_after; // the first timestamp evaluated by the db lookup |
| 76 | time_t db_before; // the last timestamp evaluated by the db lookup |
| 77 | |
| 78 | time_t delay_up_to_timestamp; // the timestamp up to which we should delay notifications |
| 79 | int delay_up_current; // the current up notification delay duration |
| 80 | int delay_down_current; // the current down notification delay duration |
| 81 | int delay_last; // the last delay we used |
| 82 | |
| 83 | // ------------------------------------------------------------------------ |
| 84 | // the chart this alarm it is linked to |
| 85 | |
| 86 | uint32_t labels_version; |
| 87 | struct rrdset *rrdset; |
| 88 | |
| 89 | struct rrdcalc *next; |
| 90 | struct rrdcalc *prev; |
| 91 | }; |
| 92 | |
| 93 | #define rrdcalc_name(rc) string2str((rc)->config.name) |
| 94 | #define rrdcalc_chart_name(rc) string2str((rc)->chart) |
| 95 | #define rrdcalc_exec(rc) string2str((rc)->config.exec) |
| 96 | #define rrdcalc_recipient(rc) string2str((rc)->config.recipient) |
| 97 | #define rrdcalc_classification(rc) string2str((rc)->config.classification) |
| 98 | #define rrdcalc_component(rc) string2str((rc)->config.component) |
| 99 | #define rrdcalc_type(rc) string2str((rc)->config.type) |
| 100 | #define rrdcalc_source(rc) string2str((rc)->config.source) |
| 101 | #define rrdcalc_units(rc) string2str((rc)->config.units) |
| 102 | #define rrdcalc_dimensions(rc) string2str((rc)->config.dimensions) |
| 103 | |
| 104 | #define foreach_rrdcalc_in_rrdhost_write(host, rc) \ |
| 105 | dfe_start_write((host)->rrdcalc_root_index, rc) \ |
| 106 | |
| 107 | #define foreach_rrdcalc_in_rrdhost_read(host, rc) \ |
| 108 | dfe_start_read((host)->rrdcalc_root_index, rc) \ |
| 109 | |
| 110 | #define foreach_rrdcalc_in_rrdhost_reentrant(host, rc) \ |
| 111 | dfe_start_reentrant((host)->rrdcalc_root_index, rc) |
| 112 | |
| 113 | #define foreach_rrdcalc_in_rrdhost_done(rc) \ |
| 114 | dfe_done(rc) |
| 115 | |
| 116 | #define RRDCALC_HAS_DB_LOOKUP(rc) ((rc)->config.after) |
| 117 | |
| 118 | void rrdcalc_update_info_using_rrdset_labels(RRDCALC *rc); |
| 119 | |
| 120 | const RRDCALC_ACQUIRED *rrdcalc_from_rrdset_get(RRDSET *st, const char *alert_name); |
| 121 | void rrdcalc_from_rrdset_release(RRDSET *st, const RRDCALC_ACQUIRED *rca); |
| 122 | RRDCALC *rrdcalc_acquired_to_rrdcalc(const RRDCALC_ACQUIRED *rca); |
| 123 | |
| 124 | const char *rrdcalc_status2string(RRDCALC_STATUS status); |
| 125 | |
| 126 | uint32_t rrdcalc_get_unique_id(RRDHOST *host, STRING *chart, STRING *name, uint32_t *next_event_id, nd_uuid_t *config_hash_id); |
| 127 | |
| 128 | static inline int rrdcalc_isrepeating(RRDCALC *rc) { |
| 129 | if (unlikely(rc->config.warn_repeat_every > 0 || rc->config.crit_repeat_every > 0)) { |
| 130 | return 1; |
| 131 | } |
| 132 | return 0; |
| 133 | } |
| 134 | |
| 135 | void rrdcalc_unlink_and_delete_all_rrdset_alerts(RRDSET *st); |
| 136 | void rrdcalc_delete_all(RRDHOST *host); |
| 137 | |
| 138 | void rrdcalc_rrdhost_index_init(RRDHOST *host); |
| 139 | void rrdcalc_rrdhost_index_destroy(RRDHOST *host); |
| 140 | |
| 141 | void rrdcalc_unlink_and_delete(RRDHOST *host, RRDCALC *rc, bool having_ll_wrlock); |
| 142 | |
| 143 | #define RRDCALC_VAR_MAX 100 |
| 144 | #define RRDCALC_VAR_FAMILY "${family}" |
| 145 | #define RRDCALC_VAR_LABEL "${label:" |
| 146 | #define RRDCALC_VAR_LABEL_LEN (sizeof(RRDCALC_VAR_LABEL)-1) |
| 147 | |
| 148 | void rrdcalc_child_disconnected(RRDHOST *host); |
| 149 | |
| 150 | #endif //NETDATA_RRDCALC_H |