sqlite_health.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "sqlite_health.h"
  3. #include "sqlite_functions.h"
  4. #define MAX_HEALTH_SQL_SIZE 2048
  5. /* Health related SQL queries
  6. Creates a health log table in sqlite, one per host guid
  7. */
  8. #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);", guid
  9. int sql_create_health_log_table(RRDHOST *host) {
  10. int rc;
  11. char *err_msg = NULL, command[MAX_HEALTH_SQL_SIZE + 1];
  12. if (unlikely(!db_meta)) {
  13. if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
  14. error_report("HEALTH [%s]: Database has not been initialized", host->hostname);
  15. return 1;
  16. }
  17. char uuid_str[GUID_LEN + 1];
  18. uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
  19. snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_CREATE_HEALTH_LOG_TABLE(uuid_str));
  20. rc = sqlite3_exec(db_meta, command, 0, 0, &err_msg);
  21. if (rc != SQLITE_OK) {
  22. error_report("HEALTH [%s]: SQLite error during creation of health log table, rc = %d (%s)", host->hostname, rc, err_msg);
  23. sqlite3_free(err_msg);
  24. return 1;
  25. }
  26. snprintfz(command, MAX_HEALTH_SQL_SIZE, "CREATE INDEX IF NOT EXISTS "
  27. "health_log_index_%s ON health_log_%s (unique_id); ", uuid_str, uuid_str);
  28. db_execute(command);
  29. return 0;
  30. }
  31. /* Health related SQL queries
  32. Updates an entry in the table
  33. */
  34. #define SQL_UPDATE_HEALTH_LOG(guid) "UPDATE health_log_%s set updated_by_id = ?, flags = ?, exec_run_timestamp = ?, exec_code = ? where unique_id = ?;", guid
  35. void sql_health_alarm_log_update(RRDHOST *host, ALARM_ENTRY *ae) {
  36. sqlite3_stmt *res = NULL;
  37. int rc;
  38. char command[MAX_HEALTH_SQL_SIZE + 1];
  39. if (unlikely(!db_meta)) {
  40. if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
  41. error_report("HEALTH [%s]: Database has not been initialized", host->hostname);
  42. return;
  43. }
  44. char uuid_str[GUID_LEN + 1];
  45. uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
  46. snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_UPDATE_HEALTH_LOG(uuid_str));
  47. rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
  48. if (unlikely(rc != SQLITE_OK)) {
  49. error_report("HEALTH [%s]: Failed to prepare statement for SQL_UPDATE_HEALTH_LOG", host->hostname);
  50. return;
  51. }
  52. rc = sqlite3_bind_int64(res, 1, (sqlite3_int64) ae->updated_by_id);
  53. if (unlikely(rc != SQLITE_OK)) {
  54. error_report("Failed to bind updated_by_id parameter for SQL_UPDATE_HEALTH_LOG");
  55. goto failed;
  56. }
  57. rc = sqlite3_bind_int64(res, 2, (sqlite3_int64) ae->flags);
  58. if (unlikely(rc != SQLITE_OK)) {
  59. error_report("Failed to bind flags parameter for SQL_UPDATE_HEALTH_LOG");
  60. goto failed;
  61. }
  62. rc = sqlite3_bind_int64(res, 3, (sqlite3_int64) ae->exec_run_timestamp);
  63. if (unlikely(rc != SQLITE_OK)) {
  64. error_report("Failed to bind exec_run_timestamp parameter for SQL_UPDATE_HEALTH_LOG");
  65. goto failed;
  66. }
  67. rc = sqlite3_bind_int(res, 4, ae->exec_code);
  68. if (unlikely(rc != SQLITE_OK)) {
  69. error_report("Failed to bind exec_code parameter for SQL_UPDATE_HEALTH_LOG");
  70. goto failed;
  71. }
  72. rc = sqlite3_bind_int64(res, 5, (sqlite3_int64) ae->unique_id);
  73. if (unlikely(rc != SQLITE_OK)) {
  74. error_report("Failed to bind unique_id parameter for SQL_UPDATE_HEALTH_LOG");
  75. goto failed;
  76. }
  77. rc = execute_insert(res);
  78. if (unlikely(rc != SQLITE_DONE)) {
  79. error_report("HEALTH [%s]: Failed to update health log, rc = %d", host->hostname, rc);
  80. }
  81. failed:
  82. if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
  83. error_report("HEALTH [%s]: Failed to finalize the prepared statement for updating health log.", host->hostname);
  84. return;
  85. }
  86. /* Health related SQL queries
  87. Inserts an entry in the table
  88. */
  89. #define SQL_INSERT_HEALTH_LOG(guid) "INSERT INTO health_log_%s(hostname, unique_id, alarm_id, alarm_event_id, " \
  90. "config_hash_id, updated_by_id, updates_id, when_key, duration, non_clear_duration, flags, " \
  91. "exec_run_timestamp, delay_up_to_timestamp, name, chart, family, exec, recipient, source, " \
  92. "units, info, exec_code, new_status, old_status, delay, new_value, old_value, last_repeat, " \
  93. "class, component, type) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", guid
  94. void sql_health_alarm_log_insert(RRDHOST *host, ALARM_ENTRY *ae) {
  95. sqlite3_stmt *res = NULL;
  96. int rc;
  97. char command[MAX_HEALTH_SQL_SIZE + 1];
  98. if (unlikely(!db_meta)) {
  99. if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
  100. error_report("HEALTH [%s]: Database has not been initialized", host->hostname);
  101. return;
  102. }
  103. char uuid_str[GUID_LEN + 1];
  104. uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
  105. snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_INSERT_HEALTH_LOG(uuid_str));
  106. rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
  107. if (unlikely(rc != SQLITE_OK)) {
  108. error_report("HEALTH [%s]: Failed to prepare statement for SQL_INSERT_HEALTH_LOG", host->hostname);
  109. return;
  110. }
  111. rc = sqlite3_bind_text(res, 1, host->hostname, -1, SQLITE_STATIC);
  112. if (unlikely(rc != SQLITE_OK)) {
  113. error_report("Failed to bind hostname parameter for SQL_INSERT_HEALTH_LOG");
  114. goto failed;
  115. }
  116. rc = sqlite3_bind_int64(res, 2, (sqlite3_int64) ae->unique_id);
  117. if (unlikely(rc != SQLITE_OK)) {
  118. error_report("Failed to bind unique_id parameter for SQL_INSERT_HEALTH_LOG");
  119. goto failed;
  120. }
  121. rc = sqlite3_bind_int64(res, 3, (sqlite3_int64) ae->alarm_id);
  122. if (unlikely(rc != SQLITE_OK)) {
  123. error_report("Failed to bind alarm_id parameter for SQL_INSERT_HEALTH_LOG");
  124. goto failed;
  125. }
  126. rc = sqlite3_bind_int64(res, 4, (sqlite3_int64) ae->alarm_event_id);
  127. if (unlikely(rc != SQLITE_OK)) {
  128. error_report("Failed to bind alarm_event_id parameter for SQL_INSERT_HEALTH_LOG");
  129. goto failed;
  130. }
  131. rc = sqlite3_bind_blob(res, 5, &ae->config_hash_id, sizeof(ae->config_hash_id), SQLITE_STATIC);
  132. if (unlikely(rc != SQLITE_OK)) {
  133. error_report("Failed to bind config_hash_id parameter for SQL_INSERT_HEALTH_LOG");
  134. goto failed;
  135. }
  136. rc = sqlite3_bind_int64(res, 6, (sqlite3_int64) ae->updated_by_id);
  137. if (unlikely(rc != SQLITE_OK)) {
  138. error_report("Failed to bind updated_by_id parameter for SQL_INSERT_HEALTH_LOG");
  139. goto failed;
  140. }
  141. rc = sqlite3_bind_int64(res, 7, (sqlite3_int64) ae->updates_id);
  142. if (unlikely(rc != SQLITE_OK)) {
  143. error_report("Failed to bind updates_id parameter for SQL_INSERT_HEALTH_LOG");
  144. goto failed;
  145. }
  146. rc = sqlite3_bind_int64(res, 8, (sqlite3_int64) ae->when);
  147. if (unlikely(rc != SQLITE_OK)) {
  148. error_report("Failed to bind when parameter for SQL_INSERT_HEALTH_LOG");
  149. goto failed;
  150. }
  151. rc = sqlite3_bind_int64(res, 9, (sqlite3_int64) ae->duration);
  152. if (unlikely(rc != SQLITE_OK)) {
  153. error_report("Failed to bind duration parameter for SQL_INSERT_HEALTH_LOG");
  154. goto failed;
  155. }
  156. rc = sqlite3_bind_int64(res, 10, (sqlite3_int64) ae->non_clear_duration);
  157. if (unlikely(rc != SQLITE_OK)) {
  158. error_report("Failed to bind non_clear_duration parameter for SQL_INSERT_HEALTH_LOG");
  159. goto failed;
  160. }
  161. rc = sqlite3_bind_int64(res, 11, (sqlite3_int64) ae->flags);
  162. if (unlikely(rc != SQLITE_OK)) {
  163. error_report("Failed to bind flags parameter for SQL_INSERT_HEALTH_LOG");
  164. goto failed;
  165. }
  166. rc = sqlite3_bind_int64(res, 12, (sqlite3_int64) ae->exec_run_timestamp);
  167. if (unlikely(rc != SQLITE_OK)) {
  168. error_report("Failed to bind exec_run_timestamp parameter for SQL_INSERT_HEALTH_LOG");
  169. goto failed;
  170. }
  171. rc = sqlite3_bind_int64(res, 13, (sqlite3_int64) ae->delay_up_to_timestamp);
  172. if (unlikely(rc != SQLITE_OK)) {
  173. error_report("Failed to bind delay_up_to_timestamp parameter for SQL_INSERT_HEALTH_LOG");
  174. goto failed;
  175. }
  176. rc = sqlite3_bind_text(res, 14, ae->name, -1, SQLITE_STATIC);
  177. if (unlikely(rc != SQLITE_OK)) {
  178. error_report("Failed to bind name parameter for SQL_INSERT_HEALTH_LOG");
  179. goto failed;
  180. }
  181. rc = sqlite3_bind_text(res, 15, ae->chart, -1, SQLITE_STATIC);
  182. if (unlikely(rc != SQLITE_OK)) {
  183. error_report("Failed to bind chart parameter for SQL_INSERT_HEALTH_LOG");
  184. goto failed;
  185. }
  186. rc = sqlite3_bind_text(res, 16, ae->family, -1, SQLITE_STATIC);
  187. if (unlikely(rc != SQLITE_OK)) {
  188. error_report("Failed to bind family parameter for SQL_INSERT_HEALTH_LOG");
  189. goto failed;
  190. }
  191. rc = sqlite3_bind_text(res, 17, ae->exec, -1, SQLITE_STATIC);
  192. if (unlikely(rc != SQLITE_OK)) {
  193. error_report("Failed to bind exec parameter for SQL_INSERT_HEALTH_LOG");
  194. goto failed;
  195. }
  196. rc = sqlite3_bind_text(res, 18, ae->recipient, -1, SQLITE_STATIC);
  197. if (unlikely(rc != SQLITE_OK)) {
  198. error_report("Failed to bind recipient parameter for SQL_INSERT_HEALTH_LOG");
  199. goto failed;
  200. }
  201. rc = sqlite3_bind_text(res, 19, ae->source, -1, SQLITE_STATIC);
  202. if (unlikely(rc != SQLITE_OK)) {
  203. error_report("Failed to bind source parameter for SQL_INSERT_HEALTH_LOG");
  204. goto failed;
  205. }
  206. rc = sqlite3_bind_text(res, 20, ae->units, -1, SQLITE_STATIC);
  207. if (unlikely(rc != SQLITE_OK)) {
  208. error_report("Failed to bind host_id parameter to store node instance information");
  209. goto failed;
  210. }
  211. rc = sqlite3_bind_text(res, 21, ae->info, -1, SQLITE_STATIC);
  212. if (unlikely(rc != SQLITE_OK)) {
  213. error_report("Failed to bind info parameter for SQL_INSERT_HEALTH_LOG");
  214. goto failed;
  215. }
  216. rc = sqlite3_bind_int(res, 22, ae->exec_code);
  217. if (unlikely(rc != SQLITE_OK)) {
  218. error_report("Failed to bind exec_code parameter for SQL_INSERT_HEALTH_LOG");
  219. goto failed;
  220. }
  221. rc = sqlite3_bind_int(res, 23, ae->new_status);
  222. if (unlikely(rc != SQLITE_OK)) {
  223. error_report("Failed to bind new_status parameter for SQL_INSERT_HEALTH_LOG");
  224. goto failed;
  225. }
  226. rc = sqlite3_bind_int(res, 24, ae->old_status);
  227. if (unlikely(rc != SQLITE_OK)) {
  228. error_report("Failed to bind old_status parameter for SQL_INSERT_HEALTH_LOG");
  229. goto failed;
  230. }
  231. rc = sqlite3_bind_int(res, 25, ae->delay);
  232. if (unlikely(rc != SQLITE_OK)) {
  233. error_report("Failed to bind delay parameter for SQL_INSERT_HEALTH_LOG");
  234. goto failed;
  235. }
  236. rc = sqlite3_bind_double(res, 26, ae->new_value);
  237. if (unlikely(rc != SQLITE_OK)) {
  238. error_report("Failed to bind new_value parameter for SQL_INSERT_HEALTH_LOG");
  239. goto failed;
  240. }
  241. rc = sqlite3_bind_double(res, 27, ae->old_value);
  242. if (unlikely(rc != SQLITE_OK)) {
  243. error_report("Failed to bind old_value parameter for SQL_INSERT_HEALTH_LOG");
  244. goto failed;
  245. }
  246. rc = sqlite3_bind_int64(res, 28, (sqlite3_int64) ae->last_repeat);
  247. if (unlikely(rc != SQLITE_OK)) {
  248. error_report("Failed to bind last_repeat parameter for SQL_INSERT_HEALTH_LOG");
  249. goto failed;
  250. }
  251. rc = sqlite3_bind_text(res, 29, ae->classification, -1, SQLITE_STATIC);
  252. if (unlikely(rc != SQLITE_OK)) {
  253. error_report("Failed to bind classification parameter for SQL_INSERT_HEALTH_LOG");
  254. goto failed;
  255. }
  256. rc = sqlite3_bind_text(res, 30, ae->component, -1, SQLITE_STATIC);
  257. if (unlikely(rc != SQLITE_OK)) {
  258. error_report("Failed to bind component parameter for SQL_INSERT_HEALTH_LOG");
  259. goto failed;
  260. }
  261. rc = sqlite3_bind_text(res, 31, ae->type, -1, SQLITE_STATIC);
  262. if (unlikely(rc != SQLITE_OK)) {
  263. error_report("Failed to bind type parameter for SQL_INSERT_HEALTH_LOG");
  264. goto failed;
  265. }
  266. rc = execute_insert(res);
  267. if (unlikely(rc != SQLITE_DONE)) {
  268. error_report("HEALTH [%s]: Failed to execute SQL_INSERT_HEALTH_LOG, rc = %d", host->hostname, rc);
  269. goto failed;
  270. }
  271. ae->flags |= HEALTH_ENTRY_FLAG_SAVED;
  272. host->health_log_entries_written++;
  273. failed:
  274. if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
  275. error_report("HEALTH [%s]: Failed to finalize the prepared statement for inserting to health log.", host->hostname);
  276. return;
  277. }
  278. void sql_health_alarm_log_save(RRDHOST *host, ALARM_ENTRY *ae)
  279. {
  280. if (ae->flags & HEALTH_ENTRY_FLAG_SAVED)
  281. sql_health_alarm_log_update(host, ae);
  282. else
  283. sql_health_alarm_log_insert(host, ae);
  284. }
  285. /* Health related SQL queries
  286. Cleans up the health_log table.
  287. */
  288. #define SQL_CLEANUP_HEALTH_LOG(guid,guid2,limit) "DELETE from health_log_%s where unique_id in (SELECT unique_id from health_log_%s order by unique_id asc LIMIT %lu);", guid, guid2, limit
  289. void sql_health_alarm_log_cleanup(RRDHOST *host) {
  290. sqlite3_stmt *res = NULL;
  291. static size_t rotate_every = 0;
  292. int rc;
  293. char command[MAX_HEALTH_SQL_SIZE + 1];
  294. if(unlikely(rotate_every == 0)) {
  295. rotate_every = (size_t)config_get_number(CONFIG_SECTION_HEALTH, "rotate log every lines", 2000);
  296. if(rotate_every < 100) rotate_every = 100;
  297. }
  298. if(likely(host->health_log_entries_written < rotate_every)) {
  299. return;
  300. }
  301. if (unlikely(!db_meta)) {
  302. if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
  303. error_report("Database has not been initialized");
  304. return;
  305. }
  306. char uuid_str[GUID_LEN + 1];
  307. uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
  308. snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_CLEANUP_HEALTH_LOG(uuid_str, uuid_str, host->health_log_entries_written - rotate_every));
  309. rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
  310. if (unlikely(rc != SQLITE_OK)) {
  311. error_report("Failed to prepare statement to cleanup health log table");
  312. return;
  313. }
  314. rc = sqlite3_step(res);
  315. if (unlikely(rc != SQLITE_DONE))
  316. error_report("Failed to cleanup health log table, rc = %d", rc);
  317. rc = sqlite3_finalize(res);
  318. if (unlikely(rc != SQLITE_OK))
  319. error_report("Failed to finalize the prepared statement to cleanup health log table");
  320. host->health_log_entries_written = rotate_every;
  321. sql_aclk_alert_clean_dead_entries(host);
  322. }
  323. /* Health related SQL queries
  324. Get a count of rows from health log table
  325. */
  326. #define SQL_COUNT_HEALTH_LOG(guid) "SELECT count(1) FROM health_log_%s;", guid
  327. void sql_health_alarm_log_count(RRDHOST *host) {
  328. sqlite3_stmt *res = NULL;
  329. int rc;
  330. char command[MAX_HEALTH_SQL_SIZE + 1];
  331. if (unlikely(!db_meta)) {
  332. if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
  333. error_report("Database has not been initialized");
  334. return;
  335. }
  336. char uuid_str[GUID_LEN + 1];
  337. uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
  338. snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_COUNT_HEALTH_LOG(uuid_str));
  339. rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
  340. if (unlikely(rc != SQLITE_OK)) {
  341. error_report("Failed to prepare statement to count health log entries from db");
  342. return;
  343. }
  344. rc = sqlite3_step(res);
  345. if (likely(rc == SQLITE_ROW))
  346. host->health_log_entries_written = (size_t) sqlite3_column_int64(res, 0);
  347. rc = sqlite3_finalize(res);
  348. if (unlikely(rc != SQLITE_OK))
  349. error_report("Failed to finalize the prepared statement to count health log entries from db");
  350. info("HEALTH [%s]: Table health_log_%s, contains %lu entries.", host->hostname, uuid_str, host->health_log_entries_written);
  351. }
  352. #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, " \
  353. "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) " \
  354. "select hostname, ?1, ?2, ?3, config_hash_id, 0, ?4, strftime('%%s'), 0, 0, flags, exec_run_timestamp, " \
  355. "strftime('%%s'), name, chart, family, exec, recipient, source, units, info, exec_code, -2, new_status, delay, NULL, new_value, 0, class, component, type " \
  356. "from health_log_%s where unique_id = ?5", guid, guid2
  357. #define SQL_INJECT_REMOVED_UPDATE(guid) "update health_log_%s set flags = flags | ?1, updated_by_id = ?2 where unique_id = ?3; ", guid
  358. 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)
  359. {
  360. int rc = 0;
  361. char command[MAX_HEALTH_SQL_SIZE + 1];
  362. if (!alarm_id || !alarm_event_id || !unique_id || !max_unique_id)
  363. return;
  364. sqlite3_stmt *res = NULL;
  365. snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_INJECT_REMOVED(uuid_str, uuid_str));
  366. rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
  367. if (rc != SQLITE_OK) {
  368. error_report("Failed to prepare statement when trying to inject removed event");
  369. return;
  370. }
  371. rc = sqlite3_bind_int64(res, 1, (sqlite3_int64) max_unique_id);
  372. if (unlikely(rc != SQLITE_OK)) {
  373. error_report("Failed to bind max_unique_id parameter for SQL_INJECT_REMOVED");
  374. goto failed;
  375. }
  376. rc = sqlite3_bind_int64(res, 2, (sqlite3_int64) alarm_id);
  377. if (unlikely(rc != SQLITE_OK)) {
  378. error_report("Failed to bind alarm_id parameter for SQL_INJECT_REMOVED");
  379. goto failed;
  380. }
  381. rc = sqlite3_bind_int64(res, 3, (sqlite3_int64) alarm_event_id + 1);
  382. if (unlikely(rc != SQLITE_OK)) {
  383. error_report("Failed to bind alarm_event_id parameter for SQL_INJECT_REMOVED");
  384. goto failed;
  385. }
  386. rc = sqlite3_bind_int64(res, 4, (sqlite3_int64) unique_id);
  387. if (unlikely(rc != SQLITE_OK)) {
  388. error_report("Failed to bind unique_id parameter for SQL_INJECT_REMOVED");
  389. goto failed;
  390. }
  391. rc = sqlite3_bind_int64(res, 5, (sqlite3_int64) unique_id);
  392. if (unlikely(rc != SQLITE_OK)) {
  393. error_report("Failed to bind unique_id parameter for SQL_INJECT_REMOVED");
  394. goto failed;
  395. }
  396. rc = execute_insert(res);
  397. if (unlikely(rc != SQLITE_DONE)) {
  398. error_report("HEALTH [N/A]: Failed to execute SQL_INJECT_REMOVED, rc = %d", rc);
  399. goto failed;
  400. }
  401. if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
  402. error_report("HEALTH [N/A]: Failed to finalize the prepared statement for injecting removed event.");
  403. //update the old entry
  404. snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_INJECT_REMOVED_UPDATE(uuid_str));
  405. rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
  406. if (rc != SQLITE_OK) {
  407. error_report("Failed to prepare statement when trying to update during inject removed event");
  408. return;
  409. }
  410. rc = sqlite3_bind_int64(res, 1, (sqlite3_int64) HEALTH_ENTRY_FLAG_UPDATED);
  411. if (unlikely(rc != SQLITE_OK)) {
  412. error_report("Failed to bind flags parameter for SQL_INJECT_REMOVED (update)");
  413. goto failed;
  414. }
  415. rc = sqlite3_bind_int64(res, 2, (sqlite3_int64) max_unique_id);
  416. if (unlikely(rc != SQLITE_OK)) {
  417. error_report("Failed to bind max_unique_id parameter for SQL_INJECT_REMOVED (update)");
  418. goto failed;
  419. }
  420. rc = sqlite3_bind_int64(res, 3, (sqlite3_int64) unique_id);
  421. if (unlikely(rc != SQLITE_OK)) {
  422. error_report("Failed to bind unique_id parameter for SQL_INJECT_REMOVED (update)");
  423. goto failed;
  424. }
  425. rc = execute_insert(res);
  426. if (unlikely(rc != SQLITE_DONE)) {
  427. error_report("HEALTH [N/A]: Failed to execute SQL_INJECT_REMOVED_UPDATE, rc = %d", rc);
  428. goto failed;
  429. }
  430. failed:
  431. if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
  432. error_report("HEALTH [N/A]: Failed to finalize the prepared statement for injecting removed event.");
  433. return;
  434. }
  435. #define SQL_SELECT_MAX_UNIQUE_ID(guid) "SELECT MAX(unique_id) from health_log_%s", guid
  436. uint32_t sql_get_max_unique_id (char *uuid_str)
  437. {
  438. int rc = 0;
  439. char command[MAX_HEALTH_SQL_SIZE + 1];
  440. uint32_t max_unique_id = 0;
  441. sqlite3_stmt *res = NULL;
  442. snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_SELECT_MAX_UNIQUE_ID(uuid_str));
  443. rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
  444. if (rc != SQLITE_OK) {
  445. error_report("Failed to prepare statement when trying to get max unique id");
  446. return 0;
  447. }
  448. while (sqlite3_step(res) == SQLITE_ROW) {
  449. max_unique_id = (uint32_t) sqlite3_column_int64(res, 0);
  450. }
  451. rc = sqlite3_finalize(res);
  452. if (unlikely(rc != SQLITE_OK))
  453. error_report("Failed to finalize the statement");
  454. return max_unique_id;
  455. }
  456. #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
  457. void sql_check_removed_alerts_state(char *uuid_str)
  458. {
  459. int rc = 0;
  460. char command[MAX_HEALTH_SQL_SIZE + 1];
  461. RRDCALC_STATUS status;
  462. uint32_t alarm_id = 0, alarm_event_id = 0, unique_id = 0, max_unique_id = 0;
  463. sqlite3_stmt *res = NULL;
  464. snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_SELECT_LAST_STATUSES(uuid_str));
  465. rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
  466. if (rc != SQLITE_OK) {
  467. error_report("Failed to prepare statement when trying to check removed statuses");
  468. return;
  469. }
  470. while (sqlite3_step(res) == SQLITE_ROW) {
  471. status = (RRDCALC_STATUS) sqlite3_column_int(res, 0);
  472. unique_id = (uint32_t) sqlite3_column_int64(res, 1);
  473. alarm_id = (uint32_t) sqlite3_column_int64(res, 2);
  474. alarm_event_id = (uint32_t) sqlite3_column_int64(res, 3);
  475. if (unlikely(status != RRDCALC_STATUS_REMOVED)) {
  476. if (unlikely(!max_unique_id))
  477. max_unique_id = sql_get_max_unique_id (uuid_str);
  478. sql_inject_removed_status (uuid_str, alarm_id, alarm_event_id, unique_id, ++max_unique_id);
  479. }
  480. }
  481. rc = sqlite3_finalize(res);
  482. if (unlikely(rc != SQLITE_OK))
  483. error_report("Failed to finalize the statement");
  484. }
  485. /* Health related SQL queries
  486. Load from the health log table
  487. */
  488. #define SQL_LOAD_HEALTH_LOG(guid,limit) "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 FROM (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 FROM health_log_%s order by unique_id desc limit %u) order by unique_id asc;", guid, limit
  489. void sql_health_alarm_log_load(RRDHOST *host) {
  490. sqlite3_stmt *res = NULL;
  491. int rc;
  492. ssize_t errored = 0, loaded = 0;
  493. char command[MAX_HEALTH_SQL_SIZE + 1];
  494. host->health_log_entries_written = 0;
  495. if (unlikely(!db_meta)) {
  496. if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
  497. error_report("HEALTH [%s]: Database has not been initialized", host->hostname);
  498. return;
  499. }
  500. char uuid_str[GUID_LEN + 1];
  501. uuid_unparse_lower_fix(&host->host_uuid, uuid_str);
  502. sql_check_removed_alerts_state(uuid_str);
  503. snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_LOAD_HEALTH_LOG(uuid_str, host->health_log.max));
  504. rc = sqlite3_prepare_v2(db_meta, command, -1, &res, 0);
  505. if (unlikely(rc != SQLITE_OK)) {
  506. error_report("HEALTH [%s]: Failed to prepare sql statement to load health log.", host->hostname);
  507. return;
  508. }
  509. netdata_rwlock_rdlock(&host->health_log.alarm_log_rwlock);
  510. while (sqlite3_step(res) == SQLITE_ROW) {
  511. ALARM_ENTRY *ae = NULL;
  512. // check that we have valid ids
  513. uint32_t unique_id = (uint32_t) sqlite3_column_int64(res, 1);
  514. if(!unique_id) {
  515. error_report("HEALTH [%s]: Got invalid unique id. Ignoring it.", host->hostname);
  516. errored++;
  517. continue;
  518. }
  519. uint32_t alarm_id = (uint32_t) sqlite3_column_int64(res, 2);
  520. if(!alarm_id) {
  521. error_report("HEALTH [%s]: Got invalid alarm id. Ignoring it.", host->hostname);
  522. errored++;
  523. continue;
  524. }
  525. //need name, chart and family
  526. if (sqlite3_column_type(res, 13) == SQLITE_NULL) {
  527. error_report("HEALTH [%s]: Got null name field. Ignoring it.", host->hostname);
  528. errored++;
  529. continue;
  530. }
  531. if (sqlite3_column_type(res, 14) == SQLITE_NULL) {
  532. error_report("HEALTH [%s]: Got null chart field. Ignoring it.", host->hostname);
  533. errored++;
  534. continue;
  535. }
  536. if (sqlite3_column_type(res, 15) == SQLITE_NULL) {
  537. error_report("HEALTH [%s]: Got null family field. Ignoring it.", host->hostname);
  538. errored++;
  539. continue;
  540. }
  541. // Check if we got last_repeat field
  542. time_t last_repeat = 0;
  543. last_repeat = (time_t)sqlite3_column_int64(res, 27);
  544. RRDCALC *rc = alarm_max_last_repeat(host, (char *) sqlite3_column_text(res, 14), simple_hash((char *) sqlite3_column_text(res, 14)));
  545. if (!rc) {
  546. for(rc = host->alarms; rc ; rc = rc->next) {
  547. RRDCALC *rdcmp = (RRDCALC *) avl_insert_lock(&(host)->alarms_idx_name, (avl_t *)rc);
  548. if(rdcmp != rc) {
  549. error("Cannot insert the alarm index ID using log %s", rc->name);
  550. }
  551. }
  552. rc = alarm_max_last_repeat(host, (char *) sqlite3_column_text(res, 14), simple_hash((char *) sqlite3_column_text(res, 14)));
  553. }
  554. if(unlikely(rc)) {
  555. if (rrdcalc_isrepeating(rc)) {
  556. rc->last_repeat = last_repeat;
  557. // We iterate through repeating alarm entries only to
  558. // find the latest last_repeat timestamp. Otherwise,
  559. // there is no need to keep them in memory.
  560. continue;
  561. }
  562. }
  563. ae = callocz(1, sizeof(ALARM_ENTRY));
  564. ae->unique_id = unique_id;
  565. ae->alarm_id = alarm_id;
  566. if (sqlite3_column_type(res, 4) != SQLITE_NULL)
  567. uuid_copy(ae->config_hash_id, *((uuid_t *) sqlite3_column_blob(res, 4)));
  568. ae->alarm_event_id = (uint32_t) sqlite3_column_int64(res, 3);
  569. ae->updated_by_id = (uint32_t) sqlite3_column_int64(res, 5);
  570. ae->updates_id = (uint32_t) sqlite3_column_int64(res, 6);
  571. ae->when = (time_t) sqlite3_column_int64(res, 7);
  572. ae->duration = (time_t) sqlite3_column_int64(res, 8);
  573. ae->non_clear_duration = (time_t) sqlite3_column_int64(res, 9);
  574. ae->flags = (uint32_t) sqlite3_column_int64(res, 10);
  575. ae->flags |= HEALTH_ENTRY_FLAG_SAVED;
  576. ae->exec_run_timestamp = (time_t) sqlite3_column_int64(res, 11);
  577. ae->delay_up_to_timestamp = (time_t) sqlite3_column_int64(res, 12);
  578. ae->name = strdupz((char *) sqlite3_column_text(res, 13));
  579. ae->hash_name = simple_hash(ae->name);
  580. ae->chart = strdupz((char *) sqlite3_column_text(res, 14));
  581. ae->hash_chart = simple_hash(ae->chart);
  582. ae->family = strdupz((char *) sqlite3_column_text(res, 15));
  583. if (sqlite3_column_type(res, 16) != SQLITE_NULL)
  584. ae->exec = strdupz((char *) sqlite3_column_text(res, 16));
  585. else
  586. ae->exec = NULL;
  587. if (sqlite3_column_type(res, 17) != SQLITE_NULL)
  588. ae->recipient = strdupz((char *) sqlite3_column_text(res, 17));
  589. else
  590. ae->recipient = NULL;
  591. if (sqlite3_column_type(res, 18) != SQLITE_NULL)
  592. ae->source = strdupz((char *) sqlite3_column_text(res, 18));
  593. else
  594. ae->source = NULL;
  595. if (sqlite3_column_type(res, 19) != SQLITE_NULL)
  596. ae->units = strdupz((char *) sqlite3_column_text(res, 19));
  597. else
  598. ae->units = NULL;
  599. if (sqlite3_column_type(res, 20) != SQLITE_NULL)
  600. ae->info = strdupz((char *) sqlite3_column_text(res, 20));
  601. else
  602. ae->info = NULL;
  603. ae->exec_code = (int) sqlite3_column_int(res, 21);
  604. ae->new_status = (RRDCALC_STATUS) sqlite3_column_int(res, 22);
  605. ae->old_status = (RRDCALC_STATUS)sqlite3_column_int(res, 23);
  606. ae->delay = (int) sqlite3_column_int(res, 24);
  607. ae->new_value = (calculated_number) sqlite3_column_double(res, 25);
  608. ae->old_value = (calculated_number) sqlite3_column_double(res, 26);
  609. ae->last_repeat = last_repeat;
  610. if (sqlite3_column_type(res, 28) != SQLITE_NULL)
  611. ae->classification = strdupz((char *) sqlite3_column_text(res, 28));
  612. else
  613. ae->classification = NULL;
  614. if (sqlite3_column_type(res, 29) != SQLITE_NULL)
  615. ae->component = strdupz((char *) sqlite3_column_text(res, 29));
  616. else
  617. ae->component = NULL;
  618. if (sqlite3_column_type(res, 30) != SQLITE_NULL)
  619. ae->type = strdupz((char *) sqlite3_column_text(res, 30));
  620. else
  621. ae->type = NULL;
  622. char value_string[100 + 1];
  623. freez(ae->old_value_string);
  624. freez(ae->new_value_string);
  625. ae->old_value_string = strdupz(format_value_and_unit(value_string, 100, ae->old_value, ae->units, -1));
  626. ae->new_value_string = strdupz(format_value_and_unit(value_string, 100, ae->new_value, ae->units, -1));
  627. ae->next = host->health_log.alarms;
  628. host->health_log.alarms = ae;
  629. if(unlikely(ae->unique_id > host->health_max_unique_id))
  630. host->health_max_unique_id = ae->unique_id;
  631. if(unlikely(ae->alarm_id >= host->health_max_alarm_id))
  632. host->health_max_alarm_id = ae->alarm_id;
  633. loaded++;
  634. }
  635. netdata_rwlock_unlock(&host->health_log.alarm_log_rwlock);
  636. if(!host->health_max_unique_id) host->health_max_unique_id = (uint32_t)now_realtime_sec();
  637. if(!host->health_max_alarm_id) host->health_max_alarm_id = (uint32_t)now_realtime_sec();
  638. host->health_log.next_log_id = host->health_max_unique_id + 1;
  639. if (unlikely(!host->health_log.next_alarm_id || host->health_log.next_alarm_id <= host->health_max_alarm_id))
  640. host->health_log.next_alarm_id = host->health_max_alarm_id + 1;
  641. info("HEALTH [%s]: Table health_log_%s, loaded %zd alarm entries, errors in %zd entries.", host->hostname, uuid_str, loaded, errored);
  642. rc = sqlite3_finalize(res);
  643. if (unlikely(rc != SQLITE_OK))
  644. error_report("Failed to finalize the health log read statement");
  645. sql_health_alarm_log_count(host);
  646. }
  647. /*
  648. * Store an alert config hash in the database
  649. */
  650. #define SQL_STORE_ALERT_CONFIG_HASH "insert or replace into alert_hash (hash_id, date_updated, alarm, template, " \
  651. "on_key, class, component, type, os, hosts, lookup, every, units, calc, families, plugin, module, " \
  652. "charts, green, red, warn, crit, exec, to_key, info, delay, options, repeat, host_labels, " \
  653. "p_db_lookup_dimensions, p_db_lookup_method, p_db_lookup_options, p_db_lookup_after, " \
  654. "p_db_lookup_before, p_update_every) values (?1,strftime('%s'),?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12," \
  655. "?13,?14,?15,?16,?17,?18,?19,?20,?21,?22,?23,?24,?25,?26,?27,?28,?29,?30,?31,?32,?33,?34);"
  656. int sql_store_alert_config_hash(uuid_t *hash_id, struct alert_config *cfg)
  657. {
  658. static __thread sqlite3_stmt *res = NULL;
  659. int rc, param = 0;
  660. if (unlikely(!db_meta)) {
  661. if (default_rrd_memory_mode != RRD_MEMORY_MODE_DBENGINE)
  662. return 0;
  663. error_report("Database has not been initialized");
  664. return 1;
  665. }
  666. if (unlikely(!res)) {
  667. rc = prepare_statement(db_meta, SQL_STORE_ALERT_CONFIG_HASH, &res);
  668. if (unlikely(rc != SQLITE_OK)) {
  669. error_report("Failed to prepare statement to store alert configuration, rc = %d", rc);
  670. return 1;
  671. }
  672. }
  673. param++;
  674. rc = sqlite3_bind_blob(res, 1, hash_id, sizeof(*hash_id), SQLITE_STATIC);
  675. if (unlikely(rc != SQLITE_OK))
  676. goto bind_fail;
  677. param++;
  678. if (cfg->alarm && *cfg->alarm)
  679. rc = sqlite3_bind_text(res, 2, cfg->alarm, -1, SQLITE_STATIC);
  680. else
  681. rc = sqlite3_bind_null(res, 2);
  682. if (unlikely(rc != SQLITE_OK))
  683. goto bind_fail;
  684. param++;
  685. if (cfg->template_key && *cfg->template_key)
  686. rc = sqlite3_bind_text(res, 3, cfg->template_key, -1, SQLITE_STATIC);
  687. else
  688. rc = sqlite3_bind_null(res, 3);
  689. if (unlikely(rc != SQLITE_OK))
  690. goto bind_fail;
  691. param++;
  692. rc = sqlite3_bind_text(res, 4, cfg->on, -1, SQLITE_STATIC);
  693. if (unlikely(rc != SQLITE_OK))
  694. goto bind_fail;
  695. param++;
  696. rc = sqlite3_bind_text(res, 5, cfg->classification, -1, SQLITE_STATIC);
  697. if (unlikely(rc != SQLITE_OK))
  698. goto bind_fail;
  699. param++;
  700. rc = sqlite3_bind_text(res, 6, cfg->component, -1, SQLITE_STATIC);
  701. if (unlikely(rc != SQLITE_OK))
  702. goto bind_fail;
  703. param++;
  704. rc = sqlite3_bind_text(res, 7, cfg->type, -1, SQLITE_STATIC);
  705. if (unlikely(rc != SQLITE_OK))
  706. goto bind_fail;
  707. param++;
  708. rc = sqlite3_bind_text(res, 8, cfg->os, -1, SQLITE_STATIC);
  709. if (unlikely(rc != SQLITE_OK))
  710. goto bind_fail;
  711. param++;
  712. rc = sqlite3_bind_text(res, 9, cfg->host, -1, SQLITE_STATIC);
  713. if (unlikely(rc != SQLITE_OK))
  714. goto bind_fail;
  715. param++;
  716. rc = sqlite3_bind_text(res, 10, cfg->lookup, -1, SQLITE_STATIC);
  717. if (unlikely(rc != SQLITE_OK))
  718. goto bind_fail;
  719. param++;
  720. rc = sqlite3_bind_text(res, 11, cfg->every, -1, SQLITE_STATIC);
  721. if (unlikely(rc != SQLITE_OK))
  722. goto bind_fail;
  723. param++;
  724. rc = sqlite3_bind_text(res, 12, cfg->units, -1, SQLITE_STATIC);
  725. if (unlikely(rc != SQLITE_OK))
  726. goto bind_fail;
  727. param++;
  728. rc = sqlite3_bind_text(res, 13, cfg->calc, -1, SQLITE_STATIC);
  729. if (unlikely(rc != SQLITE_OK))
  730. goto bind_fail;
  731. param++;
  732. rc = sqlite3_bind_text(res, 14, cfg->families, -1, SQLITE_STATIC);
  733. if (unlikely(rc != SQLITE_OK))
  734. goto bind_fail;
  735. param++;
  736. rc = sqlite3_bind_text(res, 15, cfg->plugin, -1, SQLITE_STATIC);
  737. if (unlikely(rc != SQLITE_OK))
  738. goto bind_fail;
  739. param++;
  740. rc = sqlite3_bind_text(res, 16, cfg->module, -1, SQLITE_STATIC);
  741. if (unlikely(rc != SQLITE_OK))
  742. goto bind_fail;
  743. param++;
  744. rc = sqlite3_bind_text(res, 17, cfg->charts, -1, SQLITE_STATIC);
  745. if (unlikely(rc != SQLITE_OK))
  746. goto bind_fail;
  747. param++;
  748. rc = sqlite3_bind_text(res, 18, cfg->green, -1, SQLITE_STATIC);
  749. if (unlikely(rc != SQLITE_OK))
  750. goto bind_fail;
  751. param++;
  752. rc = sqlite3_bind_text(res, 19, cfg->red, -1, SQLITE_STATIC);
  753. if (unlikely(rc != SQLITE_OK))
  754. goto bind_fail;
  755. param++;
  756. rc = sqlite3_bind_text(res, 20, cfg->warn, -1, SQLITE_STATIC);
  757. if (unlikely(rc != SQLITE_OK))
  758. goto bind_fail;
  759. param++;
  760. rc = sqlite3_bind_text(res, 21, cfg->crit, -1, SQLITE_STATIC);
  761. if (unlikely(rc != SQLITE_OK))
  762. goto bind_fail;
  763. param++;
  764. rc = sqlite3_bind_text(res, 22, cfg->exec, -1, SQLITE_STATIC);
  765. if (unlikely(rc != SQLITE_OK))
  766. goto bind_fail;
  767. param++;
  768. rc = sqlite3_bind_text(res, 23, cfg->to, -1, SQLITE_STATIC);
  769. if (unlikely(rc != SQLITE_OK))
  770. goto bind_fail;
  771. param++;
  772. rc = sqlite3_bind_text(res, 24, cfg->info, -1, SQLITE_STATIC);
  773. if (unlikely(rc != SQLITE_OK))
  774. goto bind_fail;
  775. param++;
  776. rc = sqlite3_bind_text(res, 25, cfg->delay, -1, SQLITE_STATIC);
  777. if (unlikely(rc != SQLITE_OK))
  778. goto bind_fail;
  779. param++;
  780. rc = sqlite3_bind_text(res, 26, cfg->options, -1, SQLITE_STATIC);
  781. if (unlikely(rc != SQLITE_OK))
  782. goto bind_fail;
  783. param++;
  784. rc = sqlite3_bind_text(res, 27, cfg->repeat, -1, SQLITE_STATIC);
  785. if (unlikely(rc != SQLITE_OK))
  786. goto bind_fail;
  787. param++;
  788. rc = sqlite3_bind_text(res, 28, cfg->host_labels, -1, SQLITE_STATIC);
  789. if (unlikely(rc != SQLITE_OK))
  790. goto bind_fail;
  791. if (cfg->p_db_lookup_after) {
  792. param++;
  793. rc = sqlite3_bind_text(res, 29, cfg->p_db_lookup_dimensions, -1, SQLITE_STATIC);
  794. if (unlikely(rc != SQLITE_OK))
  795. goto bind_fail;
  796. param++;
  797. rc = sqlite3_bind_text(res, 30, cfg->p_db_lookup_method, -1, SQLITE_STATIC);
  798. if (unlikely(rc != SQLITE_OK))
  799. goto bind_fail;
  800. param++;
  801. rc = sqlite3_bind_int(res, 31, cfg->p_db_lookup_options);
  802. if (unlikely(rc != SQLITE_OK))
  803. goto bind_fail;
  804. param++;
  805. rc = sqlite3_bind_int(res, 32, cfg->p_db_lookup_after);
  806. if (unlikely(rc != SQLITE_OK))
  807. goto bind_fail;
  808. param++;
  809. rc = sqlite3_bind_int(res, 33, cfg->p_db_lookup_before);
  810. if (unlikely(rc != SQLITE_OK))
  811. goto bind_fail;
  812. } else {
  813. param++;
  814. rc = sqlite3_bind_null(res, 29);
  815. if (unlikely(rc != SQLITE_OK))
  816. goto bind_fail;
  817. param++;
  818. rc = sqlite3_bind_null(res, 30);
  819. if (unlikely(rc != SQLITE_OK))
  820. goto bind_fail;
  821. param++;
  822. rc = sqlite3_bind_null(res, 31);
  823. if (unlikely(rc != SQLITE_OK))
  824. goto bind_fail;
  825. param++;
  826. rc = sqlite3_bind_null(res, 32);
  827. if (unlikely(rc != SQLITE_OK))
  828. goto bind_fail;
  829. param++;
  830. rc = sqlite3_bind_null(res, 33);
  831. if (unlikely(rc != SQLITE_OK))
  832. goto bind_fail;
  833. }
  834. param++;
  835. rc = sqlite3_bind_int(res, 34, cfg->p_update_every);
  836. if (unlikely(rc != SQLITE_OK))
  837. goto bind_fail;
  838. rc = execute_insert(res);
  839. if (unlikely(rc != SQLITE_DONE))
  840. error_report("Failed to store alert config, rc = %d", rc);
  841. rc = sqlite3_reset(res);
  842. if (unlikely(rc != SQLITE_OK))
  843. error_report("Failed to reset statement in alert hash_id store function, rc = %d", rc);
  844. return 0;
  845. bind_fail:
  846. error_report("Failed to bind parameter %d to store alert hash_id, rc = %d", param, rc);
  847. rc = sqlite3_reset(res);
  848. if (unlikely(rc != SQLITE_OK))
  849. error_report("Failed to reset statement in alert hash_id store function, rc = %d", rc);
  850. return 1;
  851. }
  852. /*
  853. alert hashes are used for cloud communication.
  854. if cloud is disabled or openssl is not available (which will prevent cloud connectivity)
  855. skip hash calculations
  856. */
  857. #if !defined DISABLE_CLOUD && defined ENABLE_HTTPS
  858. #define DIGEST_ALERT_CONFIG_VAL(v) ((v) ? EVP_DigestUpdate(evpctx, (v), strlen((v))) : EVP_DigestUpdate(evpctx, "", 1))
  859. #endif
  860. int alert_hash_and_store_config(
  861. uuid_t hash_id,
  862. struct alert_config *cfg,
  863. int store_hash)
  864. {
  865. #if !defined DISABLE_CLOUD && defined ENABLE_HTTPS
  866. EVP_MD_CTX *evpctx;
  867. unsigned char hash_value[EVP_MAX_MD_SIZE];
  868. unsigned int hash_len;
  869. evpctx = EVP_MD_CTX_create();
  870. EVP_DigestInit_ex(evpctx, EVP_sha256(), NULL);
  871. DIGEST_ALERT_CONFIG_VAL(cfg->alarm);
  872. DIGEST_ALERT_CONFIG_VAL(cfg->template_key);
  873. DIGEST_ALERT_CONFIG_VAL(cfg->os);
  874. DIGEST_ALERT_CONFIG_VAL(cfg->host);
  875. DIGEST_ALERT_CONFIG_VAL(cfg->on);
  876. DIGEST_ALERT_CONFIG_VAL(cfg->families);
  877. DIGEST_ALERT_CONFIG_VAL(cfg->plugin);
  878. DIGEST_ALERT_CONFIG_VAL(cfg->module);
  879. DIGEST_ALERT_CONFIG_VAL(cfg->charts);
  880. DIGEST_ALERT_CONFIG_VAL(cfg->lookup);
  881. DIGEST_ALERT_CONFIG_VAL(cfg->calc);
  882. DIGEST_ALERT_CONFIG_VAL(cfg->every);
  883. DIGEST_ALERT_CONFIG_VAL(cfg->green);
  884. DIGEST_ALERT_CONFIG_VAL(cfg->red);
  885. DIGEST_ALERT_CONFIG_VAL(cfg->warn);
  886. DIGEST_ALERT_CONFIG_VAL(cfg->crit);
  887. DIGEST_ALERT_CONFIG_VAL(cfg->exec);
  888. DIGEST_ALERT_CONFIG_VAL(cfg->to);
  889. DIGEST_ALERT_CONFIG_VAL(cfg->units);
  890. DIGEST_ALERT_CONFIG_VAL(cfg->info);
  891. DIGEST_ALERT_CONFIG_VAL(cfg->classification);
  892. DIGEST_ALERT_CONFIG_VAL(cfg->component);
  893. DIGEST_ALERT_CONFIG_VAL(cfg->type);
  894. DIGEST_ALERT_CONFIG_VAL(cfg->delay);
  895. DIGEST_ALERT_CONFIG_VAL(cfg->options);
  896. DIGEST_ALERT_CONFIG_VAL(cfg->repeat);
  897. DIGEST_ALERT_CONFIG_VAL(cfg->host_labels);
  898. EVP_DigestFinal_ex(evpctx, hash_value, &hash_len);
  899. EVP_MD_CTX_destroy(evpctx);
  900. fatal_assert(hash_len > sizeof(uuid_t));
  901. char uuid_str[GUID_LEN + 1];
  902. uuid_unparse_lower(*((uuid_t *)&hash_value), uuid_str);
  903. uuid_copy(hash_id, *((uuid_t *)&hash_value));
  904. /* store everything, so it can be recreated when not in memory or just a subset ? */
  905. if (store_hash)
  906. (void)sql_store_alert_config_hash( (uuid_t *)&hash_value, cfg);
  907. #else
  908. UNUSED(hash_id);
  909. UNUSED(cfg);
  910. UNUSED(store_hash);
  911. #endif
  912. return 1;
  913. }