Reduce unnecessary alert events to the cloud (#13897)
* reduce alert events to the cloud * proper column, set filtered when queing existing * increase max removed period to a day * add constraint, fix queries
Emmanuel Vasilakis committed
Nov 4, 2022 at 19:50 UTC
c51dd576b07b5cbf6d4d883bca8c85d603fed399
4 files changed
+62
-18
database/sqlite/sqlite_aclk.h
+1
-1
@@ -67,7 +67,7 @@ static inline void uuid_unparse_lower_fix(uuid_t *uuid, char *out)
67
}
68
69
#define TABLE_ACLK_ALERT "CREATE TABLE IF NOT EXISTS aclk_alert_%s (sequence_id INTEGER PRIMARY KEY, " \
70
- "alert_unique_id, date_created, date_submitted, date_cloud_ack, " \
70
+ "alert_unique_id, date_created, date_submitted, date_cloud_ack, filtered_alert_unique_id NOT NULL, " \
71
"unique(alert_unique_id));"
72
73
#define INDEX_ACLK_ALERT "CREATE INDEX IF NOT EXISTS aclk_alert_index_%s ON aclk_alert_%s (alert_unique_id);"
database/sqlite/sqlite_aclk_alert.c
+25
-16
@@ -36,7 +36,14 @@ time_t removed_when(uint32_t alarm_id, uint32_t before_unique_id, uint32_t after
36
return when;
37
}
38
39
-#define MAX_REMOVED_PERIOD 900
39
+void update_filtered(ALARM_ENTRY *ae, uint32_t unique_id, char *uuid_str) {
40
+ char sql[ACLK_SYNC_QUERY_SIZE];
41
+ snprintfz(sql, ACLK_SYNC_QUERY_SIZE-1, "UPDATE aclk_alert_%s SET filtered_alert_unique_id = %u where filtered_alert_unique_id = %u", uuid_str, ae->unique_id, unique_id);
42
+ sqlite3_exec_monitored(db_meta, sql, 0, 0, NULL);
43
+ ae->flags |= HEALTH_ENTRY_FLAG_ACLK_QUEUED;
44
+}
45
+
46
+#define MAX_REMOVED_PERIOD 86400
47
//decide if some events should be sent or not
48
int should_send_to_cloud(RRDHOST *host, ALARM_ENTRY *ae)
49
{
@@ -56,12 +63,13 @@ int should_send_to_cloud(RRDHOST *host, ALARM_ENTRY *ae)
63
uuid_t config_hash_id;
64
RRDCALC_STATUS status;
65
uint32_t unique_id;
59
-
66
+
67
//get the previous sent event of this alarm_id
68
+ //base the search on the last filtered event
69
snprintfz(sql,ACLK_SYNC_QUERY_SIZE-1, "select hl.new_status, hl.config_hash_id, hl.unique_id from health_log_%s hl, aclk_alert_%s aa \
62
- where hl.unique_id = aa.alert_unique_id \
63
- and hl.alarm_id = %u and hl.unique_id <> %u \
64
- order by alarm_event_id desc LIMIT 1;", uuid_str, uuid_str, ae->alarm_id, ae->unique_id);
70
+ where hl.unique_id = aa.filtered_alert_unique_id \
71
+ and hl.alarm_id = %u \
72
+ order by alarm_event_id desc LIMIT 1;", uuid_str, uuid_str, ae->alarm_id);
73
74
rc = sqlite3_prepare_v2(db_meta, sql, -1, &res, 0);
75
if (rc != SQLITE_OK) {
@@ -93,8 +101,9 @@ int should_send_to_cloud(RRDHOST *host, ALARM_ENTRY *ae)
101
}
102
103
//same status, same config
96
- if (ae->new_status == RRDCALC_STATUS_CLEAR) {
104
+ if (ae->new_status == RRDCALC_STATUS_CLEAR || ae->new_status == RRDCALC_STATUS_UNDEFINED) {
105
send = 0;
106
+ update_filtered(ae, unique_id, uuid_str);
107
goto done;
108
}
109
@@ -107,6 +116,7 @@ int should_send_to_cloud(RRDHOST *host, ALARM_ENTRY *ae)
116
goto done;
117
} else {
118
send = 0;
119
+ update_filtered(ae, unique_id, uuid_str);
120
goto done;
121
}
122
}
@@ -130,6 +140,8 @@ int sql_queue_alarm_to_aclk(RRDHOST *host, ALARM_ENTRY *ae, int skip_filter)
140
return 0;
141
}
142
143
+ CHECK_SQLITE_CONNECTION(db_meta);
144
+
145
if (!skip_filter) {
146
if (!should_send_to_cloud(host, ae)) {
147
return 0;
@@ -137,9 +149,6 @@ int sql_queue_alarm_to_aclk(RRDHOST *host, ALARM_ENTRY *ae, int skip_filter)
149
}
150
151
int rc = 0;
140
-
141
- CHECK_SQLITE_CONNECTION(db_meta);
142
-
152
sqlite3_stmt *res_alert = NULL;
153
char uuid_str[GUID_LEN + 1];
154
uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
@@ -148,8 +157,8 @@ int sql_queue_alarm_to_aclk(RRDHOST *host, ALARM_ENTRY *ae, int skip_filter)
157
158
buffer_sprintf(
159
sql,
151
- "INSERT INTO aclk_alert_%s (alert_unique_id, date_created) "
152
- "VALUES (@alert_unique_id, unixepoch()) on conflict (alert_unique_id) do nothing; ",
160
+ "INSERT INTO aclk_alert_%s (alert_unique_id, date_created, filtered_alert_unique_id) "
161
+ "VALUES (@alert_unique_id, unixepoch(), @alert_unique_id) on conflict (alert_unique_id) do nothing; ",
162
uuid_str);
163
164
rc = sqlite3_prepare_v2(db_meta, buffer_tostring(sql), -1, &res_alert, 0);
@@ -401,8 +410,8 @@ void sql_queue_existing_alerts_to_aclk(RRDHOST *host)
410
BUFFER *sql = buffer_create(1024);
411
412
buffer_sprintf(sql,"delete from aclk_alert_%s; " \
404
- "insert into aclk_alert_%s (alert_unique_id, date_created) " \
405
- "select unique_id alert_unique_id, unixepoch() from health_log_%s " \
413
+ "insert into aclk_alert_%s (alert_unique_id, date_created, filtered_alert_unique_id) " \
414
+ "select unique_id alert_unique_id, unixepoch(), unique_id alert_unique_id from health_log_%s " \
415
"where new_status <> 0 and new_status <> -2 and config_hash_id is not null and updated_by_id = 0 " \
416
"order by unique_id asc on conflict (alert_unique_id) do nothing;", uuid_str, uuid_str, uuid_str);
417
@@ -728,8 +737,8 @@ void sql_process_queue_removed_alerts_to_aclk(struct aclk_database_worker_config
737
738
BUFFER *sql = buffer_create(1024);
739
731
- buffer_sprintf(sql,"insert into aclk_alert_%s (alert_unique_id, date_created) " \
732
- "select unique_id alert_unique_id, unixepoch() from health_log_%s " \
740
+ buffer_sprintf(sql,"insert into aclk_alert_%s (alert_unique_id, date_created, filtered_alert_unique_id) " \
741
+ "select unique_id alert_unique_id, unixepoch(), unique_id alert_unique_id from health_log_%s " \
742
"where new_status = -2 and updated_by_id = 0 and unique_id not in " \
743
"(select alert_unique_id from aclk_alert_%s) order by unique_id asc " \
744
"on conflict (alert_unique_id) do nothing;", wc->uuid_str, wc->uuid_str, wc->uuid_str);
@@ -1015,7 +1024,7 @@ void sql_aclk_alert_clean_dead_entries(RRDHOST *host)
1024
1025
BUFFER *sql = buffer_create(1024);
1026
1018
- buffer_sprintf(sql,"delete from aclk_alert_%s where alert_unique_id not in "
1027
+ buffer_sprintf(sql,"delete from aclk_alert_%s where filtered_alert_unique_id not in "
1028
" (select unique_id from health_log_%s); ", uuid_str, uuid_str);
1029
1030
char *err_msg = NULL;
database/sqlite/sqlite_db_migration.c
+35
@@ -148,6 +148,40 @@ static int do_migration_v5_v6(sqlite3 *database, const char *name)
148
return init_database_batch(database, DB_CHECK_NONE, 0, &database_migrate_v5_v6[0]);
149
}
150
151
+static int do_migration_v6_v7(sqlite3 *database, const char *name)
152
+{
153
+ UNUSED(name);
154
+ info("Running \"%s\" database migration", name);
155
+
156
+ char sql[256];
157
+
158
+ int rc;
159
+ sqlite3_stmt *res = NULL;
160
+ snprintfz(sql, 255, "SELECT name FROM sqlite_schema WHERE type ='table' AND name LIKE 'aclk_alert_%%';");
161
+ rc = sqlite3_prepare_v2(database, sql, -1, &res, 0);
162
+ if (rc != SQLITE_OK) {
163
+ error_report("Failed to prepare statement to alter aclk_alert tables");
164
+ return 1;
165
+ }
166
+
167
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
168
+ char *table = strdupz((char *) sqlite3_column_text(res, 0));
169
+ if (!column_exists_in_table(table, "filtered_alert_unique_id")) {
170
+ snprintfz(sql, 255, "ALTER TABLE %s ADD filtered_alert_unique_id", table);
171
+ sqlite3_exec_monitored(database, sql, 0, 0, NULL);
172
+ snprintfz(sql, 255, "UPDATE %s SET filtered_alert_unique_id = alert_unique_id", table);
173
+ sqlite3_exec_monitored(database, sql, 0, 0, NULL);
174
+ }
175
+ freez(table);
176
+ }
177
+
178
+ rc = sqlite3_finalize(res);
179
+ if (unlikely(rc != SQLITE_OK))
180
+ error_report("Failed to finalize statement when altering aclk_alert tables, rc = %d", rc);
181
+
182
+ return 0;
183
+}
184
+
185
186
static int do_migration_noop(sqlite3 *database, const char *name)
187
{
@@ -198,6 +232,7 @@ DATABASE_FUNC_MIGRATION_LIST migration_action[] = {
232
{.name = "v3 to v4", .func = do_migration_v3_v4},
233
{.name = "v4 to v5", .func = do_migration_v4_v5},
234
{.name = "v5 to v6", .func = do_migration_v5_v6},
235
+ {.name = "v6 to v7", .func = do_migration_v6_v7},
236
// the terminator of this array
237
{.name = NULL, .func = NULL}
238
};
database/sqlite/sqlite_functions.c
+1
-1
@@ -3,7 +3,7 @@
3
#include "sqlite_functions.h"
4
#include "sqlite_db_migration.h"
5
6
-#define DB_METADATA_VERSION 6
6
+#define DB_METADATA_VERSION 7
7
8
const char *database_config[] = {
9
"CREATE TABLE IF NOT EXISTS host(host_id BLOB PRIMARY KEY, hostname TEXT NOT NULL, "