| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #include "pulse-db-dbengine-retention.h" |
| 4 | #ifdef ENABLE_DBENGINE |
| 5 | #include "database/engine/rrdengineapi.h" |
| 6 | |
| 7 | void dbengine_retention_statistics(bool extended __maybe_unused) { |
| 8 | |
| 9 | static bool init = false; |
| 10 | static DBENGINE_TIER_STATS stats[RRD_STORAGE_TIERS]; |
| 11 | |
| 12 | if (!localhost) |
| 13 | return; |
| 14 | |
| 15 | rrdeng_calculate_tier_disk_space_percentage(); |
| 16 | |
| 17 | for (size_t tier = 0; tier < nd_profile.storage_tiers; tier++) { |
| 18 | STORAGE_ENGINE *eng = localhost->db[tier].eng; |
| 19 | if (!eng || eng->seb != STORAGE_ENGINE_BACKEND_DBENGINE) |
| 20 | continue; |
| 21 | |
| 22 | if (init == false) { |
| 23 | char id[200]; |
| 24 | snprintfz(id, sizeof(id) - 1, "dbengine_retention_tier%zu", tier); |
| 25 | stats[tier].st = rrdset_create_localhost( |
| 26 | "netdata", |
| 27 | id, |
| 28 | NULL, |
| 29 | "dbengine retention", |
| 30 | "netdata.dbengine_tier_retention", |
| 31 | "dbengine space and time retention", |
| 32 | "%", |
| 33 | "netdata", |
| 34 | "stats", |
| 35 | 134900, // before "dbengine memory" (dbengine2_statistics_charts) |
| 36 | 10, |
| 37 | RRDSET_TYPE_LINE); |
| 38 | |
| 39 | stats[tier].rd_space = rrddim_add(stats[tier].st, "space", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); |
| 40 | stats[tier].rd_time = rrddim_add(stats[tier].st, "time", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); |
| 41 | |
| 42 | char tier_str[5]; |
| 43 | snprintfz(tier_str, 4, "%zu", tier); |
| 44 | rrdlabels_add(stats[tier].st->rrdlabels, "tier", tier_str, RRDLABEL_SRC_AUTO); |
| 45 | |
| 46 | rrdset_flag_set(stats[tier].st, RRDSET_FLAG_METADATA_UPDATE); |
| 47 | rrdhost_flag_set(stats[tier].st->rrdhost, RRDHOST_FLAG_METADATA_UPDATE); |
| 48 | rrdset_metadata_updated(stats[tier].st); |
| 49 | } |
| 50 | |
| 51 | time_t first_time_s = storage_engine_global_first_time_s(eng->seb, localhost->db[tier].si); |
| 52 | time_t retention = first_time_s ? now_realtime_sec() - first_time_s : 0; |
| 53 | |
| 54 | // |
| 55 | // Note: storage_engine_disk_space_used is the exact diskspace (as reported by api/v2/node_instances |
| 56 | // get_used_disk_space is used to determine if database cleanup (file rotation should happen) |
| 57 | // and adds to the disk space used the desired file size of the active |
| 58 | // datafile |
| 59 | uint64_t disk_space = rrdeng_get_used_disk_space(multidb_ctx[tier], false); |
| 60 | //uint64_t disk_space = storage_engine_disk_space_used(eng->seb, localhost->db[tier].si); |
| 61 | |
| 62 | uint64_t config_disk_space = storage_engine_disk_space_max(eng->seb, localhost->db[tier].si); |
| 63 | if (!config_disk_space) { |
| 64 | config_disk_space = rrdeng_get_directory_free_bytes_space(multidb_ctx[tier]); |
| 65 | config_disk_space += disk_space; |
| 66 | } |
| 67 | |
| 68 | collected_number disk_percentage = (collected_number) (config_disk_space ? 100 * disk_space / config_disk_space : 0); |
| 69 | |
| 70 | collected_number retention_percentage = (collected_number)multidb_ctx[tier]->config.max_retention_s ? |
| 71 | 100 * retention / multidb_ctx[tier]->config.max_retention_s : |
| 72 | 0; |
| 73 | |
| 74 | if (retention_percentage > 100) |
| 75 | retention_percentage = 100; |
| 76 | |
| 77 | rrddim_set_by_pointer(stats[tier].st, stats[tier].rd_space, (collected_number) disk_percentage); |
| 78 | rrddim_set_by_pointer(stats[tier].st, stats[tier].rd_time, (collected_number) retention_percentage); |
| 79 | |
| 80 | rrdset_done(stats[tier].st); |
| 81 | } |
| 82 | init = true; |
| 83 | } |
| 84 | #endif |