Store host label information in the metadata database (#13441)
* Create new host_label table * Add generic function to store chart and host labels Add function to store host labels Cleanup old host labels * Store labels from localhost and children (streaming) Remove the host label info if the host is deleted * Delete host labels before insert
Stelios Fragkakis committed
Jul 28, 2022 at 21:53 UTC
9a6fd6366fafc5585b3fe9d2be2258df4738050d
5 files changed
+89
-28
collectors/plugins.d/pluginsd_parser.c
+1
@@ -201,6 +201,7 @@ PARSER_RC pluginsd_overwrite_action(void *user, RRDHOST *host, DICTIONARY *new_h
201
host->host_labels = rrdlabels_create();
202
203
rrdlabels_migrate_to_these(host->host_labels, new_host_labels);
204
+ sql_store_host_labels(host);
205
206
return PARSER_RC_OK;
207
}
database/rrd.h
+2
@@ -209,6 +209,8 @@ typedef enum rrdlabel_source {
209
RRDLABEL_FLAG_NEW = (1 << 31) // marks for rrdlabels internal use - they are not exposed outside rrdlabels
210
} RRDLABEL_SRC;
211
212
+#define RRDLABEL_FLAG_INTERNAL (RRDLABEL_FLAG_OLD | RRDLABEL_FLAG_NEW | RRDLABEL_FLAG_PERMANENT)
213
+
214
extern DICTIONARY *rrdlabels_create(void);
215
extern void rrdlabels_destroy(DICTIONARY *labels_dict);
216
extern void rrdlabels_add(DICTIONARY *dict, const char *name, const char *value, RRDLABEL_SRC ls);
database/rrdhost.c
+1
@@ -1362,6 +1362,7 @@ void reload_host_labels(void) {
1362
rrdhost_load_auto_labels();
1363
1364
rrdlabels_remove_all_unmarked(localhost->host_labels);
1365
+ sql_store_host_labels(localhost);
1366
1367
health_label_log_save(localhost);
1368
database/sqlite/sqlite_functions.c
+84
-28
@@ -42,6 +42,9 @@ const char *database_config[] = {
42
"CREATE TABLE IF NOT EXISTS host_info(host_id blob, system_key text NOT NULL, system_value text NOT NULL, "
43
"date_created INT, PRIMARY KEY(host_id, system_key));",
44
45
+ "CREATE TABLE IF NOT EXISTS host_label(host_id blob, source_type int, label_key text NOT NULL, "
46
+ "label_value text NOT NULL, date_created INT, PRIMARY KEY (host_id, label_key));",
47
+
48
"CREATE TABLE IF NOT EXISTS chart_hash_map(chart_id blob , hash_id blob, UNIQUE (chart_id, hash_id));",
49
50
"CREATE TABLE IF NOT EXISTS chart_hash(hash_id blob PRIMARY KEY,type text, id text, name text, "
@@ -74,6 +77,7 @@ const char *database_cleanup[] = {
77
"DELETE FROM chart_hash WHERE hash_id NOT IN (SELECT hash_id FROM chart_hash_map);",
78
"DELETE FROM node_instance WHERE host_id NOT IN (SELECT host_id FROM host);",
79
"DELETE FROM host_info WHERE host_id NOT IN (SELECT host_id FROM host);",
80
+ "DELETE FROM host_label WHERE host_id NOT IN (SELECT host_id FROM host);",
81
NULL
82
};
83
@@ -764,7 +768,7 @@ static int exec_statement_with_uuid(const char *sql, uuid_t *uuid)
768
769
rc = execute_insert(res);
770
if (likely(rc == SQLITE_DONE))
767
- result = 0;
771
+ result = SQLITE_OK;
772
else
773
error_report("Failed to execute %s, rc = %d", sql, rc);
774
@@ -1599,6 +1603,45 @@ void add_migrated_file(char *path, uint64_t file_size)
1603
return;
1604
}
1605
1606
+static int sql_store_label(sqlite3_stmt *res, uuid_t *uuid, int source_type, const char *label, const char *value)
1607
+{
1608
+ int rc;
1609
+
1610
+ rc = sqlite3_bind_blob(res, 1, uuid, sizeof(*uuid), SQLITE_STATIC);
1611
+ if (unlikely(rc != SQLITE_OK)) {
1612
+ error_report("Failed to bind UUID parameter to store label information");
1613
+ goto skip_store;
1614
+ }
1615
+
1616
+ rc = sqlite3_bind_int(res, 2, source_type);
1617
+ if (unlikely(rc != SQLITE_OK)) {
1618
+ error_report("Failed to bind type parameter to store label information");
1619
+ goto skip_store;
1620
+ }
1621
+
1622
+ rc = sqlite3_bind_text(res, 3, label, -1, SQLITE_STATIC);
1623
+ if (unlikely(rc != SQLITE_OK)) {
1624
+ error_report("Failed to bind label parameter to store label information");
1625
+ goto skip_store;
1626
+ }
1627
+
1628
+ rc = sqlite3_bind_text(res, 4, value, -1, SQLITE_STATIC);
1629
+ if (unlikely(rc != SQLITE_OK)) {
1630
+ error_report("Failed to bind value parameter to store label information");
1631
+ goto skip_store;
1632
+ }
1633
+
1634
+ rc = execute_insert(res);
1635
+ if (unlikely(rc != SQLITE_DONE))
1636
+ error_report("Failed to store label entry, rc = %d", rc);
1637
+
1638
+skip_store:
1639
+ if (unlikely(sqlite3_reset(res) != SQLITE_OK))
1640
+ error_report("Failed to reset the prepared statement when storing label information");
1641
+
1642
+ return rc != SQLITE_DONE;
1643
+}
1644
+
1645
#define SQL_INS_CHART_LABEL "insert or replace into chart_label " \
1646
"(chart_id, source_type, label_key, label_value, date_created) " \
1647
"values (@chart, @source, @label, @value, unixepoch());"
@@ -1622,39 +1665,35 @@ void sql_store_chart_label(uuid_t *chart_uuid, int source_type, char *label, cha
1665
}
1666
}
1667
1625
- rc = sqlite3_bind_blob(res, 1, chart_uuid, sizeof(*chart_uuid), SQLITE_STATIC);
1626
- if (unlikely(rc != SQLITE_OK)) {
1627
- error_report("Failed to bind chart_id parameter to store label information");
1628
- goto failed;
1629
- }
1668
+ sql_store_label(res, chart_uuid, source_type, label, value);
1669
1631
- rc = sqlite3_bind_int(res, 2, source_type);
1632
- if (unlikely(rc != SQLITE_OK)) {
1633
- error_report("Failed to bind type parameter to store label information");
1634
- goto failed;
1635
- }
1670
+ return;
1671
+}
1672
1637
- rc = sqlite3_bind_text(res, 3, label, -1, SQLITE_STATIC);
1638
- if (unlikely(rc != SQLITE_OK)) {
1639
- error_report("Failed to bind label parameter to store label information");
1640
- goto failed;
1641
- }
1673
+#define SQL_INS_HOST_LABEL "INSERT OR REPLACE INTO host_label " \
1674
+ "(host_id, source_type, label_key, label_value, date_created) " \
1675
+ "values (@chart, @source, @label, @value, unixepoch());"
1676
1643
- rc = sqlite3_bind_text(res, 4, value, -1, SQLITE_STATIC);
1644
- if (unlikely(rc != SQLITE_OK)) {
1645
- error_report("Failed to bind value parameter to store label information");
1646
- goto failed;
1647
- }
1677
+static void sql_store_host_label(uuid_t *host_uuid, int source_type, const char *label, const char *value)
1678
+{
1679
+ static __thread sqlite3_stmt *res = NULL;
1680
+ int rc;
1681
1649
- rc = execute_insert(res);
1650
- if (unlikely(rc != SQLITE_DONE))
1651
- error_report("Failed to store chart label entry, rc = %d", rc);
1682
+ if (unlikely(!db_meta)) {
1683
+ if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
1684
+ error_report("Database has not been initialized");
1685
+ return;
1686
+ }
1687
1653
-failed:
1654
- if (unlikely(sqlite3_reset(res) != SQLITE_OK))
1655
- error_report("Failed to reset the prepared statement when storing chart label information");
1688
+ if (unlikely(!res)) {
1689
+ rc = prepare_statement(db_meta, SQL_INS_HOST_LABEL, &res);
1690
+ if (unlikely(rc != SQLITE_OK)) {
1691
+ error_report("Failed to prepare statement store chart labels");
1692
+ return;
1693
+ }
1694
+ }
1695
1657
- return;
1696
+ (void) sql_store_label(res, host_uuid, source_type, label, value);
1697
}
1698
1699
int find_dimension_first_last_t(char *machine_guid, char *chart_id, char *dim_id,
@@ -2601,6 +2640,23 @@ void sql_store_host_system_info(uuid_t *host_id, const struct rrdhost_system_inf
2640
return;
2641
}
2642
2643
+static int save_host_label_callback(const char *name, const char *value, RRDLABEL_SRC label_source, void *data)
2644
+{
2645
+ RRDHOST *host = (RRDHOST *)data;
2646
+ sql_store_host_label(&host->host_uuid, (int)label_source & ~(RRDLABEL_FLAG_INTERNAL), name, value);
2647
+ return 0;
2648
+}
2649
+
2650
+#define SQL_DELETE_HOST_LABELS "DELETE FROM host_label WHERE host_id = @uuid;"
2651
+void sql_store_host_labels(RRDHOST *host)
2652
+{
2653
+ int rc = exec_statement_with_uuid(SQL_DELETE_HOST_LABELS, &host->host_uuid);
2654
+ if (rc != SQLITE_OK)
2655
+ error_report("Failed to remove old host labels for host %s", host->hostname);
2656
+
2657
+ rrdlabels_walkthrough_read(host->host_labels, save_host_label_callback, host);
2658
+}
2659
+
2660
// Utils
2661
int bind_text_null(sqlite3_stmt *res, int position, const char *text, bool can_be_null)
2662
{
database/sqlite/sqlite_functions.h
+1
@@ -111,4 +111,5 @@ int init_database_batch(sqlite3 *database, int rebuild, int init_type, const cha
111
void migrate_localhost(uuid_t *host_uuid);
112
extern void sql_store_host_system_info(uuid_t *host_id, const struct rrdhost_system_info *system_info);
113
extern void sql_build_host_system_info(uuid_t *host_id, struct rrdhost_system_info *system_info);
114
+void sql_store_host_labels(RRDHOST *host);
115
#endif //NETDATA_SQLITE_FUNCTIONS_H