7
#define MAX_HEALTH_SQL_SIZE 2048
8
#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))
9
10
-/* Health related SQL queries
11
- Creates a health log table in sqlite, one per host guid
12
-*/
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, transition_id blob);", guid
14
-int sql_create_health_log_table(RRDHOST *host) {
15
- int rc;
16
- char command[MAX_HEALTH_SQL_SIZE + 1];
17
-
18
- if (unlikely(!db_meta)) {
19
- if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
20
- error_report("HEALTH [%s]: Database has not been initialized", rrdhost_hostname(host));
21
- return 1;
22
- }
23
-
24
- char uuid_str[UUID_STR_LEN];
25
- uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
26
-
27
- snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_CREATE_HEALTH_LOG_TABLE(uuid_str));
28
-
29
- rc = db_execute(db_meta, command);
30
- if (unlikely(rc))
31
- error_report("HEALTH [%s]: SQLite error during creation of health log table", rrdhost_hostname(host));
32
- else {
33
- snprintfz(command, MAX_HEALTH_SQL_SIZE, "CREATE INDEX IF NOT EXISTS health_log_index_%s ON health_log_%s (unique_id); ", uuid_str, uuid_str);
34
- rc = db_execute(db_meta, command);
35
- if (unlikely(unlikely(rc)))
36
- error_report("HEALTH [%s]: SQLite error during creation of health log table index", rrdhost_hostname(host));
37
- }
38
-
39
- return rc;
40
-}
41
-
10
/* Health related SQL queries
11
Updates an entry in the table
12
*/
45
-#define SQL_UPDATE_HEALTH_LOG(guid) "UPDATE health_log_%s set updated_by_id = ?, flags = ?, exec_run_timestamp = ?, exec_code = ? where unique_id = ?;", guid
13
+#define SQL_UPDATE_HEALTH_LOG "UPDATE health_log_detail set updated_by_id = ?, flags = ?, exec_run_timestamp = ?, exec_code = ? where unique_id = ? AND alarm_id = ? and transition_id = ?;"
14
void sql_health_alarm_log_update(RRDHOST *host, ALARM_ENTRY *ae) {
15
sqlite3_stmt *res = NULL;
16
int rc;
49
- char command[MAX_HEALTH_SQL_SIZE + 1];
17
18
if (unlikely(!db_meta)) {
19
if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
21
return;
22
}
23
57
- char uuid_str[UUID_STR_LEN];
58
- uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
59
-
60
- snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_UPDATE_HEALTH_LOG(uuid_str));
61
-
62
- rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
24
+ rc = sqlite3_prepare_v2(db_meta, SQL_UPDATE_HEALTH_LOG, -1, &res, 0);
25
if (unlikely(rc != SQLITE_OK)) {
64
- sql_create_health_log_table(host);
65
- rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
66
- if (unlikely(rc != SQLITE_OK)) {
67
- error_report("HEALTH [%s]: Failed to prepare statement for SQL_INSERT_HEALTH_LOG", rrdhost_hostname(host));
68
- return;
69
- }
26
+ error_report("HEALTH [%s]: Failed to prepare statement for SQL_UPDATE_HEALTH_LOG", rrdhost_hostname(host));
27
+ return;
28
}
29
30
rc = sqlite3_bind_int64(res, 1, (sqlite3_int64) ae->updated_by_id);
57
goto failed;
58
}
59
60
+ rc = sqlite3_bind_int64(res, 6, (sqlite3_int64) ae->alarm_id);
61
+ if (unlikely(rc != SQLITE_OK)) {
62
+ error_report("Failed to bind unique_id parameter for SQL_UPDATE_HEALTH_LOG");
63
+ goto failed;
64
+ }
65
+
66
+ rc = sqlite3_bind_blob(res, 7, &ae->transition_id, sizeof(ae->transition_id), SQLITE_STATIC);
67
+ if (unlikely(rc != SQLITE_OK)) {
68
+ error_report("Failed to bind host_id for SQL_UPDATE_HEALTH_LOG.");
69
+ goto failed;
70
+ }
71
+
72
rc = execute_insert(res);
73
if (unlikely(rc != SQLITE_DONE)) {
74
error_report("HEALTH [%s]: Failed to update health log, rc = %d", rrdhost_hostname(host), rc);
82
/* Health related SQL queries
83
Inserts an entry in the table
84
*/
115
-#define SQL_INSERT_HEALTH_LOG(guid) "INSERT INTO health_log_%s(hostname, unique_id, alarm_id, alarm_event_id, " \
116
- "config_hash_id, updated_by_id, updates_id, when_key, duration, non_clear_duration, flags, " \
117
- "exec_run_timestamp, delay_up_to_timestamp, name, chart, family, exec, recipient, source, " \
118
- "units, info, exec_code, new_status, old_status, delay, new_value, old_value, last_repeat, " \
119
- "class, component, type, chart_context, transition_id) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", guid
120
-
85
+#define SQL_INSERT_HEALTH_LOG "INSERT INTO health_log (host_id, alarm_id, " \
86
+ "config_hash_id, name, chart, family, exec, recipient, units, chart_context, last_transition_id) " \
87
+ "VALUES (?,?,?,?,?,?,?,?,?,?,?) " \
88
+ "ON CONFLICT (host_id, alarm_id) DO UPDATE SET last_transition_id = excluded.last_transition_id RETURNING health_log_id; "
89
+
90
+#define SQL_INSERT_HEALTH_LOG_DETAIL "INSERT INTO health_log_detail (health_log_id, unique_id, alarm_id, alarm_event_id, " \
91
+ "updated_by_id, updates_id, when_key, duration, non_clear_duration, flags, exec_run_timestamp, delay_up_to_timestamp, " \
92
+ "info, exec_code, new_status, old_status, delay, new_value, old_value, last_repeat, transition_id, global_id) " \
93
+ "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,now_usec(0)); "
94
void sql_health_alarm_log_insert(RRDHOST *host, ALARM_ENTRY *ae) {
95
sqlite3_stmt *res = NULL;
96
int rc;
124
- char command[MAX_HEALTH_SQL_SIZE + 1];
97
+ uint64_t health_log_id = 0;
98
99
if (unlikely(!db_meta)) {
100
if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
102
return;
103
}
104
132
- char uuid_str[UUID_STR_LEN];
133
- uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
134
-
135
- snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_INSERT_HEALTH_LOG(uuid_str));
136
-
137
- rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
105
+ rc = sqlite3_prepare_v2(db_meta, SQL_INSERT_HEALTH_LOG, -1, &res, 0);
106
if (unlikely(rc != SQLITE_OK)) {
139
- sql_create_health_log_table(host);
140
- rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
141
- if (unlikely(rc != SQLITE_OK)) {
142
- error_report("HEALTH [%s]: Failed to prepare statement for SQL_INSERT_HEALTH_LOG", rrdhost_hostname(host));
143
- return;
144
- }
107
+ error_report("HEALTH [%s]: Failed to prepare statement for SQL_INSERT_HEALTH_LOG", rrdhost_hostname(host));
108
+ return;
109
}
110
147
- rc = sqlite3_bind_text(res, 1, rrdhost_hostname(host), -1, SQLITE_STATIC);
111
+ rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
112
if (unlikely(rc != SQLITE_OK)) {
149
- error_report("Failed to bind hostname parameter for SQL_INSERT_HEALTH_LOG");
113
+ error_report("Failed to bind host_id for SQL_INSERT_HEALTH_LOG.");
114
goto failed;
115
}
116
153
- rc = sqlite3_bind_int64(res, 2, (sqlite3_int64) ae->unique_id);
117
+ rc = sqlite3_bind_int64(res, 2, (sqlite3_int64) ae->alarm_id);
118
if (unlikely(rc != SQLITE_OK)) {
155
- error_report("Failed to bind unique_id parameter for SQL_INSERT_HEALTH_LOG");
119
+ error_report("Failed to bind alarm_id parameter for SQL_INSERT_HEALTH_LOG");
120
goto failed;
121
}
122
159
- rc = sqlite3_bind_int64(res, 3, (sqlite3_int64) ae->alarm_id);
123
+ rc = sqlite3_bind_blob(res, 3, &ae->config_hash_id, sizeof(ae->config_hash_id), SQLITE_STATIC);
124
if (unlikely(rc != SQLITE_OK)) {
161
- error_report("Failed to bind alarm_id parameter for SQL_INSERT_HEALTH_LOG");
125
+ error_report("Failed to bind config_hash_id parameter for SQL_INSERT_HEALTH_LOG");
126
goto failed;
127
}
128
165
- rc = sqlite3_bind_int64(res, 4, (sqlite3_int64) ae->alarm_event_id);
129
+ rc = sqlite3_bind_string_or_null(res, ae->name, 4);
130
if (unlikely(rc != SQLITE_OK)) {
167
- error_report("Failed to bind alarm_event_id parameter for SQL_INSERT_HEALTH_LOG");
131
+ error_report("Failed to bind name parameter for SQL_INSERT_HEALTH_LOG");
132
goto failed;
133
}
134
171
- rc = sqlite3_bind_blob(res, 5, &ae->config_hash_id, sizeof(ae->config_hash_id), SQLITE_STATIC);
135
+ rc = sqlite3_bind_string_or_null(res, ae->chart, 5);
136
if (unlikely(rc != SQLITE_OK)) {
173
- error_report("Failed to bind config_hash_id parameter for SQL_INSERT_HEALTH_LOG");
137
+ error_report("Failed to bind chart parameter for SQL_INSERT_HEALTH_LOG");
138
goto failed;
139
}
140
177
- rc = sqlite3_bind_int64(res, 6, (sqlite3_int64) ae->updated_by_id);
141
+ rc = sqlite3_bind_string_or_null(res, ae->family, 6);
142
if (unlikely(rc != SQLITE_OK)) {
179
- error_report("Failed to bind updated_by_id parameter for SQL_INSERT_HEALTH_LOG");
143
+ error_report("Failed to bind family parameter for SQL_INSERT_HEALTH_LOG");
144
goto failed;
145
}
146
183
- rc = sqlite3_bind_int64(res, 7, (sqlite3_int64) ae->updates_id);
147
+ rc = sqlite3_bind_string_or_null(res, ae->exec, 7);
148
if (unlikely(rc != SQLITE_OK)) {
185
- error_report("Failed to bind updates_id parameter for SQL_INSERT_HEALTH_LOG");
149
+ error_report("Failed to bind exec parameter for SQL_INSERT_HEALTH_LOG");
150
goto failed;
151
}
152
189
- rc = sqlite3_bind_int64(res, 8, (sqlite3_int64) ae->when);
153
+ rc = sqlite3_bind_string_or_null(res, ae->recipient, 8);
154
if (unlikely(rc != SQLITE_OK)) {
191
- error_report("Failed to bind when parameter for SQL_INSERT_HEALTH_LOG");
155
+ error_report("Failed to bind recipient parameter for SQL_INSERT_HEALTH_LOG");
156
goto failed;
157
}
158
195
- rc = sqlite3_bind_int64(res, 9, (sqlite3_int64) ae->duration);
159
+ rc = sqlite3_bind_string_or_null(res, ae->units, 9);
160
if (unlikely(rc != SQLITE_OK)) {
197
- error_report("Failed to bind duration parameter for SQL_INSERT_HEALTH_LOG");
161
+ error_report("Failed to bind host_id parameter to store node instance information");
162
goto failed;
163
}
164
201
- rc = sqlite3_bind_int64(res, 10, (sqlite3_int64) ae->non_clear_duration);
165
+ rc = sqlite3_bind_string_or_null(res, ae->chart_context, 10);
166
if (unlikely(rc != SQLITE_OK)) {
203
- error_report("Failed to bind non_clear_duration parameter for SQL_INSERT_HEALTH_LOG");
167
+ error_report("Failed to bind chart_context parameter for SQL_INSERT_HEALTH_LOG");
168
goto failed;
169
}
170
207
- rc = sqlite3_bind_int64(res, 11, (sqlite3_int64) ae->flags);
171
+ rc = sqlite3_bind_blob(res, 11, &ae->transition_id, sizeof(ae->transition_id), SQLITE_STATIC);
172
if (unlikely(rc != SQLITE_OK)) {
209
- error_report("Failed to bind flags parameter for SQL_INSERT_HEALTH_LOG");
173
+ error_report("Failed to bind transition_id parameter for SQL_INSERT_HEALTH_LOG");
174
goto failed;
175
}
176
213
- rc = sqlite3_bind_int64(res, 12, (sqlite3_int64) ae->exec_run_timestamp);
214
- if (unlikely(rc != SQLITE_OK)) {
215
- error_report("Failed to bind exec_run_timestamp parameter for SQL_INSERT_HEALTH_LOG");
177
+ rc = sqlite3_step_monitored(res);
178
+ if (likely(rc == SQLITE_ROW))
179
+ health_log_id = (size_t) sqlite3_column_int64(res, 0);
180
+ else {
181
+ error_report("HEALTH [%s]: Failed to execute SQL_INSERT_HEALTH_LOG, rc = %d", rrdhost_hostname(host), rc);
182
goto failed;
183
}
184
219
- rc = sqlite3_bind_int64(res, 13, (sqlite3_int64) ae->delay_up_to_timestamp);
185
+ rc = sqlite3_finalize(res);
186
+ if (unlikely(rc != SQLITE_OK))
187
+ error_report("HEALTH [%s]: Failed to finalize the prepared statement for inserting to health log.", rrdhost_hostname(host));
188
+
189
+ rc = sqlite3_prepare_v2(db_meta, SQL_INSERT_HEALTH_LOG_DETAIL, -1, &res, 0);
190
if (unlikely(rc != SQLITE_OK)) {
221
- error_report("Failed to bind delay_up_to_timestamp parameter for SQL_INSERT_HEALTH_LOG");
191
+ error_report("HEALTH [%s]: Failed to prepare statement for SQL_INSERT_HEALTH_LOG_DETAIL", rrdhost_hostname(host));
192
+ return;
193
+ }
194
+
195
+ rc = sqlite3_bind_int64(res, 1, (sqlite3_int64) health_log_id);
196
+ if (unlikely(rc != SQLITE_OK)) {
197
+ error_report("Failed to bind unique_id parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
198
goto failed;
199
}
200
225
- rc = sqlite3_bind_string_or_null(res, ae->name, 14);
201
+ rc = sqlite3_bind_int64(res, 2, (sqlite3_int64) ae->unique_id);
202
if (unlikely(rc != SQLITE_OK)) {
227
- error_report("Failed to bind name parameter for SQL_INSERT_HEALTH_LOG");
203
+ error_report("Failed to bind unique_id parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
204
goto failed;
205
}
206
231
- rc = sqlite3_bind_string_or_null(res, ae->chart, 15);
207
+ rc = sqlite3_bind_int64(res, 3, (sqlite3_int64) ae->alarm_id);
208
if (unlikely(rc != SQLITE_OK)) {
233
- error_report("Failed to bind chart parameter for SQL_INSERT_HEALTH_LOG");
209
+ error_report("Failed to bind unique_id parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
210
goto failed;
211
}
212
237
- rc = sqlite3_bind_string_or_null(res, ae->family, 16);
213
+ rc = sqlite3_bind_int64(res, 4, (sqlite3_int64) ae->alarm_event_id);
214
if (unlikely(rc != SQLITE_OK)) {
239
- error_report("Failed to bind family parameter for SQL_INSERT_HEALTH_LOG");
215
+ error_report("Failed to bind alarm_event_id parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
216
goto failed;
217
}
218
243
- rc = sqlite3_bind_string_or_null(res, ae->exec, 17);
219
+ rc = sqlite3_bind_int64(res, 5, (sqlite3_int64) ae->updated_by_id);
220
if (unlikely(rc != SQLITE_OK)) {
245
- error_report("Failed to bind exec parameter for SQL_INSERT_HEALTH_LOG");
221
+ error_report("Failed to bind updated_by_id parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
222
goto failed;
223
}
224
249
- rc = sqlite3_bind_string_or_null(res, ae->recipient, 18);
225
+ rc = sqlite3_bind_int64(res, 6, (sqlite3_int64) ae->updates_id);
226
if (unlikely(rc != SQLITE_OK)) {
251
- error_report("Failed to bind recipient parameter for SQL_INSERT_HEALTH_LOG");
227
+ error_report("Failed to bind updates_id parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
228
goto failed;
229
}
230
255
- rc = sqlite3_bind_string_or_null(res, ae->source, 19);
231
+ rc = sqlite3_bind_int64(res, 7, (sqlite3_int64) ae->when);
232
if (unlikely(rc != SQLITE_OK)) {
257
- error_report("Failed to bind source parameter for SQL_INSERT_HEALTH_LOG");
233
+ error_report("Failed to bind when parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
234
goto failed;
235
}
236
261
- rc = sqlite3_bind_string_or_null(res, ae->units, 20);
237
+ rc = sqlite3_bind_int64(res, 8, (sqlite3_int64) ae->duration);
238
if (unlikely(rc != SQLITE_OK)) {
263
- error_report("Failed to bind host_id parameter to store node instance information");
239
+ error_report("Failed to bind duration parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
240
goto failed;
241
}
242
267
- rc = sqlite3_bind_string_or_null(res, ae->info, 21);
243
+ rc = sqlite3_bind_int64(res, 9, (sqlite3_int64) ae->non_clear_duration);
244
if (unlikely(rc != SQLITE_OK)) {
269
- error_report("Failed to bind info parameter for SQL_INSERT_HEALTH_LOG");
245
+ error_report("Failed to bind non_clear_duration parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
246
goto failed;
247
}
248
273
- rc = sqlite3_bind_int(res, 22, ae->exec_code);
249
+ rc = sqlite3_bind_int64(res, 10, (sqlite3_int64) ae->flags);
250
if (unlikely(rc != SQLITE_OK)) {
275
- error_report("Failed to bind exec_code parameter for SQL_INSERT_HEALTH_LOG");
251
+ error_report("Failed to bind flags parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
252
goto failed;
253
}
254
279
- rc = sqlite3_bind_int(res, 23, ae->new_status);
255
+ rc = sqlite3_bind_int64(res, 11, (sqlite3_int64) ae->exec_run_timestamp);
256
if (unlikely(rc != SQLITE_OK)) {
281
- error_report("Failed to bind new_status parameter for SQL_INSERT_HEALTH_LOG");
257
+ error_report("Failed to bind exec_run_timestamp parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
258
goto failed;
259
}
260
285
- rc = sqlite3_bind_int(res, 24, ae->old_status);
261
+ rc = sqlite3_bind_int64(res, 12, (sqlite3_int64) ae->delay_up_to_timestamp);
262
if (unlikely(rc != SQLITE_OK)) {
287
- error_report("Failed to bind old_status parameter for SQL_INSERT_HEALTH_LOG");
263
+ error_report("Failed to bind delay_up_to_timestamp parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
264
goto failed;
265
}
266
291
- rc = sqlite3_bind_int(res, 25, ae->delay);
267
+ rc = sqlite3_bind_string_or_null(res, ae->info, 13);
268
if (unlikely(rc != SQLITE_OK)) {
293
- error_report("Failed to bind delay parameter for SQL_INSERT_HEALTH_LOG");
269
+ error_report("Failed to bind info parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
270
goto failed;
271
}
272
297
- rc = sqlite3_bind_double(res, 26, ae->new_value);
273
+ rc = sqlite3_bind_int(res, 14, ae->exec_code);
274
if (unlikely(rc != SQLITE_OK)) {
299
- error_report("Failed to bind new_value parameter for SQL_INSERT_HEALTH_LOG");
275
+ error_report("Failed to bind exec_code parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
276
goto failed;
277
}
278
303
- rc = sqlite3_bind_double(res, 27, ae->old_value);
279
+ rc = sqlite3_bind_int(res, 15, ae->new_status);
280
if (unlikely(rc != SQLITE_OK)) {
305
- error_report("Failed to bind old_value parameter for SQL_INSERT_HEALTH_LOG");
281
+ error_report("Failed to bind new_status parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
282
goto failed;
283
}
284
309
- rc = sqlite3_bind_int64(res, 28, (sqlite3_int64) ae->last_repeat);
285
+ rc = sqlite3_bind_int(res, 16, ae->old_status);
286
if (unlikely(rc != SQLITE_OK)) {
311
- error_report("Failed to bind last_repeat parameter for SQL_INSERT_HEALTH_LOG");
287
+ error_report("Failed to bind old_status parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
288
goto failed;
289
}
290
315
- rc = sqlite3_bind_string_or_null(res, ae->classification, 29);
291
+ rc = sqlite3_bind_int(res, 17, ae->delay);
292
if (unlikely(rc != SQLITE_OK)) {
317
- error_report("Failed to bind classification parameter for SQL_INSERT_HEALTH_LOG");
293
+ error_report("Failed to bind delay parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
294
goto failed;
295
}
296
321
- rc = sqlite3_bind_string_or_null(res, ae->component, 30);
297
+ rc = sqlite3_bind_double(res, 18, ae->new_value);
298
if (unlikely(rc != SQLITE_OK)) {
323
- error_report("Failed to bind component parameter for SQL_INSERT_HEALTH_LOG");
299
+ error_report("Failed to bind new_value parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
300
goto failed;
301
}
302
327
- rc = sqlite3_bind_string_or_null(res, ae->type, 31);
303
+ rc = sqlite3_bind_double(res, 19, ae->old_value);
304
if (unlikely(rc != SQLITE_OK)) {
329
- error_report("Failed to bind type parameter for SQL_INSERT_HEALTH_LOG");
305
+ error_report("Failed to bind old_value parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
306
goto failed;
307
}
308
333
- rc = sqlite3_bind_string_or_null(res, ae->chart_context, 32);
309
+ rc = sqlite3_bind_int64(res, 20, (sqlite3_int64) ae->last_repeat);
310
if (unlikely(rc != SQLITE_OK)) {
335
- error_report("Failed to bind chart_context parameter for SQL_INSERT_HEALTH_LOG");
311
+ error_report("Failed to bind last_repeat parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
312
goto failed;
313
}
314
339
- rc = sqlite3_bind_blob(res, 33, &ae->transition_id, sizeof(ae->transition_id), SQLITE_STATIC);
315
+ rc = sqlite3_bind_blob(res, 21, &ae->transition_id, sizeof(ae->transition_id), SQLITE_STATIC);
316
if (unlikely(rc != SQLITE_OK)) {
341
- error_report("Failed to bind transition_id parameter for SQL_INSERT_HEALTH_LOG");
317
+ error_report("Failed to bind transition_id parameter for SQL_INSERT_HEALTH_LOG_DETAIL");
318
goto failed;
319
}
320
321
rc = execute_insert(res);
322
if (unlikely(rc != SQLITE_DONE)) {
347
- error_report("HEALTH [%s]: Failed to execute SQL_INSERT_HEALTH_LOG, rc = %d", rrdhost_hostname(host), rc);
323
+ error_report("HEALTH [%s]: Failed to execute SQL_INSERT_HEALTH_LOG_DETAIL, rc = %d", rrdhost_hostname(host), rc);
324
goto failed;
325
}
326
349
/* Health related SQL queries
350
Get a count of rows from health log table
351
*/
376
-#define SQL_COUNT_HEALTH_LOG(guid) "SELECT count(1) FROM health_log_%s;", guid
352
+#define SQL_COUNT_HEALTH_LOG_DETAIL "SELECT count(1) FROM health_log_detail hld, health_log hl where hl.host_id = @host_id and hl.health_log_id = hld.health_log_id;"
353
void sql_health_alarm_log_count(RRDHOST *host) {
354
sqlite3_stmt *res = NULL;
355
int rc;
380
- char command[MAX_HEALTH_SQL_SIZE + 1];
356
357
if (unlikely(!db_meta)) {
358
if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
360
return;
361
}
362
388
- char uuid_str[UUID_STR_LEN];
389
- uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
390
-
391
- snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_COUNT_HEALTH_LOG(uuid_str));
392
-
393
- rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
363
+ rc = sqlite3_prepare_v2(db_meta, SQL_COUNT_HEALTH_LOG_DETAIL, -1, &res, 0);
364
if (unlikely(rc != SQLITE_OK)) {
365
error_report("Failed to prepare statement to count health log entries from db");
366
return;
367
}
368
369
+ rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
370
+ if (unlikely(rc != SQLITE_OK)) {
371
+ error_report("Failed to bind host_id for SQL_COUNT_HEALTH_LOG.");
372
+ sqlite3_finalize(res);
373
+ return;
374
+ }
375
+
376
rc = sqlite3_step_monitored(res);
377
if (likely(rc == SQLITE_ROW))
378
host->health.health_log_entries_written = (size_t) sqlite3_column_int64(res, 0);
381
if (unlikely(rc != SQLITE_OK))
382
error_report("Failed to finalize the prepared statement to count health log entries from db");
383
407
- info("HEALTH [%s]: Table health_log_%s, contains %lu entries.", rrdhost_hostname(host), uuid_str, (unsigned long int) host->health.health_log_entries_written);
384
+ info("HEALTH [%s]: Table health_log_detail contains %lu entries.", rrdhost_hostname(host), (unsigned long int) host->health.health_log_entries_written);
385
}
386
387
/* Health related SQL queries
411
- Cleans up the health_log table on a non-claimed host
388
+ Cleans up the health_log_detail table on a non-claimed host
389
*/
413
-#define SQL_CLEANUP_HEALTH_LOG_NOT_CLAIMED(guid,limit) "DELETE FROM health_log_%s ORDER BY unique_id ASC LIMIT %lu;", guid, limit
390
+#define SQL_CLEANUP_HEALTH_LOG_DETAIL_NOT_CLAIMED(limit) "DELETE FROM health_log_detail where health_log_id in (select health_log_id from health_log where host_id = @host_id) ORDER BY unique_id ASC LIMIT %lu;", limit
391
void sql_health_alarm_log_cleanup_not_claimed(RRDHOST *host, size_t rotate_every) {
392
sqlite3_stmt *res = NULL;
393
int rc;
402
char uuid_str[UUID_STR_LEN];
403
uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
404
428
- snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_CLEANUP_HEALTH_LOG_NOT_CLAIMED(uuid_str, (unsigned long int) (host->health.health_log_entries_written - rotate_every)));
405
+ snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_CLEANUP_HEALTH_LOG_DETAIL_NOT_CLAIMED((unsigned long int) (host->health.health_log_entries_written - rotate_every)));
406
407
rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
408
if (unlikely(rc != SQLITE_OK)) {
432
- error_report("Failed to prepare statement to cleanup health log table");
409
+ error_report("Failed to prepare statement to cleanup health log detail table (un-claimed)");
410
+ return;
411
+ }
412
+
413
+ rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
414
+ if (unlikely(rc != SQLITE_OK)) {
415
+ error_report("Failed to bind host_id for SQL_CLEANUP_HEALTH_LOG_NOT_CLAIMED.");
416
+ sqlite3_finalize(res);
417
return;
418
}
419
423
424
rc = sqlite3_finalize(res);
425
if (unlikely(rc != SQLITE_OK))
442
- error_report("Failed to finalize the prepared statement to cleanup health log table");
426
+ error_report("Failed to finalize the prepared statement to cleanup health log detail table (un-claimed)");
427
428
host->health.health_log_entries_written = rotate_every;
429
434
}
435
436
/* Health related SQL queries
453
- Cleans up the health_log table on a claimed host
437
+ Cleans up the health_log_detail table on a claimed host
438
*/
455
-#define SQL_CLEANUP_HEALTH_LOG_CLAIMED(guid, guid2, guid3, limit) "DELETE from health_log_%s WHERE unique_id NOT IN (SELECT filtered_alert_unique_id FROM aclk_alert_%s) AND unique_id IN (SELECT unique_id FROM health_log_%s ORDER BY unique_id asc LIMIT %lu);", guid, guid2, guid3, limit
439
+#define SQL_CLEANUP_HEALTH_LOG_DETAIL_CLAIMED(guid, limit) "DELETE from health_log_detail WHERE unique_id NOT IN (SELECT filtered_alert_unique_id FROM aclk_alert_%s) AND unique_id IN (SELECT hld.unique_id FROM health_log hl, health_log_detail hld WHERE hl.host_id = ?1 AND hl.health_log_id = hld.health_log_id) and health_log_id in (SELECT health_log_id FROM health_log WHERE host_id = ?2) ORDER BY unique_id asc LIMIT %lu;", guid, limit
440
void sql_health_alarm_log_cleanup_claimed(RRDHOST *host, size_t rotate_every) {
441
sqlite3_stmt *res = NULL;
442
int rc;
457
return;
458
}
459
476
- snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_CLEANUP_HEALTH_LOG_CLAIMED(uuid_str, uuid_str, uuid_str, (unsigned long int) (host->health.health_log_entries_written - rotate_every)));
460
+ snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_CLEANUP_HEALTH_LOG_DETAIL_CLAIMED(uuid_str, (unsigned long int) (host->health.health_log_entries_written - rotate_every)));
461
462
rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
463
if (unlikely(rc != SQLITE_OK)) {
480
- error_report("Failed to prepare statement to cleanup health log table");
464
+ error_report("Failed to prepare statement to cleanup health log detail table (claimed)");
465
+ return;
466
+ }
467
+
468
+ rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
469
+ if (unlikely(rc != SQLITE_OK)) {
470
+ error_report("Failed to bind first host_id for SQL_CLEANUP_HEALTH_LOG_CLAIMED.");
471
+ sqlite3_finalize(res);
472
+ return;
473
+ }
474
+
475
+ rc = sqlite3_bind_blob(res, 2, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
476
+ if (unlikely(rc != SQLITE_OK)) {
477
+ error_report("Failed to bind second host_id for SQL_CLEANUP_HEALTH_LOG_CLAIMED.");
478
+ sqlite3_finalize(res);
479
return;
480
}
481
485
486
rc = sqlite3_finalize(res);
487
if (unlikely(rc != SQLITE_OK))
490
- error_report("Failed to finalize the prepared statement to cleanup health log table");
488
+ error_report("Failed to finalize the prepared statement to cleanup health log detail table (claimed)");
489
490
sql_health_alarm_log_count(host);
491
513
sql_health_alarm_log_cleanup_claimed(host, rotate_every);
514
}
515
518
-#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, " \
519
-"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) " \
520
-"select hostname, ?1, ?2, ?3, config_hash_id, 0, ?4, unixepoch(), 0, 0, flags, exec_run_timestamp, " \
521
-"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 " \
522
-"from health_log_%s where unique_id = ?6", guid, guid2
523
-#define SQL_INJECT_REMOVED_UPDATE(guid) "update health_log_%s set flags = flags | ?1, updated_by_id = ?2 where unique_id = ?3; ", guid
524
-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)
516
+#define SQL_INJECT_REMOVED "insert into health_log_detail (health_log_id, unique_id, alarm_id, alarm_event_id, updated_by_id, updates_id, when_key, duration, non_clear_duration, flags, exec_run_timestamp, delay_up_to_timestamp, info, exec_code, new_status, old_status, delay, new_value, old_value, last_repeat, transition_id, global_id) select health_log_id, ?1, ?2, ?3, 0, ?4, unixepoch(), 0, 0, flags, exec_run_timestamp, unixepoch(), info, exec_code, -2, new_status, delay, NULL, new_value, 0, ?5, now_usec(0) from health_log_detail where unique_id = ?6 and transition_id = ?7;"
517
+#define SQL_INJECT_REMOVED_UPDATE_DETAIL "update health_log_detail set flags = flags | ?1, updated_by_id = ?2 where unique_id = ?3 and transition_id = ?4;"
518
+#define SQL_INJECT_REMOVED_UPDATE_LOG "update health_log set last_transition_id = ?1 where alarm_id = ?2 and last_transition_id = ?3 and host_id = ?4;"
519
+void sql_inject_removed_status(RRDHOST *host, uint32_t alarm_id, uint32_t alarm_event_id, uint32_t unique_id, uint32_t max_unique_id, uuid_t *prev_transition_id)
520
{
521
int rc;
527
- char command[MAX_HEALTH_SQL_SIZE + 1];
522
523
if (!alarm_id || !alarm_event_id || !unique_id || !max_unique_id)
524
return;
525
526
sqlite3_stmt *res = NULL;
527
534
- snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_INJECT_REMOVED(uuid_str, uuid_str));
535
- rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
528
+ rc = sqlite3_prepare_v2(db_meta, SQL_INJECT_REMOVED, -1, &res, 0);
529
if (rc != SQLITE_OK) {
530
error_report("Failed to prepare statement when trying to inject removed event");
531
return;
559
uuid_generate_random(transition_id);
560
rc = sqlite3_bind_blob(res, 5, &transition_id, sizeof(transition_id), SQLITE_STATIC);
561
if (unlikely(rc != SQLITE_OK)) {
569
- error_report("Failed to bind config_hash_id parameter for SQL_INSERT_HEALTH_LOG");
562
+ error_report("Failed to bind config_hash_id parameter for SQL_INJECT_REMOVED");
563
goto failed;
564
}
565
569
goto failed;
570
}
571
572
+ rc = sqlite3_bind_blob(res, 7, prev_transition_id, sizeof(*prev_transition_id), SQLITE_STATIC);
573
+ if (unlikely(rc != SQLITE_OK)) {
574
+ error_report("Failed to bind host_id parameter for SQL_INJECT_REMOVED.");
575
+ goto failed;
576
+ }
577
+
578
rc = execute_insert(res);
579
if (unlikely(rc != SQLITE_DONE)) {
580
error_report("HEALTH [N/A]: Failed to execute SQL_INJECT_REMOVED, rc = %d", rc);
584
if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
585
error_report("HEALTH [N/A]: Failed to finalize the prepared statement for injecting removed event.");
586
588
- //update the old entry
589
- snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_INJECT_REMOVED_UPDATE(uuid_str));
590
- rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
587
+ //update the old entry in health_log_detail
588
+ rc = sqlite3_prepare_v2(db_meta, SQL_INJECT_REMOVED_UPDATE_DETAIL, -1, &res, 0);
589
if (rc != SQLITE_OK) {
592
- error_report("Failed to prepare statement when trying to update during inject removed event");
590
+ error_report("Failed to prepare statement when trying to update health_log_detail during inject removed event");
591
return;
592
}
593
594
rc = sqlite3_bind_int64(res, 1, (sqlite3_int64) HEALTH_ENTRY_FLAG_UPDATED);
595
if (unlikely(rc != SQLITE_OK)) {
598
- error_report("Failed to bind flags parameter for SQL_INJECT_REMOVED (update)");
596
+ error_report("Failed to bind flags parameter for SQL_INJECT_REMOVED_UPDATE_DETAIL");
597
goto failed;
598
}
599
600
rc = sqlite3_bind_int64(res, 2, (sqlite3_int64) max_unique_id);
601
if (unlikely(rc != SQLITE_OK)) {
604
- error_report("Failed to bind max_unique_id parameter for SQL_INJECT_REMOVED (update)");
602
+ error_report("Failed to bind max_unique_id parameter for SQL_INJECT_REMOVED_UPDATE_DETAIL");
603
goto failed;
604
}
605
606
rc = sqlite3_bind_int64(res, 3, (sqlite3_int64) unique_id);
607
if (unlikely(rc != SQLITE_OK)) {
610
- error_report("Failed to bind unique_id parameter for SQL_INJECT_REMOVED (update)");
608
+ error_report("Failed to bind unique_id parameter for SQL_INJECT_REMOVED_UPDATE_DETAIL");
609
+ goto failed;
610
+ }
611
+
612
+ rc = sqlite3_bind_blob(res, 4, prev_transition_id, sizeof(*prev_transition_id), SQLITE_STATIC);
613
+ if (unlikely(rc != SQLITE_OK)) {
614
+ error_report("Failed to bind host_id parameter for SQL_INJECT_REMOVED_UPDATE_DETAIL");
615
+ goto failed;
616
+ }
617
+
618
+ rc = execute_insert(res);
619
+ if (unlikely(rc != SQLITE_DONE)) {
620
+ error_report("HEALTH [N/A]: Failed to execute SQL_INJECT_REMOVED_UPDATE_DETAIL, rc = %d", rc);
621
+ goto failed;
622
+ }
623
+
624
+ //update the health_log_table
625
+ rc = sqlite3_prepare_v2(db_meta, SQL_INJECT_REMOVED_UPDATE_LOG, -1, &res, 0);
626
+ if (rc != SQLITE_OK) {
627
+ error_report("Failed to prepare statement when trying to update health_log during inject removed event");
628
+ return;
629
+ }
630
+
631
+ rc = sqlite3_bind_blob(res, 1, &transition_id, sizeof(transition_id), SQLITE_STATIC);
632
+ if (unlikely(rc != SQLITE_OK)) {
633
+ error_report("Failed to bind host_id parameter for SQL_INJECT_REMOVED_UPDATE_LOG");
634
+ goto failed;
635
+ }
636
+
637
+ rc = sqlite3_bind_int64(res, 2, (sqlite3_int64) alarm_id);
638
+ if (unlikely(rc != SQLITE_OK)) {
639
+ error_report("Failed to bind unique_id parameter for SQL_INJECT_REMOVED_UPDATE_DETAIL");
640
+ goto failed;
641
+ }
642
+
643
+ rc = sqlite3_bind_blob(res, 3, prev_transition_id, sizeof(*prev_transition_id), SQLITE_STATIC);
644
+ if (unlikely(rc != SQLITE_OK)) {
645
+ error_report("Failed to bind host_id parameter for SQL_INJECT_REMOVED_UPDATE_LOG");
646
+ goto failed;
647
+ }
648
+
649
+ rc = sqlite3_bind_blob(res, 4, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
650
+ if (unlikely(rc != SQLITE_OK)) {
651
+ error_report("Failed to bind host_id parameter for SQL_INJECT_REMOVED_UPDATE_DETAIL");
652
goto failed;
653
}
654
655
rc = execute_insert(res);
656
if (unlikely(rc != SQLITE_DONE)) {
616
- error_report("HEALTH [N/A]: Failed to execute SQL_INJECT_REMOVED_UPDATE, rc = %d", rc);
657
+ error_report("HEALTH [N/A]: Failed to execute SQL_INJECT_REMOVED_UPDATE_DETAIL, rc = %d", rc);
658
goto failed;
659
}
660
663
error_report("HEALTH [N/A]: Failed to finalize the prepared statement for injecting removed event.");
664
}
665
625
-#define SQL_SELECT_MAX_UNIQUE_ID(guid) "SELECT MAX(unique_id) from health_log_%s", guid
626
-uint32_t sql_get_max_unique_id (char *uuid_str)
666
+#define SQL_SELECT_MAX_UNIQUE_ID "SELECT MAX(hld.unique_id) from health_log_detail hld, health_log hl where hl.host_id = @host_id; and hl.health_log_id = hld.health_log_id"
667
+uint32_t sql_get_max_unique_id (RRDHOST *host)
668
{
669
int rc;
629
- char command[MAX_HEALTH_SQL_SIZE + 1];
670
uint32_t max_unique_id = 0;
671
672
sqlite3_stmt *res = NULL;
673
634
- snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_SELECT_MAX_UNIQUE_ID(uuid_str));
635
- rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
674
+ rc = sqlite3_prepare_v2(db_meta, SQL_SELECT_MAX_UNIQUE_ID, -1, &res, 0);
675
if (rc != SQLITE_OK) {
676
error_report("Failed to prepare statement when trying to get max unique id");
677
return 0;
678
}
679
680
+ rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
681
+ if (unlikely(rc != SQLITE_OK)) {
682
+ error_report("Failed to bind host_id parameter for SQL_SELECT_MAX_UNIQUE_ID.");
683
+ sqlite3_finalize(res);
684
+ return 0;
685
+ }
686
+
687
while (sqlite3_step_monitored(res) == SQLITE_ROW) {
688
max_unique_id = (uint32_t) sqlite3_column_int64(res, 0);
689
}
695
return max_unique_id;
696
}
697
652
-#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
653
-void sql_check_removed_alerts_state(char *uuid_str)
698
+#define SQL_SELECT_LAST_STATUSES "SELECT hld.new_status, hld.unique_id, hld.alarm_id, hld.alarm_event_id, hld.transition_id from health_log hl, health_log_detail hld where hl.host_id = @host_id and hl.last_transition_id = hld.transition_id;"
699
+void sql_check_removed_alerts_state(RRDHOST *host)
700
{
701
int rc;
656
- char command[MAX_HEALTH_SQL_SIZE + 1];
702
uint32_t max_unique_id = 0;
658
-
703
sqlite3_stmt *res = NULL;
704
+ uuid_t transition_id;
705
661
- snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_SELECT_LAST_STATUSES(uuid_str));
662
- rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
706
+ rc = sqlite3_prepare_v2(db_meta, SQL_SELECT_LAST_STATUSES, -1, &res, 0);
707
if (rc != SQLITE_OK) {
708
error_report("Failed to prepare statement when trying to check removed statuses");
709
return;
710
}
711
668
- while (sqlite3_step_monitored(res) == SQLITE_ROW) {
669
- uint32_t alarm_id, alarm_event_id, unique_id;
670
- RRDCALC_STATUS status;
671
-
672
- status = (RRDCALC_STATUS) sqlite3_column_int(res, 0);
673
- unique_id = (uint32_t) sqlite3_column_int64(res, 1);
674
- alarm_id = (uint32_t) sqlite3_column_int64(res, 2);
675
- alarm_event_id = (uint32_t) sqlite3_column_int64(res, 3);
676
- if (unlikely(status != RRDCALC_STATUS_REMOVED)) {
677
- if (unlikely(!max_unique_id))
678
- max_unique_id = sql_get_max_unique_id (uuid_str);
679
- sql_inject_removed_status (uuid_str, alarm_id, alarm_event_id, unique_id, ++max_unique_id);
680
- }
681
- }
712
+ rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
713
+ if (unlikely(rc != SQLITE_OK)) {
714
+ error_report("Failed to bind host_id parameter for SQL_SELECT_LAST_STATUSES.");
715
+ sqlite3_finalize(res);
716
+ return;
717
+ }
718
+
719
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
720
+ uint32_t alarm_id, alarm_event_id, unique_id;
721
+ RRDCALC_STATUS status;
722
+
723
+ status = (RRDCALC_STATUS) sqlite3_column_int(res, 0);
724
+ unique_id = (uint32_t) sqlite3_column_int64(res, 1);
725
+ alarm_id = (uint32_t) sqlite3_column_int64(res, 2);
726
+ alarm_event_id = (uint32_t) sqlite3_column_int64(res, 3);
727
+ uuid_copy(transition_id, *((uuid_t *) sqlite3_column_blob(res, 4)));
728
+ if (unlikely(status != RRDCALC_STATUS_REMOVED)) {
729
+ if (unlikely(!max_unique_id))
730
+ max_unique_id = sql_get_max_unique_id (host);
731
+ sql_inject_removed_status (host, alarm_id, alarm_event_id, unique_id, ++max_unique_id, &transition_id);
732
+ }
733
+ }
734
735
rc = sqlite3_finalize(res);
736
if (unlikely(rc != SQLITE_OK))
740
/* Health related SQL queries
741
Load from the health log table
742
*/
691
-#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
743
+#define SQL_LOAD_HEALTH_LOG "SELECT hld.unique_id, hld.alarm_id, hld.alarm_event_id, hl.config_hash_id, hld.updated_by_id, hld.updates_id, hld.when_key, hld.duration, hld.non_clear_duration, hld.flags, hld.exec_run_timestamp, hld.delay_up_to_timestamp, hl.name, hl.chart, hl.family, hl.exec, hl.recipient, ah.source, hl.units, hld.info, hld.exec_code, hld.new_status, hld.old_status, hld.delay, hld.new_value, hld.old_value, hld.last_repeat, ah.class, ah.component, ah.type, hl.chart_context, hld.transition_id FROM health_log hl, alert_hash ah, health_log_detail hld where hl.config_hash_id = ah.hash_id and hl.host_id = @host_id and hl.last_transition_id = hld.transition_id;"
744
void sql_health_alarm_log_load(RRDHOST *host) {
745
sqlite3_stmt *res = NULL;
746
int ret;
747
ssize_t errored = 0, loaded = 0;
696
- char command[MAX_HEALTH_SQL_SIZE + 1];
748
749
host->health.health_log_entries_written = 0;
750
754
return;
755
}
756
706
- char uuid_str[UUID_STR_LEN];
707
- uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
708
-
709
- sql_check_removed_alerts_state(uuid_str);
710
-
711
- snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_LOAD_HEALTH_LOG(uuid_str));
757
+ sql_check_removed_alerts_state(host);
758
713
- ret = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
759
+ ret = sqlite3_prepare_v2(db_meta, SQL_LOAD_HEALTH_LOG, -1, &res, 0);
760
if (unlikely(ret != SQLITE_OK)) {
761
error_report("HEALTH [%s]: Failed to prepare sql statement to load health log.", rrdhost_hostname(host));
762
return;
763
}
764
765
+ ret = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
766
+ if (unlikely(ret != SQLITE_OK)) {
767
+ error_report("Failed to bind host_id parameter for SQL_LOAD_HEALTH_LOG.");
768
+ sqlite3_finalize(res);
769
+ return;
770
+ }
771
+
772
DICTIONARY *all_rrdcalcs = dictionary_create(
773
DICT_OPTION_NAME_LINK_DONT_CLONE | DICT_OPTION_VALUE_LINK_DONT_CLONE | DICT_OPTION_DONT_OVERWRITE_VALUE);
774
RRDCALC *rc;
783
ALARM_ENTRY *ae = NULL;
784
785
// check that we have valid ids
733
- uint32_t unique_id = (uint32_t) sqlite3_column_int64(res, 1);
786
+ uint32_t unique_id = (uint32_t) sqlite3_column_int64(res, 0);
787
if(!unique_id) {
788
error_report("HEALTH [%s]: Got invalid unique id. Ignoring it.", rrdhost_hostname(host));
789
errored++;
790
continue;
791
}
792
740
- uint32_t alarm_id = (uint32_t) sqlite3_column_int64(res, 2);
793
+ uint32_t alarm_id = (uint32_t) sqlite3_column_int64(res, 1);
794
if(!alarm_id) {
795
error_report("HEALTH [%s]: Got invalid alarm id. Ignoring it.", rrdhost_hostname(host));
796
errored++;
798
}
799
800
//need name, chart and family
748
- if (sqlite3_column_type(res, 13) == SQLITE_NULL) {
801
+ if (sqlite3_column_type(res, 12) == SQLITE_NULL) {
802
error_report("HEALTH [%s]: Got null name field. Ignoring it.", rrdhost_hostname(host));
803
errored++;
804
continue;
805
}
806
754
- if (sqlite3_column_type(res, 14) == SQLITE_NULL) {
807
+ if (sqlite3_column_type(res, 13) == SQLITE_NULL) {
808
error_report("HEALTH [%s]: Got null chart field. Ignoring it.", rrdhost_hostname(host));
809
errored++;
810
continue;
811
}
812
760
- if (sqlite3_column_type(res, 15) == SQLITE_NULL) {
813
+ if (sqlite3_column_type(res, 14) == SQLITE_NULL) {
814
error_report("HEALTH [%s]: Got null family field. Ignoring it.", rrdhost_hostname(host));
815
errored++;
816
continue;
817
}
818
819
// Check if we got last_repeat field
767
- time_t last_repeat = (time_t)sqlite3_column_int64(res, 27);
820
+ time_t last_repeat = (time_t)sqlite3_column_int64(res, 26);
821
769
- rc = dictionary_get(all_rrdcalcs, (char *) sqlite3_column_text(res, 14));
822
+ rc = dictionary_get(all_rrdcalcs, (char *) sqlite3_column_text(res, 13));
823
if(unlikely(rc)) {
824
if (rrdcalc_isrepeating(rc)) {
825
rc->last_repeat = last_repeat;
835
ae->unique_id = unique_id;
836
ae->alarm_id = alarm_id;
837
785
- if (sqlite3_column_type(res, 4) != SQLITE_NULL)
786
- uuid_copy(ae->config_hash_id, *((uuid_t *) sqlite3_column_blob(res, 4)));
838
+ if (sqlite3_column_type(res, 3) != SQLITE_NULL)
839
+ uuid_copy(ae->config_hash_id, *((uuid_t *) sqlite3_column_blob(res, 3)));
840
788
- ae->alarm_event_id = (uint32_t) sqlite3_column_int64(res, 3);
789
- ae->updated_by_id = (uint32_t) sqlite3_column_int64(res, 5);
790
- ae->updates_id = (uint32_t) sqlite3_column_int64(res, 6);
841
+ ae->alarm_event_id = (uint32_t) sqlite3_column_int64(res, 2);
842
+ ae->updated_by_id = (uint32_t) sqlite3_column_int64(res, 4);
843
+ ae->updates_id = (uint32_t) sqlite3_column_int64(res, 5);
844
792
- ae->when = (time_t) sqlite3_column_int64(res, 7);
793
- ae->duration = (time_t) sqlite3_column_int64(res, 8);
794
- ae->non_clear_duration = (time_t) sqlite3_column_int64(res, 9);
845
+ ae->when = (time_t) sqlite3_column_int64(res, 6);
846
+ ae->duration = (time_t) sqlite3_column_int64(res, 7);
847
+ ae->non_clear_duration = (time_t) sqlite3_column_int64(res, 8);
848
796
- ae->flags = (uint32_t) sqlite3_column_int64(res, 10);
849
+ ae->flags = (uint32_t) sqlite3_column_int64(res, 9);
850
ae->flags |= HEALTH_ENTRY_FLAG_SAVED;
851
799
- ae->exec_run_timestamp = (time_t) sqlite3_column_int64(res, 11);
800
- ae->delay_up_to_timestamp = (time_t) sqlite3_column_int64(res, 12);
852
+ ae->exec_run_timestamp = (time_t) sqlite3_column_int64(res, 10);
853
+ ae->delay_up_to_timestamp = (time_t) sqlite3_column_int64(res, 11);
854
802
- ae->name = string_strdupz((char *) sqlite3_column_text(res, 13));
803
- ae->chart = string_strdupz((char *) sqlite3_column_text(res, 14));
804
- ae->family = string_strdupz((char *) sqlite3_column_text(res, 15));
855
+ ae->name = string_strdupz((char *) sqlite3_column_text(res, 12));
856
+ ae->chart = string_strdupz((char *) sqlite3_column_text(res, 13));
857
+ ae->family = string_strdupz((char *) sqlite3_column_text(res, 14));
858
806
- if (sqlite3_column_type(res, 16) != SQLITE_NULL)
807
- ae->exec = string_strdupz((char *) sqlite3_column_text(res, 16));
859
+ if (sqlite3_column_type(res, 15) != SQLITE_NULL)
860
+ ae->exec = string_strdupz((char *) sqlite3_column_text(res, 15));
861
else
862
ae->exec = NULL;
863
811
- if (sqlite3_column_type(res, 17) != SQLITE_NULL)
812
- ae->recipient = string_strdupz((char *) sqlite3_column_text(res, 17));
864
+ if (sqlite3_column_type(res, 16) != SQLITE_NULL)
865
+ ae->recipient = string_strdupz((char *) sqlite3_column_text(res, 16));
866
else
867
ae->recipient = NULL;
868
816
- if (sqlite3_column_type(res, 18) != SQLITE_NULL)
817
- ae->source = string_strdupz((char *) sqlite3_column_text(res, 18));
869
+ if (sqlite3_column_type(res, 17) != SQLITE_NULL)
870
+ ae->source = string_strdupz((char *) sqlite3_column_text(res, 17));
871
else
872
ae->source = NULL;
873
821
- if (sqlite3_column_type(res, 19) != SQLITE_NULL)
822
- ae->units = string_strdupz((char *) sqlite3_column_text(res, 19));
874
+ if (sqlite3_column_type(res, 18) != SQLITE_NULL)
875
+ ae->units = string_strdupz((char *) sqlite3_column_text(res, 18));
876
else
877
ae->units = NULL;
878
826
- if (sqlite3_column_type(res, 20) != SQLITE_NULL)
827
- ae->info = string_strdupz((char *) sqlite3_column_text(res, 20));
879
+ if (sqlite3_column_type(res, 19) != SQLITE_NULL)
880
+ ae->info = string_strdupz((char *) sqlite3_column_text(res, 19));
881
else
882
ae->info = NULL;
883
831
- ae->exec_code = (int) sqlite3_column_int(res, 21);
832
- ae->new_status = (RRDCALC_STATUS) sqlite3_column_int(res, 22);
833
- ae->old_status = (RRDCALC_STATUS)sqlite3_column_int(res, 23);
834
- ae->delay = (int) sqlite3_column_int(res, 24);
884
+ ae->exec_code = (int) sqlite3_column_int(res, 20);
885
+ ae->new_status = (RRDCALC_STATUS) sqlite3_column_int(res, 21);
886
+ ae->old_status = (RRDCALC_STATUS)sqlite3_column_int(res, 22);
887
+ ae->delay = (int) sqlite3_column_int(res, 23);
888
836
- ae->new_value = (NETDATA_DOUBLE) sqlite3_column_double(res, 25);
837
- ae->old_value = (NETDATA_DOUBLE) sqlite3_column_double(res, 26);
889
+ ae->new_value = (NETDATA_DOUBLE) sqlite3_column_double(res, 24);
890
+ ae->old_value = (NETDATA_DOUBLE) sqlite3_column_double(res, 25);
891
892
ae->last_repeat = last_repeat;
893
841
- if (sqlite3_column_type(res, 28) != SQLITE_NULL)
842
- ae->classification = string_strdupz((char *) sqlite3_column_text(res, 28));
894
+ if (sqlite3_column_type(res, 27) != SQLITE_NULL)
895
+ ae->classification = string_strdupz((char *) sqlite3_column_text(res, 27));
896
else
897
ae->classification = NULL;
898
846
- if (sqlite3_column_type(res, 29) != SQLITE_NULL)
847
- ae->component = string_strdupz((char *) sqlite3_column_text(res, 29));
899
+ if (sqlite3_column_type(res, 28) != SQLITE_NULL)
900
+ ae->component = string_strdupz((char *) sqlite3_column_text(res, 28));
901
else
902
ae->component = NULL;
903
851
- if (sqlite3_column_type(res, 30) != SQLITE_NULL)
852
- ae->type = string_strdupz((char *) sqlite3_column_text(res, 30));
904
+ if (sqlite3_column_type(res, 29) != SQLITE_NULL)
905
+ ae->type = string_strdupz((char *) sqlite3_column_text(res, 29));
906
else
907
ae->type = NULL;
908
856
- if (sqlite3_column_type(res, 31) != SQLITE_NULL)
857
- ae->chart_context = string_strdupz((char *) sqlite3_column_text(res, 31));
909
+ if (sqlite3_column_type(res, 30) != SQLITE_NULL)
910
+ ae->chart_context = string_strdupz((char *) sqlite3_column_text(res, 30));
911
else
912
ae->chart_context = NULL;
913
861
- if (sqlite3_column_type(res, 32) != SQLITE_NULL)
862
- uuid_copy(ae->transition_id, *((uuid_t *) sqlite3_column_blob(res, 32)));
914
+ if (sqlite3_column_type(res, 31) != SQLITE_NULL)
915
+ uuid_copy(ae->transition_id, *((uuid_t *) sqlite3_column_blob(res, 31)));
916
917
char value_string[100 + 1];
918
string_freez(ae->old_value_string);
944
if (unlikely(!host->health_log.next_alarm_id || host->health_log.next_alarm_id <= host->health_max_alarm_id))
945
host->health_log.next_alarm_id = host->health_max_alarm_id + 1;
946
894
- log_health("[%s]: Table health_log_%s, loaded %zd alarm entries, errors in %zd entries.", rrdhost_hostname(host), uuid_str, loaded, errored);
947
+ log_health("[%s]: Table health_log, loaded %zd alarm entries, errors in %zd entries.", rrdhost_hostname(host), loaded, errored);
948
949
ret = sqlite3_finalize(res);
950
if (unlikely(ret != SQLITE_OK))
960
"on_key, class, component, type, os, hosts, lookup, every, units, calc, families, plugin, module, " \
961
"charts, green, red, warn, crit, exec, to_key, info, delay, options, repeat, host_labels, " \
962
"p_db_lookup_dimensions, p_db_lookup_method, p_db_lookup_options, p_db_lookup_after, " \
910
- "p_db_lookup_before, p_update_every) values (?1,unixepoch(),?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12," \
911
- "?13,?14,?15,?16,?17,?18,?19,?20,?21,?22,?23,?24,?25,?26,?27,?28,?29,?30,?31,?32,?33,?34);"
963
+ "p_db_lookup_before, p_update_every, source) values (?1,unixepoch(),?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12," \
964
+ "?13,?14,?15,?16,?17,?18,?19,?20,?21,?22,?23,?24,?25,?26,?27,?28,?29,?30,?31,?32,?33,?34,?35);"
965
966
int sql_store_alert_config_hash(uuid_t *hash_id, struct alert_config *cfg)
967
{
1141
if (unlikely(rc != SQLITE_OK))
1142
goto bind_fail;
1143
1144
+ rc = sqlite3_bind_string_or_null(res, cfg->source, ++param);
1145
+ if (unlikely(rc != SQLITE_OK))
1146
+ goto bind_fail;
1147
+
1148
rc = execute_insert(res);
1149
if (unlikely(rc != SQLITE_DONE))
1150
error_report("Failed to store alert config, rc = %d", rc);
1232
return 1;
1233
}
1234
1178
-#define SQL_SELECT_HEALTH_LAST_EXECUTED_EVENT "SELECT new_status FROM health_log_%s WHERE alarm_id = %u AND unique_id != %u AND flags & %d ORDER BY unique_id DESC LIMIT 1"
1235
+#define SQL_SELECT_HEALTH_LAST_EXECUTED_EVENT "SELECT hld.new_status FROM health_log hl, health_log_detail hld WHERE hl.alarm_id = %u AND hld.unique_id != %u AND hld.flags & %d AND hl.host_id = @host_id and hl.health_log_id = hld.health_log_id ORDER BY hld.unique_id DESC LIMIT 1;"
1236
int sql_health_get_last_executed_event(RRDHOST *host, ALARM_ENTRY *ae, RRDCALC_STATUS *last_executed_status)
1237
{
1238
int rc = 0, ret = -1;
1239
char command[MAX_HEALTH_SQL_SIZE + 1];
1183
-
1184
- char uuid_str[UUID_STR_LEN];
1185
- uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
1186
-
1240
sqlite3_stmt *res = NULL;
1241
1189
- snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_SELECT_HEALTH_LAST_EXECUTED_EVENT, uuid_str, ae->alarm_id, ae->unique_id, HEALTH_ENTRY_FLAG_EXEC_RUN);
1242
+ snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_SELECT_HEALTH_LAST_EXECUTED_EVENT, ae->alarm_id, ae->unique_id, HEALTH_ENTRY_FLAG_EXEC_RUN);
1243
1244
rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
1245
if (rc != SQLITE_OK) {
1247
return ret;
1248
}
1249
1250
+ rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
1251
+ if (unlikely(rc != SQLITE_OK)) {
1252
+ error_report("Failed to bind host_id parameter for SQL_SELECT_HEALTH_LAST_EXECUTED_EVENT.");
1253
+ sqlite3_finalize(res);
1254
+ return ret;
1255
+ }
1256
+
1257
ret = 0;
1258
while (sqlite3_step_monitored(res) == SQLITE_ROW) {
1259
*last_executed_status = (RRDCALC_STATUS) sqlite3_column_int(res, 0);
1267
return ret;
1268
}
1269
1210
-#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
1270
+#define SQL_SELECT_HEALTH_LOG "SELECT hld.unique_id, hld.alarm_id, hld.alarm_event_id, hl.config_hash_id, hld.updated_by_id, hld.updates_id, hld.when_key, hld.duration, hld.non_clear_duration, hld.flags, hld.exec_run_timestamp, hld.delay_up_to_timestamp, hl.name, hl.chart, hl.family, hl.exec, hl.recipient, ah.source, hl.units, hld.info, hld.exec_code, hld.new_status, hld.old_status, hld.delay, hld.new_value, hld.old_value, hld.last_repeat, ah.class, ah.component, ah.type, hl.chart_context, hld.transition_id FROM health_log hl, alert_hash ah, health_log_detail hld WHERE hl.config_hash_id = ah.hash_id and hl.health_log_id = hld.health_log_id and hl.host_id = @host_id "
1271
void sql_health_alarm_log2json(RRDHOST *host, BUFFER *wb, uint32_t after, char *chart) {
1272
1273
buffer_strcat(wb, "[");
1279
int rc;
1280
1281
BUFFER *command = buffer_create(MAX_HEALTH_SQL_SIZE, NULL);
1222
- char uuid_str[UUID_STR_LEN];
1223
- uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
1224
-
1225
- buffer_sprintf(command, SQL_SELECT_HEALTH_LOG(uuid_str));
1282
+ buffer_sprintf(command, SQL_SELECT_HEALTH_LOG);
1283
1284
if (chart) {
1285
char chart_sql[MAX_HEALTH_SQL_SIZE + 1];
1229
- snprintfz(chart_sql, MAX_HEALTH_SQL_SIZE, "AND chart = '%s' ", chart);
1286
+ snprintfz(chart_sql, MAX_HEALTH_SQL_SIZE, "AND hl.chart = '%s' ", chart);
1287
buffer_strcat(command, chart_sql);
1288
}
1289
1290
if (after) {
1291
char after_sql[MAX_HEALTH_SQL_SIZE + 1];
1235
- snprintfz(after_sql, MAX_HEALTH_SQL_SIZE, "AND unique_id > %u ", after);
1292
+ snprintfz(after_sql, MAX_HEALTH_SQL_SIZE, "AND hld.unique_id > %u ", after);
1293
buffer_strcat(command, after_sql);
1294
}
1295
1296
{
1297
char limit_sql[MAX_HEALTH_SQL_SIZE + 1];
1241
- snprintfz(limit_sql, MAX_HEALTH_SQL_SIZE, "ORDER BY unique_id DESC LIMIT %u ", max);
1298
+ snprintfz(limit_sql, MAX_HEALTH_SQL_SIZE, "ORDER BY hld.unique_id DESC LIMIT %u ", max);
1299
buffer_strcat(command, limit_sql);
1300
}
1301
1306
return;
1307
}
1308
1309
+ rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
1310
+ if (unlikely(rc != SQLITE_OK)) {
1311
+ error_report("Failed to bind host_id for SQL_SELECT_HEALTH_LOG.");
1312
+ sqlite3_finalize(res);
1313
+ buffer_free(command);
1314
+ return;
1315
+ }
1316
+
1317
while (sqlite3_step(res) == SQLITE_ROW) {
1318
1319
char old_value_string[100 + 1];
1320
char new_value_string[100 + 1];
1321
1322
char config_hash_id[UUID_STR_LEN];
1258
- uuid_unparse_lower(*((uuid_t *) sqlite3_column_blob(res, 4)), config_hash_id);
1323
+ uuid_unparse_lower(*((uuid_t *) sqlite3_column_blob(res, 3)), config_hash_id);
1324
1325
char transition_id[UUID_STR_LEN] = {0};
1261
- if (sqlite3_column_type(res, 32) != SQLITE_NULL)
1262
- uuid_unparse_lower(*((uuid_t *) sqlite3_column_blob(res, 32)), transition_id);
1326
+ if (sqlite3_column_type(res, 31) != SQLITE_NULL)
1327
+ uuid_unparse_lower(*((uuid_t *) sqlite3_column_blob(res, 31)), transition_id);
1328
1264
- char *edit_command = health_edit_command_from_source((char *)sqlite3_column_text(res, 18));
1329
+ char *edit_command = health_edit_command_from_source((char *)sqlite3_column_text(res, 17));
1330
1331
if (count)
1332
buffer_sprintf(wb, ",");
1374
"\t\t\"old_value_string\": \"%s\",\n"
1375
"\t\t\"last_repeat\": \"%lu\",\n"
1376
"\t\t\"silenced\": \"%s\",\n",
1312
- sqlite3_column_text(res, 0),
1377
+ rrdhost_hostname(host),
1378
host->utc_offset,
1379
rrdhost_abbrev_timezone(host),
1380
+ (unsigned int) sqlite3_column_int64(res, 0),
1381
(unsigned int) sqlite3_column_int64(res, 1),
1382
(unsigned int) sqlite3_column_int64(res, 2),
1317
- (unsigned int) sqlite3_column_int64(res, 3),
1383
config_hash_id,
1384
transition_id,
1385
+ sqlite3_column_text(res, 12),
1386
sqlite3_column_text(res, 13),
1387
+ sqlite3_column_text(res, 30),
1388
sqlite3_column_text(res, 14),
1322
- sqlite3_column_text(res, 31),
1323
- sqlite3_column_text(res, 15),
1389
+ sqlite3_column_text(res, 27) ? (const char *) sqlite3_column_text(res, 27) : (char *) "Unknown",
1390
sqlite3_column_text(res, 28) ? (const char *) sqlite3_column_text(res, 28) : (char *) "Unknown",
1391
sqlite3_column_text(res, 29) ? (const char *) sqlite3_column_text(res, 29) : (char *) "Unknown",
1326
- sqlite3_column_text(res, 30) ? (const char *) sqlite3_column_text(res, 30) : (char *) "Unknown",
1327
- (sqlite3_column_int64(res, 10) & HEALTH_ENTRY_FLAG_PROCESSED)?"true":"false",
1328
- (sqlite3_column_int64(res, 10) & HEALTH_ENTRY_FLAG_UPDATED)?"true":"false",
1329
- (long unsigned int)sqlite3_column_int64(res, 11),
1330
- (sqlite3_column_int64(res, 10) & HEALTH_ENTRY_FLAG_EXEC_FAILED)?"true":"false",
1331
- sqlite3_column_text(res, 16) ? (const char *) sqlite3_column_text(res, 16) : string2str(host->health.health_default_exec),
1332
- sqlite3_column_text(res, 17) ? (const char *) sqlite3_column_text(res, 17) : string2str(host->health.health_default_recipient),
1333
- sqlite3_column_int(res, 21),
1334
- sqlite3_column_text(res, 18),
1392
+ (sqlite3_column_int64(res, 9) & HEALTH_ENTRY_FLAG_PROCESSED)?"true":"false",
1393
+ (sqlite3_column_int64(res, 9) & HEALTH_ENTRY_FLAG_UPDATED)?"true":"false",
1394
+ (long unsigned int)sqlite3_column_int64(res, 10),
1395
+ (sqlite3_column_int64(res, 9) & HEALTH_ENTRY_FLAG_EXEC_FAILED)?"true":"false",
1396
+ sqlite3_column_text(res, 15) ? (const char *) sqlite3_column_text(res, 15) : string2str(host->health.health_default_exec),
1397
+ sqlite3_column_text(res, 16) ? (const char *) sqlite3_column_text(res, 16) : string2str(host->health.health_default_recipient),
1398
+ sqlite3_column_int(res, 20),
1399
+ sqlite3_column_text(res, 17),
1400
edit_command,
1336
- sqlite3_column_text(res, 19),
1401
+ sqlite3_column_text(res, 18),
1402
+ (long unsigned int)sqlite3_column_int64(res, 6),
1403
(long unsigned int)sqlite3_column_int64(res, 7),
1404
(long unsigned int)sqlite3_column_int64(res, 8),
1339
- (long unsigned int)sqlite3_column_int64(res, 9),
1405
+ rrdcalc_status2string(sqlite3_column_int(res, 21)),
1406
rrdcalc_status2string(sqlite3_column_int(res, 22)),
1341
- rrdcalc_status2string(sqlite3_column_int(res, 23)),
1342
- sqlite3_column_int(res, 24),
1343
- (long unsigned int)sqlite3_column_int64(res, 12),
1407
+ sqlite3_column_int(res, 23),
1408
+ (long unsigned int)sqlite3_column_int64(res, 11),
1409
+ (unsigned int)sqlite3_column_int64(res, 4),
1410
(unsigned int)sqlite3_column_int64(res, 5),
1345
- (unsigned int)sqlite3_column_int64(res, 6),
1346
- sqlite3_column_type(res, 25) == SQLITE_NULL ? "-" : format_value_and_unit(new_value_string, 100, sqlite3_column_double(res, 25), (char *) sqlite3_column_text(res, 19), -1),
1347
- sqlite3_column_type(res, 26) == SQLITE_NULL ? "-" : format_value_and_unit(old_value_string, 100, sqlite3_column_double(res, 26), (char *) sqlite3_column_text(res, 19), -1),
1348
- (long unsigned int)sqlite3_column_int64(res, 27),
1349
- (sqlite3_column_int64(res, 10) & HEALTH_ENTRY_FLAG_SILENCED)?"true":"false");
1411
+ sqlite3_column_type(res, 24) == SQLITE_NULL ? "-" : format_value_and_unit(new_value_string, 100, sqlite3_column_double(res, 24), (char *) sqlite3_column_text(res, 18), -1),
1412
+ sqlite3_column_type(res, 25) == SQLITE_NULL ? "-" : format_value_and_unit(old_value_string, 100, sqlite3_column_double(res, 25), (char *) sqlite3_column_text(res, 18), -1),
1413
+ (long unsigned int)sqlite3_column_int64(res, 26),
1414
+ (sqlite3_column_int64(res, 9) & HEALTH_ENTRY_FLAG_SILENCED)?"true":"false");
1415
1351
- health_string2json(wb, "\t\t", "info", (char *) sqlite3_column_text(res, 20), ",\n");
1416
+ health_string2json(wb, "\t\t", "info", (char *) sqlite3_column_text(res, 19), ",\n");
1417
1353
- if(unlikely(sqlite3_column_int64(res, 10) & HEALTH_ENTRY_FLAG_NO_CLEAR_NOTIFICATION)) {
1418
+ if(unlikely(sqlite3_column_int64(res, 9) & HEALTH_ENTRY_FLAG_NO_CLEAR_NOTIFICATION)) {
1419
buffer_strcat(wb, "\t\t\"no_clear_notification\": true,\n");
1420
}
1421
1422
buffer_strcat(wb, "\t\t\"value\":");
1358
- if (sqlite3_column_type(res, 25) == SQLITE_NULL)
1423
+ if (sqlite3_column_type(res, 24) == SQLITE_NULL)
1424
buffer_strcat(wb, "null");
1425
else
1361
- buffer_print_netdata_double(wb, sqlite3_column_double(res, 25));
1426
+ buffer_print_netdata_double(wb, sqlite3_column_double(res, 24));
1427
buffer_strcat(wb, ",\n");
1428
1429
buffer_strcat(wb, "\t\t\"old_value\":");
1365
- if (sqlite3_column_type(res, 26) == SQLITE_NULL)
1430
+ if (sqlite3_column_type(res, 25) == SQLITE_NULL)
1431
buffer_strcat(wb, "null");
1432
else
1368
- buffer_print_netdata_double(wb, sqlite3_column_double(res, 26));
1433
+ buffer_print_netdata_double(wb, sqlite3_column_double(res, 25));
1434
buffer_strcat(wb, "\n");
1435
1436
buffer_strcat(wb, "\t}");
1446
1447
buffer_free(command);
1448
}
1449
+
1450
+#define SQL_COPY_HEALTH_LOG(table) "INSERT OR IGNORE INTO health_log (host_id, alarm_id, config_hash_id, name, chart, family, exec, recipient, units, chart_context) SELECT ?1, alarm_id, config_hash_id, name, chart, family, exec, recipient, units, chart_context from %s;", table
1451
+#define SQL_COPY_HEALTH_LOG_DETAIL(table) "INSERT INTO health_log_detail (unique_id, alarm_id, alarm_event_id, updated_by_id, updates_id, when_key, duration, non_clear_duration, flags, exec_run_timestamp, delay_up_to_timestamp, info, exec_code, new_status, old_status, delay, new_value, old_value, last_repeat, transition_id, global_id, host_id) SELECT unique_id, alarm_id, alarm_event_id, updated_by_id, updates_id, when_key, duration, non_clear_duration, flags, exec_run_timestamp, delay_up_to_timestamp, info, exec_code, new_status, old_status, delay, new_value, old_value, last_repeat, transition_id, now_usec(1), ?1 from %s;", table
1452
+#define SQL_UPDATE_HEALTH_LOG_DETAIL_TRANSITION_ID "update health_log_detail set transition_id = uuid_random() where transition_id is null;"
1453
+#define SQL_UPDATE_HEALTH_LOG_DETAIL_HEALTH_LOG_ID "update health_log_detail set health_log_id = (select health_log_id from health_log where host_id = ?1 and alarm_id = health_log_detail.alarm_id) where health_log_id is null and host_id = ?2;"
1454
+#define SQL_UPDATE_HEALTH_LOG_LAST_TRANSITION_ID "update health_log set last_transition_id = (select transition_id from health_log_detail where health_log_id = health_log.health_log_id and alarm_id = health_log.alarm_id group by (alarm_id) having max(alarm_event_id)) where host_id = ?1;"
1455
+int health_migrate_old_health_log_table(char *table) {
1456
+ if (!table)
1457
+ return 0;
1458
+
1459
+ //table should contain guid. We need to
1460
+ //keep it in the new table along with it's data
1461
+ //health_log_XXXXXXXX_XXXX_XXXX_XXXX_XXXXXXXXXXXX
1462
+ if (strnlen(table, 46) != 46) {
1463
+ return 0;
1464
+ }
1465
+
1466
+ char *uuid_from_table = strdupz(table + 11);
1467
+ uuid_t uuid;
1468
+ if (uuid_parse_fix(uuid_from_table, uuid)) {
1469
+ freez(uuid_from_table);
1470
+ return 0;
1471
+ }
1472
+
1473
+ int rc;
1474
+ char command[MAX_HEALTH_SQL_SIZE + 1];
1475
+ sqlite3_stmt *res = NULL;
1476
+ snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_COPY_HEALTH_LOG(table));
1477
+ rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
1478
+ if (unlikely(rc != SQLITE_OK)) {
1479
+ error_report("Failed to prepare statement to copy health log, rc = %d", rc);
1480
+ freez(uuid_from_table);
1481
+ return 0;
1482
+ }
1483
+
1484
+ rc = sqlite3_bind_blob(res, 1, &uuid, sizeof(uuid), SQLITE_STATIC);
1485
+ if (unlikely(rc != SQLITE_OK)) {
1486
+ rc = sqlite3_finalize(res);
1487
+ if (unlikely(rc != SQLITE_OK))
1488
+ error_report("Failed to reset statement to copy health log table, rc = %d", rc);
1489
+ freez(uuid_from_table);
1490
+ return 0;
1491
+ }
1492
+
1493
+ rc = execute_insert(res);
1494
+ if (unlikely(rc != SQLITE_DONE)) {
1495
+ error_report("Failed to execute SQL_COPY_HEALTH_LOG, rc = %d", rc);
1496
+ rc = sqlite3_finalize(res);
1497
+ if (unlikely(rc != SQLITE_OK))
1498
+ error_report("Failed to reset statement to copy health log table, rc = %d", rc);
1499
+ freez(uuid_from_table);
1500
+ }
1501
+
1502
+ //detail
1503
+ snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_COPY_HEALTH_LOG_DETAIL(table));
1504
+ rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
1505
+ if (unlikely(rc != SQLITE_OK)) {
1506
+ error_report("Failed to prepare statement to copy health log detail, rc = %d", rc);
1507
+ return 0;
1508
+ }
1509
+
1510
+ rc = sqlite3_bind_blob(res, 1, &uuid, sizeof(uuid), SQLITE_STATIC);
1511
+ if (unlikely(rc != SQLITE_OK)) {
1512
+ rc = sqlite3_finalize(res);
1513
+ if (unlikely(rc != SQLITE_OK))
1514
+ error_report("Failed to reset statement to copy health log detail, rc = %d", rc);
1515
+ return 0;
1516
+ }
1517
+
1518
+ rc = execute_insert(res);
1519
+ if (unlikely(rc != SQLITE_DONE)) {
1520
+ error_report("Failed to execute SQL_COPY_HEALTH_LOG_DETAIL, rc = %d", rc);
1521
+ rc = sqlite3_finalize(res);
1522
+ if (unlikely(rc != SQLITE_OK))
1523
+ error_report("Failed to reset statement to copy health log detail table, rc = %d", rc);
1524
+ return 0;
1525
+ }
1526
+
1527
+ //update transition ids
1528
+ rc = sqlite3_prepare_v2(db_meta, SQL_UPDATE_HEALTH_LOG_DETAIL_TRANSITION_ID, -1, &res, 0);
1529
+ if (unlikely(rc != SQLITE_OK)) {
1530
+ error_report("Failed to prepare statement to update health log detail with transition ids, rc = %d", rc);
1531
+ return 0;
1532
+ }
1533
+
1534
+ rc = execute_insert(res);
1535
+ if (unlikely(rc != SQLITE_DONE)) {
1536
+ error_report("Failed to execute SQL_UPDATE_HEALTH_LOG_DETAIL_TRANSITION_ID, rc = %d", rc);
1537
+ rc = sqlite3_finalize(res);
1538
+ if (unlikely(rc != SQLITE_OK))
1539
+ error_report("Failed to reset statement to update health log detail table with transition ids, rc = %d", rc);
1540
+ return 0;
1541
+ }
1542
+
1543
+ //update health_log_id
1544
+ rc = sqlite3_prepare_v2(db_meta, SQL_UPDATE_HEALTH_LOG_DETAIL_HEALTH_LOG_ID, -1, &res, 0);
1545
+ if (unlikely(rc != SQLITE_OK)) {
1546
+ error_report("Failed to prepare statement to update health log detail with health log ids, rc = %d", rc);
1547
+ return 0;
1548
+ }
1549
+
1550
+ rc = sqlite3_bind_blob(res, 1, &uuid, sizeof(uuid), SQLITE_STATIC);
1551
+ if (unlikely(rc != SQLITE_OK)) {
1552
+ rc = sqlite3_finalize(res);
1553
+ if (unlikely(rc != SQLITE_OK))
1554
+ error_report("Failed to reset statement to update health log detail with health log ids, rc = %d", rc);
1555
+ return 0;
1556
+ }
1557
+
1558
+ rc = sqlite3_bind_blob(res, 2, &uuid, sizeof(uuid), SQLITE_STATIC);
1559
+ if (unlikely(rc != SQLITE_OK)) {
1560
+ rc = sqlite3_finalize(res);
1561
+ if (unlikely(rc != SQLITE_OK))
1562
+ error_report("Failed to reset statement to update health log detail with health log ids, rc = %d", rc);
1563
+ return 0;
1564
+ }
1565
+
1566
+ rc = execute_insert(res);
1567
+ if (unlikely(rc != SQLITE_DONE)) {
1568
+ error_report("Failed to execute SQL_UPDATE_HEALTH_LOG_DETAIL_HEALTH_LOG_ID, rc = %d", rc);
1569
+ rc = sqlite3_finalize(res);
1570
+ if (unlikely(rc != SQLITE_OK))
1571
+ error_report("Failed to reset statement to update health log detail table with health log ids, rc = %d", rc);
1572
+ }
1573
+
1574
+ //update last transition id
1575
+ rc = sqlite3_prepare_v2(db_meta, SQL_UPDATE_HEALTH_LOG_LAST_TRANSITION_ID, -1, &res, 0);
1576
+ if (unlikely(rc != SQLITE_OK)) {
1577
+ error_report("Failed to prepare statement to update health log with last transition id, rc = %d", rc);
1578
+ return 0;
1579
+ }
1580
+
1581
+ rc = sqlite3_bind_blob(res, 1, &uuid, sizeof(uuid), SQLITE_STATIC);
1582
+ if (unlikely(rc != SQLITE_OK)) {
1583
+ rc = sqlite3_finalize(res);
1584
+ if (unlikely(rc != SQLITE_OK))
1585
+ error_report("Failed to reset statement to update health log with last transition id, rc = %d", rc);
1586
+ return 0;
1587
+ }
1588
+
1589
+ rc = execute_insert(res);
1590
+ if (unlikely(rc != SQLITE_DONE)) {
1591
+ error_report("Failed to execute SQL_UPDATE_HEALTH_LOG_LAST_TRANSITION_ID, rc = %d", rc);
1592
+ rc = sqlite3_finalize(res);
1593
+ if (unlikely(rc != SQLITE_OK))
1594
+ error_report("Failed to reset statement to update health log table with last transition id, rc = %d", rc);
1595
+ }
1596
+
1597
+ return 1;
1598
+}
1599
+
1600
+#define SQL_GET_ALARM_ID "select alarm_id, health_log_id from health_log where host_id = @host_id and chart = @chart and name = @name"
1601
+#define SQL_GET_EVENT_ID "select max(alarm_event_id) + 1 from health_log_detail where health_log_id = @health_log_id and alarm_id = @alarm_id"
1602
+uint32_t sql_get_alarm_id(RRDHOST *host, STRING *chart, STRING *name, uint32_t *next_event_id)
1603
+{
1604
+ int rc = 0;
1605
+ sqlite3_stmt *res = NULL;
1606
+ uint32_t alarm_id = 0;
1607
+ uint64_t health_log_id = 0;
1608
+
1609
+ rc = sqlite3_prepare_v2(db_meta, SQL_GET_ALARM_ID, -1, &res, 0);
1610
+ if (rc != SQLITE_OK) {
1611
+ error_report("Failed to prepare statement when trying to get an alarm id");
1612
+ return alarm_id;
1613
+ }
1614
+
1615
+ rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
1616
+ if (unlikely(rc != SQLITE_OK)) {
1617
+ error_report("Failed to bind host_id parameter for SQL_GET_ALARM_ID.");
1618
+ sqlite3_finalize(res);
1619
+ return alarm_id;
1620
+ }
1621
+
1622
+ rc = sqlite3_bind_string_or_null(res, chart, 2);
1623
+ if (unlikely(rc != SQLITE_OK)) {
1624
+ error_report("Failed to bind char parameter for SQL_GET_ALARM_ID.");
1625
+ sqlite3_finalize(res);
1626
+ return alarm_id;
1627
+ }
1628
+
1629
+ rc = sqlite3_bind_string_or_null(res, name, 3);
1630
+ if (unlikely(rc != SQLITE_OK)) {
1631
+ error_report("Failed to bind name parameter for SQL_GET_ALARM_ID.");
1632
+ sqlite3_finalize(res);
1633
+ return alarm_id;
1634
+ }
1635
+
1636
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
1637
+ alarm_id = (uint32_t) sqlite3_column_int64(res, 0);
1638
+ health_log_id = (uint64_t) sqlite3_column_int64(res, 1);
1639
+ }
1640
+
1641
+ rc = sqlite3_finalize(res);
1642
+ if (unlikely(rc != SQLITE_OK))
1643
+ error_report("Failed to finalize the statement while getting an alarm id.");
1644
+
1645
+ if (alarm_id) {
1646
+ rc = sqlite3_prepare_v2(db_meta, SQL_GET_EVENT_ID, -1, &res, 0);
1647
+ if (rc != SQLITE_OK) {
1648
+ error_report("Failed to prepare statement when trying to get an event id");
1649
+ return alarm_id;
1650
+ }
1651
+
1652
+ rc = sqlite3_bind_int64(res, 1, (sqlite3_int64) health_log_id);
1653
+ if (unlikely(rc != SQLITE_OK)) {
1654
+ error_report("Failed to bind host_id parameter for SQL_GET_EVENT_ID.");
1655
+ sqlite3_finalize(res);
1656
+ return alarm_id;
1657
+ }
1658
+
1659
+ rc = sqlite3_bind_int64(res, 2, (sqlite3_int64) alarm_id);
1660
+ if (unlikely(rc != SQLITE_OK)) {
1661
+ error_report("Failed to bind char parameter for SQL_GET_EVENT_ID.");
1662
+ sqlite3_finalize(res);
1663
+ return alarm_id;
1664
+ }
1665
+
1666
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
1667
+ *next_event_id = (uint32_t) sqlite3_column_int64(res, 0);
1668
+ }
1669
+
1670
+ rc = sqlite3_finalize(res);
1671
+ if (unlikely(rc != SQLITE_OK))
1672
+ error_report("Failed to finalize the statement while getting an alarm id.");
1673
+ }
1674
+
1675
+ return alarm_id;
1676
+}