@cryptotaxi247 / netdata-1 / commits / 880c9fbc6

alerts_transitions outputs hostnames and items statistics (#15329)

* alerts_transitions outputs hostnames and items statistics * return details about the items in the database * added comments to items list and made the whole of statsd available under debug

Costa Tsaousis committed Jul 9, 2023 at 17:02 UTC 880c9fbc61bf5b7d7fde43309a2a5837ebede86d
1 file changed +68 -36
database/contexts/api_v2.c
+68 -36
@@ -69,14 +69,17 @@ struct alert_transitions_callback_data {
69 DICTIONARY *dict;
70 } facets[ATF_TOTAL_ENTRIES];
71
72 - uint32_t limit;
73 - uint32_t items;
72 + uint32_t max_items_to_return;
73 + uint32_t items_to_return;
74 +
75 + uint32_t items_evaluated;
76 + uint32_t items_matched;
77 +
78
79 struct sql_alert_transition_fixed_size *base; // double linked list - last item is base->prev
80 struct sql_alert_transition_fixed_size *last_added; // the last item added, not the last of the list
81
82 struct {
79 - size_t items;
83 size_t first;
84 size_t skips_before;
85 size_t skips_after;
@@ -85,7 +88,7 @@ struct alert_transitions_callback_data {
88 size_t prepend;
89 size_t append;
90 size_t shifts;
88 - } stats;
91 + } operations;
92
93 uint32_t configs_added;
94 };
@@ -1452,76 +1455,78 @@ static void contexts_v2_alert_transition_free(struct sql_alert_transition_fixed_
1455 }
1456
1457 static inline void contexts_v2_alert_transition_keep(struct alert_transitions_callback_data *d, struct sql_alert_transition_data *t, const char *machine_guid) {
1458 + d->items_matched++;
1459 +
1460 if(unlikely(t->global_id <= d->ctl->request->alerts.global_id_anchor)) {
1461 // this is in our past, we are not interested
1457 - d->stats.skips_before++;
1462 + d->operations.skips_before++;
1463 return;
1464 }
1465
1466 if(unlikely(!d->base)) {
1467 d->last_added = contexts_v2_alert_transition_dup(t, machine_guid, NULL);
1468 DOUBLE_LINKED_LIST_APPEND_ITEM_UNSAFE(d->base, d->last_added, prev, next);
1464 - d->items++;
1465 - d->stats.first++;
1469 + d->items_to_return++;
1470 + d->operations.first++;
1471 return;
1472 }
1473
1474 struct sql_alert_transition_fixed_size *last = d->last_added;
1475 while(last->prev != d->base->prev && t->global_id > last->prev->global_id) {
1476 last = last->prev;
1472 - d->stats.backwards++;
1477 + d->operations.backwards++;
1478 }
1479
1480 while(last->next && t->global_id < last->next->global_id) {
1481 last = last->next;
1477 - d->stats.forwards++;
1482 + d->operations.forwards++;
1483 }
1484
1480 - if(d->items >= d->limit) {
1485 + if(d->items_to_return >= d->max_items_to_return) {
1486 if(last == d->base->prev && t->global_id < last->global_id) {
1482 - d->stats.skips_after++;
1487 + d->operations.skips_after++;
1488 return;
1489 }
1490 }
1491
1487 - d->items++;
1492 + d->items_to_return++;
1493
1494 if(t->global_id > last->global_id) {
1490 - if(d->items > d->limit) {
1491 - d->items--;
1492 - d->stats.shifts++;
1495 + if(d->items_to_return > d->max_items_to_return) {
1496 + d->items_to_return--;
1497 + d->operations.shifts++;
1498 d->last_added = d->base->prev;
1499 DOUBLE_LINKED_LIST_REMOVE_ITEM_UNSAFE(d->base, d->last_added, prev, next);
1500 d->last_added = contexts_v2_alert_transition_dup(t, machine_guid, d->last_added);
1501 }
1502 DOUBLE_LINKED_LIST_PREPEND_ITEM_UNSAFE(d->base, d->last_added, prev, next);
1498 - d->stats.prepend++;
1503 + d->operations.prepend++;
1504 }
1505 else {
1506 d->last_added = contexts_v2_alert_transition_dup(t, machine_guid, NULL);
1507 DOUBLE_LINKED_LIST_APPEND_ITEM_UNSAFE(d->base, d->last_added, prev, next);
1503 - d->stats.append++;
1508 + d->operations.append++;
1509 }
1510
1506 - while(d->items > d->limit) {
1511 + while(d->items_to_return > d->max_items_to_return) {
1512 // we have to remove something
1513
1514 struct sql_alert_transition_fixed_size *tmp = d->base->prev;
1515 DOUBLE_LINKED_LIST_REMOVE_ITEM_UNSAFE(d->base, tmp, prev, next);
1511 - d->items--;
1516 + d->items_to_return--;
1517
1518 if(unlikely(d->last_added == tmp))
1519 d->last_added = d->base;
1520
1521 contexts_v2_alert_transition_free(tmp);
1522
1518 - d->stats.shifts++;
1523 + d->operations.shifts++;
1524 }
1525 }
1526
1527 static void contexts_v2_alert_transition_callback(struct sql_alert_transition_data *t, void *data) {
1528 struct alert_transitions_callback_data *d = data;
1524 - d->stats.items++;
1529 + d->items_evaluated++;
1530
1531 char machine_guid[UUID_STR_LEN] = "";
1532 uuid_unparse_lower(*t->host_id, machine_guid);
@@ -1591,8 +1596,8 @@ static void contexts_v2_alert_transitions_to_json(BUFFER *wb, struct rrdcontext_
1596 .ctl = ctl,
1597 .debug = debug,
1598 .only_one_config = true,
1594 - .limit = ctl->request->alerts.last,
1595 - .items = 0,
1599 + .max_items_to_return = ctl->request->alerts.last,
1600 + .items_to_return = 0,
1601 .base = NULL,
1602 };
1603
@@ -1658,8 +1663,12 @@ static void contexts_v2_alert_transitions_to_json(BUFFER *wb, struct rrdcontext_
1663 buffer_json_member_add_uuid(wb, "config_hash_id", &t->config_hash_id);
1664 buffer_json_member_add_string(wb, "machine_guid", t->machine_guid);
1665
1661 - if(host && host->node_id)
1662 - buffer_json_member_add_uuid(wb, "node_id", host->node_id);
1666 + if(host) {
1667 + buffer_json_member_add_string(wb, "hostname", rrdhost_hostname(host));
1668 +
1669 + if(host->node_id)
1670 + buffer_json_member_add_uuid(wb, "node_id", host->node_id);
1671 + }
1672
1673 buffer_json_member_add_string(wb, "alert", *t->alert_name ? t->alert_name : NULL);
1674 buffer_json_member_add_string(wb, "instance", *t->chart ? t->chart : NULL);
@@ -1730,19 +1739,42 @@ static void contexts_v2_alert_transitions_to_json(BUFFER *wb, struct rrdcontext_
1739 simple_pattern_free(data.facets[i].pattern);
1740 }
1741
1733 - buffer_json_member_add_object(wb, "stats");
1742 + buffer_json_member_add_object(wb, "items");
1743 {
1735 - buffer_json_member_add_uint64(wb, "items", data.stats.items);
1736 - buffer_json_member_add_uint64(wb, "first", data.stats.first);
1737 - buffer_json_member_add_uint64(wb, "prepend", data.stats.prepend);
1738 - buffer_json_member_add_uint64(wb, "append", data.stats.append);
1739 - buffer_json_member_add_uint64(wb, "backwards", data.stats.backwards);
1740 - buffer_json_member_add_uint64(wb, "forwards", data.stats.forwards);
1741 - buffer_json_member_add_uint64(wb, "shifts", data.stats.shifts);
1742 - buffer_json_member_add_uint64(wb, "skips_before", data.stats.skips_before);
1743 - buffer_json_member_add_uint64(wb, "skips_after", data.stats.skips_after);
1744 + // all the items in the window, under the scope_nodes, ignoring the facets (filters)
1745 + buffer_json_member_add_uint64(wb, "evaluated", data.items_evaluated);
1746 +
1747 + // all the items matching the query (if you didn't put anchor_gi and last, these are all the items you would get back)
1748 + buffer_json_member_add_uint64(wb, "matched", data.items_matched);
1749 +
1750 + // the items included in this response
1751 + buffer_json_member_add_uint64(wb, "returned", data.items_to_return);
1752 +
1753 + // same as last=X parameter
1754 + buffer_json_member_add_uint64(wb, "max_to_return", data.max_items_to_return);
1755 +
1756 + // items before the first returned, this should be 0 if anchor_gi is not set
1757 + buffer_json_member_add_uint64(wb, "before", data.operations.skips_before);
1758 +
1759 + // items after the last returned, when this is zero there aren't any items after the current list
1760 + buffer_json_member_add_uint64(wb, "after", data.operations.skips_after + data.operations.shifts);
1761 + }
1762 + buffer_json_object_close(wb); // items
1763 +
1764 + if(debug) {
1765 + buffer_json_member_add_object(wb, "stats");
1766 + {
1767 + buffer_json_member_add_uint64(wb, "first", data.operations.first);
1768 + buffer_json_member_add_uint64(wb, "prepend", data.operations.prepend);
1769 + buffer_json_member_add_uint64(wb, "append", data.operations.append);
1770 + buffer_json_member_add_uint64(wb, "backwards", data.operations.backwards);
1771 + buffer_json_member_add_uint64(wb, "forwards", data.operations.forwards);
1772 + buffer_json_member_add_uint64(wb, "shifts", data.operations.shifts);
1773 + buffer_json_member_add_uint64(wb, "skips_before", data.operations.skips_before);
1774 + buffer_json_member_add_uint64(wb, "skips_after", data.operations.skips_after);
1775 + }
1776 + buffer_json_object_close(wb);
1777 }
1745 - buffer_json_object_close(wb);
1778 }
1779
1780 int rrdcontext_to_json_v2(BUFFER *wb, struct api_v2_contexts_request *req, CONTEXTS_V2_MODE mode) {