@cryptotaxi247 / netdata-1 / commits / 81174475a

Generate, store and transmit a unique alert event_hash_id (#15111)

* generate and store an event_hash_id * transmit to cloud * transmit to the cloud

Emmanuel Vasilakis committed Jun 5, 2023 at 18:16 UTC 81174475a315fdf5a0b6d23bd5edbae82d028cb1
9 files changed +90 -11
aclk/aclk-schemas
+1 -1
@@ -1 +1 @@
1 -Subproject commit d3a5c636b6dacf364834f2ba99ce0170c71ef861
1 +Subproject commit a9fac9a0e4ebfa021d6f900403626213d28d6852
aclk/schema-wrappers/alarm_stream.cc
+4
@@ -86,6 +86,7 @@ void destroy_alarm_log_entry(struct alarm_log_entry *entry)
86
87 freez(entry->rendered_info);
88 freez(entry->chart_context);
89 + freez(entry->transition_id);
90 }
91
92 static void fill_alarm_log_entry(struct alarm_log_entry *data, AlarmLogEntry *proto)
@@ -134,6 +135,9 @@ static void fill_alarm_log_entry(struct alarm_log_entry *data, AlarmLogEntry *pr
135 proto->set_rendered_info(data->rendered_info);
136
137 proto->set_chart_context(data->chart_context);
138 +
139 + proto->set_event_id(data->event_id);
140 + proto->set_transition_id(data->transition_id);
141 }
142
143 char *generate_alarm_log_entry(size_t *len, struct alarm_log_entry *data)
aclk/schema-wrappers/alarm_stream.h
+3
@@ -73,6 +73,9 @@ struct alarm_log_entry {
73 char *rendered_info;
74
75 char *chart_context;
76 +
77 + uint64_t event_id;
78 + char *transition_id;
79 };
80
81 struct send_alarm_checkpoint {
database/rrd.h
+1
@@ -977,6 +977,7 @@ struct alarm_entry {
977 uint32_t alarm_id;
978 uint32_t alarm_event_id;
979 uuid_t config_hash_id;
980 + uuid_t transition_id;
981
982 time_t when;
983 time_t duration;
database/sqlite/sqlite_aclk_alert.c
+13 -1
@@ -285,7 +285,7 @@ void aclk_push_alert_event(struct aclk_sync_host_config *wc)
285 buffer_sprintf(sql, "select aa.sequence_id, hl.unique_id, hl.alarm_id, hl.config_hash_id, hl.updated_by_id, hl.when_key, " \
286 " hl.duration, hl.non_clear_duration, hl.flags, hl.exec_run_timestamp, hl.delay_up_to_timestamp, hl.name, " \
287 " hl.chart, hl.family, hl.exec, hl.recipient, hl.source, hl.units, hl.info, hl.exec_code, hl.new_status, " \
288 - " hl.old_status, hl.delay, hl.new_value, hl.old_value, hl.last_repeat, hl.chart_context " \
288 + " hl.old_status, hl.delay, hl.new_value, hl.old_value, hl.last_repeat, hl.chart_context, hl.transition_id, hl.alarm_event_id " \
289 " from health_log_%s hl, aclk_alert_%s aa " \
290 " where hl.unique_id = aa.alert_unique_id and aa.date_submitted is null " \
291 " order by aa.sequence_id asc limit %d;", wc->uuid_str, wc->uuid_str, limit);
@@ -395,6 +395,13 @@ void aclk_push_alert_event(struct aclk_sync_host_config *wc)
395 strdupz((char *)"") :
396 strdupz((char *)sqlite3_column_text(res, 26));
397
398 + uuid_unparse_lower(*((uuid_t *) sqlite3_column_blob(res, 27)), uuid_str);
399 + alarm_log.transition_id = sqlite3_column_type(res, 27) == SQLITE_NULL ?
400 + strdupz((char *)"") :
401 + strdupz((char *)uuid_str);
402 +
403 + alarm_log.event_id = (time_t) sqlite3_column_int64(res, 28);
404 +
405 aclk_send_alarm_log_entry(&alarm_log);
406
407 if (first_sequence_id == 0)
@@ -749,6 +756,8 @@ void health_alarm_entry2proto_nolock(struct alarm_log_entry *alarm_log, ALARM_EN
756 char *edit_command = ae->source ? health_edit_command_from_source(ae_source(ae)) : strdupz("UNKNOWN=0=UNKNOWN");
757 char config_hash_id[UUID_STR_LEN];
758 uuid_unparse_lower(ae->config_hash_id, config_hash_id);
759 + char transition_id[UUID_STR_LEN];
760 + uuid_unparse_lower(ae->transition_id, transition_id);
761
762 alarm_log->chart = strdupz(ae_chart_name(ae));
763 alarm_log->name = strdupz(ae_name(ae));
@@ -790,6 +799,9 @@ void health_alarm_entry2proto_nolock(struct alarm_log_entry *alarm_log, ALARM_EN
799 alarm_log->rendered_info = strdupz(ae_info(ae));
800 alarm_log->chart_context = strdupz(ae_chart_context(ae));
801
802 + alarm_log->transition_id = strdupz((char *)transition_id);
803 + alarm_log->event_id = (uint64_t) ae->alarm_event_id;
804 +
805 freez(edit_command);
806 }
807 #endif
database/sqlite/sqlite_db_migration.c
+33
@@ -182,6 +182,38 @@ static int do_migration_v6_v7(sqlite3 *database, const char *name)
182 return 0;
183 }
184
185 +static int do_migration_v7_v8(sqlite3 *database, const char *name)
186 +{
187 + UNUSED(name);
188 + info("Running database migration %s", name);
189 +
190 + char sql[256];
191 +
192 + int rc;
193 + sqlite3_stmt *res = NULL;
194 + snprintfz(sql, 255, "SELECT name FROM sqlite_schema WHERE type ='table' AND name LIKE 'health_log_%%';");
195 + rc = sqlite3_prepare_v2(database, sql, -1, &res, 0);
196 + if (rc != SQLITE_OK) {
197 + error_report("Failed to prepare statement to alter health_log tables");
198 + return 1;
199 + }
200 +
201 + while (sqlite3_step_monitored(res) == SQLITE_ROW) {
202 + char *table = strdupz((char *) sqlite3_column_text(res, 0));
203 + if (!column_exists_in_table(table, "transition_id")) {
204 + snprintfz(sql, 255, "ALTER TABLE %s ADD transition_id blob", table);
205 + sqlite3_exec_monitored(database, sql, 0, 0, NULL);
206 + }
207 + freez(table);
208 + }
209 +
210 + rc = sqlite3_finalize(res);
211 + if (unlikely(rc != SQLITE_OK))
212 + error_report("Failed to finalize statement when altering health_log tables, rc = %d", rc);
213 +
214 + return 0;
215 +}
216 +
217
218 static int do_migration_noop(sqlite3 *database, const char *name)
219 {
@@ -233,6 +265,7 @@ DATABASE_FUNC_MIGRATION_LIST migration_action[] = {
265 {.name = "v4 to v5", .func = do_migration_v4_v5},
266 {.name = "v5 to v6", .func = do_migration_v5_v6},
267 {.name = "v6 to v7", .func = do_migration_v6_v7},
268 + {.name = "v7 to v8", .func = do_migration_v7_v8},
269 // the terminator of this array
270 {.name = NULL, .func = NULL}
271 };
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 7
6 +#define DB_METADATA_VERSION 8
7
8 const char *database_config[] = {
9 "CREATE TABLE IF NOT EXISTS host(host_id BLOB PRIMARY KEY, hostname TEXT NOT NULL, "
database/sqlite/sqlite_health.c
+32 -8
@@ -3,6 +3,7 @@
3 #include "sqlite_health.h"
4 #include "sqlite_functions.h"
5 #include "sqlite_db_migration.h"
6 +#include "uuid.h"
7
8 #define MAX_HEALTH_SQL_SIZE 2048
9 #define sqlite3_bind_string_or_null(res,key,param) ((key) ? sqlite3_bind_text(res, param, string2str(key), -1, SQLITE_STATIC) : sqlite3_bind_null(res, param))
@@ -10,7 +11,7 @@
11 /* Health related SQL queries
12 Creates a health log table in sqlite, one per host guid
13 */
13 -#define SQL_CREATE_HEALTH_LOG_TABLE(guid) "CREATE TABLE IF NOT EXISTS health_log_%s(hostname text, unique_id int, alarm_id int, alarm_event_id int, config_hash_id blob, updated_by_id int, updates_id int, when_key int, duration int, non_clear_duration int, flags int, exec_run_timestamp int, delay_up_to_timestamp int, name text, chart text, family text, exec text, recipient text, source text, units text, info text, exec_code int, new_status real, old_status real, delay int, new_value double, old_value double, last_repeat int, class text, component text, type text, chart_context text);", guid
14 +#define SQL_CREATE_HEALTH_LOG_TABLE(guid) "CREATE TABLE IF NOT EXISTS health_log_%s(hostname text, unique_id int, alarm_id int, alarm_event_id int, config_hash_id blob, updated_by_id int, updates_id int, when_key int, duration int, non_clear_duration int, flags int, exec_run_timestamp int, delay_up_to_timestamp int, name text, chart text, family text, exec text, recipient text, source text, units text, info text, exec_code int, new_status real, old_status real, delay int, new_value double, old_value double, last_repeat int, class text, component text, type text, chart_context text, transition_id blob);", guid
15 int sql_create_health_log_table(RRDHOST *host) {
16 int rc;
17 char command[MAX_HEALTH_SQL_SIZE + 1];
@@ -116,7 +117,7 @@ failed:
117 "config_hash_id, updated_by_id, updates_id, when_key, duration, non_clear_duration, flags, " \
118 "exec_run_timestamp, delay_up_to_timestamp, name, chart, family, exec, recipient, source, " \
119 "units, info, exec_code, new_status, old_status, delay, new_value, old_value, last_repeat, " \
119 - "class, component, type, chart_context) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", guid
120 + "class, component, type, chart_context, transition_id) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", guid
121
122 void sql_health_alarm_log_insert(RRDHOST *host, ALARM_ENTRY *ae) {
123 sqlite3_stmt *res = NULL;
@@ -336,6 +337,12 @@ void sql_health_alarm_log_insert(RRDHOST *host, ALARM_ENTRY *ae) {
337 goto failed;
338 }
339
340 + rc = sqlite3_bind_blob(res, 33, &ae->transition_id, sizeof(ae->transition_id), SQLITE_STATIC);
341 + if (unlikely(rc != SQLITE_OK)) {
342 + error_report("Failed to bind transition_id parameter for SQL_INSERT_HEALTH_LOG");
343 + goto failed;
344 + }
345 +
346 rc = execute_insert(res);
347 if (unlikely(rc != SQLITE_DONE)) {
348 error_report("HEALTH [%s]: Failed to execute SQL_INSERT_HEALTH_LOG, rc = %d", rrdhost_hostname(host), rc);
@@ -510,10 +517,10 @@ void sql_health_alarm_log_cleanup(RRDHOST *host) {
517 }
518
519 #define SQL_INJECT_REMOVED(guid, guid2) "insert into health_log_%s (hostname, unique_id, alarm_id, alarm_event_id, config_hash_id, updated_by_id, updates_id, when_key, duration, non_clear_duration, flags, exec_run_timestamp, " \
513 -"delay_up_to_timestamp, name, chart, family, exec, recipient, source, units, info, exec_code, new_status, old_status, delay, new_value, old_value, last_repeat, class, component, type, chart_context) " \
520 +"delay_up_to_timestamp, name, chart, family, exec, recipient, source, units, info, exec_code, new_status, old_status, delay, new_value, old_value, last_repeat, class, component, type, chart_context, transition_id) " \
521 "select hostname, ?1, ?2, ?3, config_hash_id, 0, ?4, unixepoch(), 0, 0, flags, exec_run_timestamp, " \
515 -"unixepoch(), name, chart, family, exec, recipient, source, units, info, exec_code, -2, new_status, delay, NULL, new_value, 0, class, component, type, chart_context " \
516 -"from health_log_%s where unique_id = ?5", guid, guid2
522 +"unixepoch(), name, chart, family, exec, recipient, source, units, info, exec_code, -2, new_status, delay, NULL, new_value, 0, class, component, type, chart_context, ?5 " \
523 +"from health_log_%s where unique_id = ?6", guid, guid2
524 #define SQL_INJECT_REMOVED_UPDATE(guid) "update health_log_%s set flags = flags | ?1, updated_by_id = ?2 where unique_id = ?3; ", guid
525 void sql_inject_removed_status(char *uuid_str, uint32_t alarm_id, uint32_t alarm_event_id, uint32_t unique_id, uint32_t max_unique_id)
526 {
@@ -556,7 +563,15 @@ void sql_inject_removed_status(char *uuid_str, uint32_t alarm_id, uint32_t alarm
563 goto failed;
564 }
565
559 - rc = sqlite3_bind_int64(res, 5, (sqlite3_int64) unique_id);
566 + uuid_t transition_id;
567 + uuid_generate_random(transition_id);
568 + rc = sqlite3_bind_blob(res, 5, &transition_id, sizeof(transition_id), SQLITE_STATIC);
569 + if (unlikely(rc != SQLITE_OK)) {
570 + error_report("Failed to bind config_hash_id parameter for SQL_INSERT_HEALTH_LOG");
571 + goto failed;
572 + }
573 +
574 + rc = sqlite3_bind_int64(res, 6, (sqlite3_int64) unique_id);
575 if (unlikely(rc != SQLITE_OK)) {
576 error_report("Failed to bind unique_id parameter for SQL_INJECT_REMOVED");
577 goto failed;
@@ -674,7 +689,7 @@ void sql_check_removed_alerts_state(char *uuid_str)
689 /* Health related SQL queries
690 Load from the health log table
691 */
677 -#define SQL_LOAD_HEALTH_LOG(guid) "SELECT hostname, unique_id, alarm_id, alarm_event_id, config_hash_id, updated_by_id, updates_id, when_key, duration, non_clear_duration, flags, exec_run_timestamp, delay_up_to_timestamp, name, chart, family, exec, recipient, source, units, info, exec_code, new_status, old_status, delay, new_value, old_value, last_repeat, class, component, type, chart_context FROM health_log_%s group by alarm_id having max(alarm_event_id);", guid
692 +#define SQL_LOAD_HEALTH_LOG(guid) "SELECT hostname, unique_id, alarm_id, alarm_event_id, config_hash_id, updated_by_id, updates_id, when_key, duration, non_clear_duration, flags, exec_run_timestamp, delay_up_to_timestamp, name, chart, family, exec, recipient, source, units, info, exec_code, new_status, old_status, delay, new_value, old_value, last_repeat, class, component, type, chart_context, transition_id FROM health_log_%s group by alarm_id having max(alarm_event_id);", guid
693 void sql_health_alarm_log_load(RRDHOST *host) {
694 sqlite3_stmt *res = NULL;
695 int ret;
@@ -844,6 +859,9 @@ void sql_health_alarm_log_load(RRDHOST *host) {
859 else
860 ae->chart_context = NULL;
861
862 + if (sqlite3_column_type(res, 32) != SQLITE_NULL)
863 + uuid_copy(ae->transition_id, *((uuid_t *) sqlite3_column_blob(res, 32)));
864 +
865 char value_string[100 + 1];
866 string_freez(ae->old_value_string);
867 string_freez(ae->new_value_string);
@@ -1190,7 +1208,7 @@ int sql_health_get_last_executed_event(RRDHOST *host, ALARM_ENTRY *ae, RRDCALC_S
1208 return ret;
1209 }
1210
1193 -#define SQL_SELECT_HEALTH_LOG(guid) "SELECT hostname, unique_id, alarm_id, alarm_event_id, config_hash_id, updated_by_id, updates_id, when_key, duration, non_clear_duration, flags, exec_run_timestamp, delay_up_to_timestamp, name, chart, family, exec, recipient, source, units, info, exec_code, new_status, old_status, delay, new_value, old_value, last_repeat, class, component, type, chart_context FROM health_log_%s WHERE 1=1 ", guid
1211 +#define SQL_SELECT_HEALTH_LOG(guid) "SELECT hostname, unique_id, alarm_id, alarm_event_id, config_hash_id, updated_by_id, updates_id, when_key, duration, non_clear_duration, flags, exec_run_timestamp, delay_up_to_timestamp, name, chart, family, exec, recipient, source, units, info, exec_code, new_status, old_status, delay, new_value, old_value, last_repeat, class, component, type, chart_context, transition_id FROM health_log_%s WHERE 1=1 ", guid
1212 void sql_health_alarm_log2json(RRDHOST *host, BUFFER *wb, uint32_t after, char *chart) {
1213
1214 buffer_strcat(wb, "[");
@@ -1240,6 +1258,10 @@ void sql_health_alarm_log2json(RRDHOST *host, BUFFER *wb, uint32_t after, char *
1258 char config_hash_id[UUID_STR_LEN];
1259 uuid_unparse_lower(*((uuid_t *) sqlite3_column_blob(res, 4)), config_hash_id);
1260
1261 + char transition_id[UUID_STR_LEN] = {0};
1262 + if (sqlite3_column_type(res, 32) != SQLITE_NULL)
1263 + uuid_unparse_lower(*((uuid_t *) sqlite3_column_blob(res, 32)), transition_id);
1264 +
1265 char *edit_command = health_edit_command_from_source((char *)sqlite3_column_text(res, 18));
1266
1267 if (count)
@@ -1257,6 +1279,7 @@ void sql_health_alarm_log2json(RRDHOST *host, BUFFER *wb, uint32_t after, char *
1279 "\t\t\"alarm_id\": %u,\n"
1280 "\t\t\"alarm_event_id\": %u,\n"
1281 "\t\t\"config_hash_id\": \"%s\",\n"
1282 + "\t\t\"transition_id\": \"%s\",\n"
1283 "\t\t\"name\": \"%s\",\n"
1284 "\t\t\"chart\": \"%s\",\n"
1285 "\t\t\"context\": \"%s\",\n"
@@ -1294,6 +1317,7 @@ void sql_health_alarm_log2json(RRDHOST *host, BUFFER *wb, uint32_t after, char *
1317 (unsigned int) sqlite3_column_int64(res, 2),
1318 (unsigned int) sqlite3_column_int64(res, 3),
1319 config_hash_id,
1320 + transition_id,
1321 sqlite3_column_text(res, 13),
1322 sqlite3_column_text(res, 14),
1323 sqlite3_column_text(res, 31),
health/health_log.c
+2
@@ -46,6 +46,8 @@ inline ALARM_ENTRY* health_create_alarm_entry(
46
47 uuid_copy(ae->config_hash_id, *((uuid_t *) config_hash_id));
48
49 + uuid_generate_random(ae->transition_id);
50 +
51 ae->family = string_dup(family);
52 ae->classification = string_dup(class);
53 ae->component = string_dup(component);