@cryptotaxi247 / netdata-1 / commits / 5148e5101

Fill missing removed events after a crash (#12803)

* inject removed events when missing from sqlite * pass flag * remove log message

Emmanuel Vasilakis committed May 5, 2022 at 12:08 UTC 5148e510178967bd138b68cbaa2612a6ca6b7ce7
1 file changed +164
database/sqlite/sqlite_health.c
+164
@@ -433,6 +433,168 @@ void sql_health_alarm_log_count(RRDHOST *host) {
433 info("HEALTH [%s]: Table health_log_%s, contains %lu entries.", host->hostname, uuid_str, host->health_log_entries_written);
434 }
435
436 +#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, " \
437 +"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) " \
438 +"select hostname, ?1, ?2, ?3, config_hash_id, 0, ?4, strftime('%%s'), 0, 0, flags, exec_run_timestamp, " \
439 +"strftime('%%s'), name, chart, family, exec, recipient, source, units, info, exec_code, -2, new_status, delay, NULL, new_value, 0, class, component, type " \
440 +"from health_log_%s where unique_id = ?5", guid, guid2
441 +#define SQL_INJECT_REMOVED_UPDATE(guid) "update health_log_%s set flags = flags | ?1, updated_by_id = ?2 where unique_id = ?3; ", guid
442 +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)
443 +{
444 + int rc = 0;
445 + char command[MAX_HEALTH_SQL_SIZE + 1];
446 +
447 + if (!alarm_id || !alarm_event_id || !unique_id || !max_unique_id)
448 + return;
449 +
450 + sqlite3_stmt *res = NULL;
451 +
452 + snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_INJECT_REMOVED(uuid_str, uuid_str));
453 + rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
454 + if (rc != SQLITE_OK) {
455 + error_report("Failed to prepare statement when trying to inject removed event");
456 + return;
457 + }
458 +
459 + rc = sqlite3_bind_int64(res, 1, (sqlite3_int64) max_unique_id);
460 + if (unlikely(rc != SQLITE_OK)) {
461 + error_report("Failed to bind max_unique_id parameter for SQL_INJECT_REMOVED");
462 + goto failed;
463 + }
464 +
465 + rc = sqlite3_bind_int64(res, 2, (sqlite3_int64) alarm_id);
466 + if (unlikely(rc != SQLITE_OK)) {
467 + error_report("Failed to bind alarm_id parameter for SQL_INJECT_REMOVED");
468 + goto failed;
469 + }
470 +
471 + rc = sqlite3_bind_int64(res, 3, (sqlite3_int64) alarm_event_id + 1);
472 + if (unlikely(rc != SQLITE_OK)) {
473 + error_report("Failed to bind alarm_event_id parameter for SQL_INJECT_REMOVED");
474 + goto failed;
475 + }
476 +
477 + rc = sqlite3_bind_int64(res, 4, (sqlite3_int64) unique_id);
478 + if (unlikely(rc != SQLITE_OK)) {
479 + error_report("Failed to bind unique_id parameter for SQL_INJECT_REMOVED");
480 + goto failed;
481 + }
482 +
483 + rc = sqlite3_bind_int64(res, 5, (sqlite3_int64) unique_id);
484 + if (unlikely(rc != SQLITE_OK)) {
485 + error_report("Failed to bind unique_id parameter for SQL_INJECT_REMOVED");
486 + goto failed;
487 + }
488 +
489 + rc = execute_insert(res);
490 + if (unlikely(rc != SQLITE_DONE)) {
491 + error_report("HEALTH [N/A]: Failed to execute SQL_INJECT_REMOVED, rc = %d", rc);
492 + goto failed;
493 + }
494 +
495 + if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
496 + error_report("HEALTH [N/A]: Failed to finalize the prepared statement for injecting removed event.");
497 +
498 + //update the old entry
499 + snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_INJECT_REMOVED_UPDATE(uuid_str));
500 + rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
501 + if (rc != SQLITE_OK) {
502 + error_report("Failed to prepare statement when trying to update during inject removed event");
503 + return;
504 + }
505 +
506 + rc = sqlite3_bind_int64(res, 1, (sqlite3_int64) HEALTH_ENTRY_FLAG_UPDATED);
507 + if (unlikely(rc != SQLITE_OK)) {
508 + error_report("Failed to bind flags parameter for SQL_INJECT_REMOVED (update)");
509 + goto failed;
510 + }
511 +
512 + rc = sqlite3_bind_int64(res, 2, (sqlite3_int64) max_unique_id);
513 + if (unlikely(rc != SQLITE_OK)) {
514 + error_report("Failed to bind max_unique_id parameter for SQL_INJECT_REMOVED (update)");
515 + goto failed;
516 + }
517 +
518 + rc = sqlite3_bind_int64(res, 3, (sqlite3_int64) unique_id);
519 + if (unlikely(rc != SQLITE_OK)) {
520 + error_report("Failed to bind unique_id parameter for SQL_INJECT_REMOVED (update)");
521 + goto failed;
522 + }
523 +
524 + rc = execute_insert(res);
525 + if (unlikely(rc != SQLITE_DONE)) {
526 + error_report("HEALTH [N/A]: Failed to execute SQL_INJECT_REMOVED_UPDATE, rc = %d", rc);
527 + goto failed;
528 + }
529 +
530 +failed:
531 + if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
532 + error_report("HEALTH [N/A]: Failed to finalize the prepared statement for injecting removed event.");
533 + return;
534 +
535 +}
536 +
537 +#define SQL_SELECT_MAX_UNIQUE_ID(guid) "SELECT MAX(unique_id) from health_log_%s", guid
538 +uint32_t sql_get_max_unique_id (char *uuid_str)
539 +{
540 + int rc = 0;
541 + char command[MAX_HEALTH_SQL_SIZE + 1];
542 + uint32_t max_unique_id = 0;
543 +
544 + sqlite3_stmt *res = NULL;
545 +
546 + snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_SELECT_MAX_UNIQUE_ID(uuid_str));
547 + rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
548 + if (rc != SQLITE_OK) {
549 + error_report("Failed to prepare statement when trying to get max unique id");
550 + return 0;
551 + }
552 +
553 + while (sqlite3_step(res) == SQLITE_ROW) {
554 + max_unique_id = (uint32_t) sqlite3_column_int64(res, 0);
555 + }
556 +
557 + rc = sqlite3_finalize(res);
558 + if (unlikely(rc != SQLITE_OK))
559 + error_report("Failed to finalize the statement");
560 +
561 + return max_unique_id;
562 +}
563 +
564 +#define SQL_SELECT_LAST_STATUSES(guid) "SELECT new_status, unique_id, alarm_id, alarm_event_id from health_log_%s group by alarm_id having max(alarm_event_id)", guid
565 +void sql_check_removed_alerts_state(char *uuid_str)
566 +{
567 + int rc = 0;
568 + char command[MAX_HEALTH_SQL_SIZE + 1];
569 + RRDCALC_STATUS status;
570 + uint32_t alarm_id = 0, alarm_event_id = 0, unique_id = 0, max_unique_id = 0;
571 +
572 + sqlite3_stmt *res = NULL;
573 +
574 + snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_SELECT_LAST_STATUSES(uuid_str));
575 + rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
576 + if (rc != SQLITE_OK) {
577 + error_report("Failed to prepare statement when trying to check removed statuses");
578 + return;
579 + }
580 +
581 + while (sqlite3_step(res) == SQLITE_ROW) {
582 + status = (RRDCALC_STATUS) sqlite3_column_int(res, 0);
583 + unique_id = (uint32_t) sqlite3_column_int64(res, 1);
584 + alarm_id = (uint32_t) sqlite3_column_int64(res, 2);
585 + alarm_event_id = (uint32_t) sqlite3_column_int64(res, 3);
586 + if (unlikely(status != RRDCALC_STATUS_REMOVED)) {
587 + if (unlikely(!max_unique_id))
588 + max_unique_id = sql_get_max_unique_id (uuid_str);
589 + sql_inject_removed_status (uuid_str, alarm_id, alarm_event_id, unique_id, ++max_unique_id);
590 + }
591 + }
592 +
593 + rc = sqlite3_finalize(res);
594 + if (unlikely(rc != SQLITE_OK))
595 + error_report("Failed to finalize the statement");
596 +}
597 +
598 /* Health related SQL queries
599 Load from the health log table
600 */
@@ -454,6 +616,8 @@ void sql_health_alarm_log_load(RRDHOST *host) {
616 char uuid_str[GUID_LEN + 1];
617 uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
618
619 + sql_check_removed_alerts_state(uuid_str);
620 +
621 snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_LOAD_HEALTH_LOG(uuid_str, host->health_log.max));
622
623 rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);