health.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "health.h"
  3. SILENCERS *silencers;
  4. /**
  5. * Create Silencer
  6. *
  7. * Allocate a new silencer to Netdata.
  8. *
  9. * @return It returns the address off the silencer on success and NULL otherwise
  10. */
  11. SILENCER *create_silencer(void) {
  12. SILENCER *t = callocz(1, sizeof(SILENCER));
  13. netdata_log_debug(D_HEALTH, "HEALTH command API: Created empty silencer");
  14. return t;
  15. }
  16. /**
  17. * Health Silencers add
  18. *
  19. * Add more one silencer to the list of silencers.
  20. *
  21. * @param silencer
  22. */
  23. void health_silencers_add(SILENCER *silencer) {
  24. // Add the created instance to the linked list in silencers
  25. silencer->next = silencers->silencers;
  26. silencers->silencers = silencer;
  27. netdata_log_debug(D_HEALTH, "HEALTH command API: Added silencer %s:%s:%s:%s", silencer->alarms,
  28. silencer->charts, silencer->contexts, silencer->hosts
  29. );
  30. }
  31. /**
  32. * Silencers Add Parameter
  33. *
  34. * Create a new silencer and adjust the variables
  35. *
  36. * @param silencer a pointer to the silencer that will be adjusted
  37. * @param key the key value sent by client
  38. * @param value the value sent to the key
  39. *
  40. * @return It returns the silencer configured on success and NULL otherwise
  41. */
  42. SILENCER *health_silencers_addparam(SILENCER *silencer, char *key, char *value) {
  43. static uint32_t
  44. hash_alarm = 0,
  45. hash_template = 0,
  46. hash_chart = 0,
  47. hash_context = 0,
  48. hash_host = 0;
  49. if (unlikely(!hash_alarm)) {
  50. hash_alarm = simple_uhash(HEALTH_ALARM_KEY);
  51. hash_template = simple_uhash(HEALTH_TEMPLATE_KEY);
  52. hash_chart = simple_uhash(HEALTH_CHART_KEY);
  53. hash_context = simple_uhash(HEALTH_CONTEXT_KEY);
  54. hash_host = simple_uhash(HEALTH_HOST_KEY);
  55. }
  56. uint32_t hash = simple_uhash(key);
  57. if (unlikely(silencer == NULL)) {
  58. if (
  59. (hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) ||
  60. (hash == hash_template && !strcasecmp(key, HEALTH_TEMPLATE_KEY)) ||
  61. (hash == hash_chart && !strcasecmp(key, HEALTH_CHART_KEY)) ||
  62. (hash == hash_context && !strcasecmp(key, HEALTH_CONTEXT_KEY)) ||
  63. (hash == hash_host && !strcasecmp(key, HEALTH_HOST_KEY))
  64. ) {
  65. silencer = create_silencer();
  66. if(!silencer) {
  67. netdata_log_error("Cannot add a new silencer to Netdata");
  68. return NULL;
  69. }
  70. }
  71. }
  72. if (hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) {
  73. silencer->alarms = strdupz(value);
  74. silencer->alarms_pattern = simple_pattern_create(silencer->alarms, NULL, SIMPLE_PATTERN_EXACT, true);
  75. } else if (hash == hash_chart && !strcasecmp(key, HEALTH_CHART_KEY)) {
  76. silencer->charts = strdupz(value);
  77. silencer->charts_pattern = simple_pattern_create(silencer->charts, NULL, SIMPLE_PATTERN_EXACT, true);
  78. } else if (hash == hash_context && !strcasecmp(key, HEALTH_CONTEXT_KEY)) {
  79. silencer->contexts = strdupz(value);
  80. silencer->contexts_pattern = simple_pattern_create(silencer->contexts, NULL, SIMPLE_PATTERN_EXACT, true);
  81. } else if (hash == hash_host && !strcasecmp(key, HEALTH_HOST_KEY)) {
  82. silencer->hosts = strdupz(value);
  83. silencer->hosts_pattern = simple_pattern_create(silencer->hosts, NULL, SIMPLE_PATTERN_EXACT, true);
  84. }
  85. return silencer;
  86. }
  87. /**
  88. * JSON Read Callback
  89. *
  90. * Callback called by netdata to create the silencer.
  91. *
  92. * @param e the main json structure
  93. *
  94. * @return It always return 0.
  95. */
  96. int health_silencers_json_read_callback(JSON_ENTRY *e)
  97. {
  98. switch(e->type) {
  99. case JSON_OBJECT:
  100. #ifndef ENABLE_JSONC
  101. e->callback_function = health_silencers_json_read_callback;
  102. if(strcmp(e->name,"")) {
  103. // init silencer
  104. netdata_log_debug(D_HEALTH, "JSON: Got object with a name, initializing new silencer for %s",e->name);
  105. #endif
  106. e->callback_data = create_silencer();
  107. if(e->callback_data) {
  108. health_silencers_add(e->callback_data);
  109. }
  110. #ifndef ENABLE_JSONC
  111. }
  112. #endif
  113. break;
  114. case JSON_ARRAY:
  115. e->callback_function = health_silencers_json_read_callback;
  116. break;
  117. case JSON_STRING:
  118. if(!strcmp(e->name,"type")) {
  119. netdata_log_debug(D_HEALTH, "JSON: Processing type=%s",e->data.string);
  120. if (!strcmp(e->data.string,"SILENCE")) silencers->stype = STYPE_SILENCE_NOTIFICATIONS;
  121. else if (!strcmp(e->data.string,"DISABLE")) silencers->stype = STYPE_DISABLE_ALARMS;
  122. } else {
  123. netdata_log_debug(D_HEALTH, "JSON: Adding %s=%s", e->name, e->data.string);
  124. if (e->callback_data)
  125. (void)health_silencers_addparam(e->callback_data, e->name, e->data.string);
  126. }
  127. break;
  128. case JSON_BOOLEAN:
  129. netdata_log_debug(D_HEALTH, "JSON: Processing all_alarms");
  130. silencers->all_alarms=e->data.boolean?1:0;
  131. break;
  132. case JSON_NUMBER:
  133. case JSON_NULL:
  134. break;
  135. }
  136. return 0;
  137. }
  138. /**
  139. * Initialize Global Silencers
  140. *
  141. * Initialize the silencer for the whole netdata system.
  142. *
  143. * @return It returns 0 on success and -1 otherwise
  144. */
  145. int health_initialize_global_silencers() {
  146. silencers = mallocz(sizeof(SILENCERS));
  147. silencers->all_alarms=0;
  148. silencers->stype=STYPE_NONE;
  149. silencers->silencers=NULL;
  150. return 0;
  151. }