rrdsetvar.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #define NETDATA_HEALTH_INTERNALS
  3. #include "rrd.h"
  4. // ----------------------------------------------------------------------------
  5. // RRDSETVAR management
  6. // CHART VARIABLES
  7. static inline void rrdsetvar_free_variables(RRDSETVAR *rs) {
  8. RRDSET *st = rs->rrdset;
  9. RRDHOST *host = st->rrdhost;
  10. // ------------------------------------------------------------------------
  11. // CHART
  12. rrdvar_free(host, &st->rrdvar_root_index, rs->var_local);
  13. rs->var_local = NULL;
  14. // ------------------------------------------------------------------------
  15. // FAMILY
  16. rrdvar_free(host, &st->rrdfamily->rrdvar_root_index, rs->var_family);
  17. rs->var_family = NULL;
  18. rrdvar_free(host, &st->rrdfamily->rrdvar_root_index, rs->var_family_name);
  19. rs->var_family_name = NULL;
  20. // ------------------------------------------------------------------------
  21. // HOST
  22. rrdvar_free(host, &host->rrdvar_root_index, rs->var_host);
  23. rs->var_host = NULL;
  24. rrdvar_free(host, &host->rrdvar_root_index, rs->var_host_name);
  25. rs->var_host_name = NULL;
  26. // ------------------------------------------------------------------------
  27. // KEYS
  28. freez(rs->key_fullid);
  29. rs->key_fullid = NULL;
  30. freez(rs->key_fullname);
  31. rs->key_fullname = NULL;
  32. }
  33. static inline void rrdsetvar_create_variables(RRDSETVAR *rs) {
  34. RRDSET *st = rs->rrdset;
  35. RRDHOST *host = st->rrdhost;
  36. RRDVAR_OPTIONS options = rs->options;
  37. if(rs->options & RRDVAR_OPTION_ALLOCATED)
  38. options &= ~ RRDVAR_OPTION_ALLOCATED;
  39. // ------------------------------------------------------------------------
  40. // free the old ones (if any)
  41. rrdsetvar_free_variables(rs);
  42. // ------------------------------------------------------------------------
  43. // KEYS
  44. char buffer[RRDVAR_MAX_LENGTH + 1];
  45. snprintfz(buffer, RRDVAR_MAX_LENGTH, "%s.%s", st->id, rs->variable);
  46. rs->key_fullid = strdupz(buffer);
  47. snprintfz(buffer, RRDVAR_MAX_LENGTH, "%s.%s", st->name, rs->variable);
  48. rs->key_fullname = strdupz(buffer);
  49. // ------------------------------------------------------------------------
  50. // CHART
  51. rs->var_local = rrdvar_create_and_index("local", &st->rrdvar_root_index, rs->variable, rs->type, options, rs->value);
  52. // ------------------------------------------------------------------------
  53. // FAMILY
  54. rs->var_family = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_fullid, rs->type, options, rs->value);
  55. rs->var_family_name = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_fullname, rs->type, options, rs->value);
  56. // ------------------------------------------------------------------------
  57. // HOST
  58. rs->var_host = rrdvar_create_and_index("host", &host->rrdvar_root_index, rs->key_fullid, rs->type, options, rs->value);
  59. rs->var_host_name = rrdvar_create_and_index("host", &host->rrdvar_root_index, rs->key_fullname, rs->type, options, rs->value);
  60. }
  61. RRDSETVAR *rrdsetvar_create(RRDSET *st, const char *variable, RRDVAR_TYPE type, void *value, RRDVAR_OPTIONS options) {
  62. debug(D_VARIABLES, "RRDVARSET create for chart id '%s' name '%s' with variable name '%s'", st->id, st->name, variable);
  63. RRDSETVAR *rs = (RRDSETVAR *)callocz(1, sizeof(RRDSETVAR));
  64. rs->variable = strdupz(variable);
  65. rs->hash = simple_hash(rs->variable);
  66. rs->type = type;
  67. rs->value = value;
  68. rs->options = options;
  69. rs->rrdset = st;
  70. rs->next = st->variables;
  71. st->variables = rs;
  72. rrdsetvar_create_variables(rs);
  73. return rs;
  74. }
  75. void rrdsetvar_rename_all(RRDSET *st) {
  76. debug(D_VARIABLES, "RRDSETVAR rename for chart id '%s' name '%s'", st->id, st->name);
  77. RRDSETVAR *rs;
  78. for(rs = st->variables; rs ; rs = rs->next)
  79. rrdsetvar_create_variables(rs);
  80. rrdsetcalc_link_matching(st);
  81. }
  82. void rrdsetvar_free(RRDSETVAR *rs) {
  83. RRDSET *st = rs->rrdset;
  84. debug(D_VARIABLES, "RRDSETVAR free for chart id '%s' name '%s', variable '%s'", st->id, st->name, rs->variable);
  85. if(st->variables == rs) {
  86. st->variables = rs->next;
  87. }
  88. else {
  89. RRDSETVAR *t;
  90. for (t = st->variables; t && t->next != rs; t = t->next);
  91. if(!t) error("RRDSETVAR '%s' not found in chart '%s' variables linked list", rs->key_fullname, st->id);
  92. else t->next = rs->next;
  93. }
  94. rrdsetvar_free_variables(rs);
  95. freez(rs->variable);
  96. if(rs->options & RRDVAR_OPTION_ALLOCATED)
  97. freez(rs->value);
  98. freez(rs);
  99. }
  100. // --------------------------------------------------------------------------------------------------------------------
  101. // custom chart variables
  102. RRDSETVAR *rrdsetvar_custom_chart_variable_create(RRDSET *st, const char *name) {
  103. RRDHOST *host = st->rrdhost;
  104. char *n = strdupz(name);
  105. rrdvar_fix_name(n);
  106. uint32_t hash = simple_hash(n);
  107. rrdset_wrlock(st);
  108. // find it
  109. RRDSETVAR *rs;
  110. for(rs = st->variables; rs ; rs = rs->next) {
  111. if(hash == rs->hash && strcmp(n, rs->variable) == 0) {
  112. rrdset_unlock(st);
  113. if(rs->options & RRDVAR_OPTION_CUSTOM_CHART_VAR) {
  114. freez(n);
  115. return rs;
  116. }
  117. else {
  118. error("RRDSETVAR: custom variable '%s' on chart '%s' of host '%s', conflicts with an internal chart variable", n, st->id, host->hostname);
  119. freez(n);
  120. return NULL;
  121. }
  122. }
  123. }
  124. // not found, allocate one
  125. NETDATA_DOUBLE *v = mallocz(sizeof(NETDATA_DOUBLE));
  126. *v = NAN;
  127. rs = rrdsetvar_create(st, n, RRDVAR_TYPE_CALCULATED, v, RRDVAR_OPTION_ALLOCATED|RRDVAR_OPTION_CUSTOM_CHART_VAR);
  128. rrdset_unlock(st);
  129. freez(n);
  130. return rs;
  131. }
  132. void rrdsetvar_custom_chart_variable_set(RRDSETVAR *rs, NETDATA_DOUBLE value) {
  133. if(rs->type != RRDVAR_TYPE_CALCULATED || !(rs->options & RRDVAR_OPTION_CUSTOM_CHART_VAR) || !(rs->options & RRDVAR_OPTION_ALLOCATED)) {
  134. error("RRDSETVAR: requested to set variable '%s' of chart '%s' on host '%s' to value " NETDATA_DOUBLE_FORMAT
  135. " but the variable is not a custom chart one.", rs->variable, rs->rrdset->id, rs->rrdset->rrdhost->hostname, value);
  136. }
  137. else {
  138. NETDATA_DOUBLE *v = rs->value;
  139. if(*v != value) {
  140. *v = value;
  141. // mark the chart to be sent upstream
  142. rrdset_flag_clear(rs->rrdset, RRDSET_FLAG_UPSTREAM_EXPOSED);
  143. }
  144. }
  145. }