@cryptotaxi247 / netdata-1 / commits / 6050f6170

support chart custom variables at the API and streaming; fixes #2884

Costa Tsaousis (ktsaou) committed Oct 17, 2017 at 01:30 UTC 6050f617090485a3492d584a665eae8ad1e3c34f
10 files changed +135 -111
src/health.h
+8 -5
@@ -16,9 +16,9 @@ typedef enum rrdvar_type {
16
17 // the variables as stored in the variables indexes
18 // there are 3 indexes:
19 -// 1. at each chart (RRDSET.variables_root_index)
20 -// 2. at each context (RRDFAMILY.variables_root_index)
21 -// 3. at each host (RRDHOST.variables_root_index)
19 +// 1. at each chart (RRDSET.rrdvar_root_index)
20 +// 2. at each context (RRDFAMILY.rrdvar_root_index)
21 +// 3. at each host (RRDHOST.rrdvar_root_index)
22 typedef struct rrdvar {
23 avl avl;
24
@@ -363,9 +363,12 @@ extern void health_alarm_log2json(RRDHOST *host, BUFFER *wb, uint32_t after);
363 void health_api_v1_chart_variables2json(RRDSET *st, BUFFER *buf);
364
365 extern RRDVAR *rrdvar_custom_host_variable_create(RRDHOST *host, const char *name);
366 -extern void rrdvar_custom_host_variable_destroy(RRDHOST *host, const char *name);
366 extern void rrdvar_custom_host_variable_set(RRDHOST *host, RRDVAR *rv, calculated_number value);
368 -extern void rrdvar_free_remaining_variables(RRDHOST *host);
367 +
368 +extern RRDVAR *rrdvar_custom_chart_variable_create(RRDSET *st, const char *name);
369 +extern void rrdvar_custom_chart_variable_set(RRDSET *st, RRDVAR *rv, calculated_number value);
370 +
371 +extern void rrdvar_free_remaining_variables(RRDHOST *host, avl_tree_lock *tree_lock);
372
373 extern const char *rrdcalc_status2string(RRDCALC_STATUS status);
374
src/plugins_d.c
+28 -5
@@ -375,6 +375,7 @@ inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int
375 else if(likely(hash == VARIABLE_HASH && !strcmp(s, PLUGINSD_KEYWORD_VARIABLE))) {
376 char *name = words[1];
377 char *value = words[2];
378 + int global = (st)?0:1;
379
380 if(unlikely(!name || !*name)) {
381 error("PLUGINSD: '%s' is requesting a VARIABLE on host '%s', without a variable name. Disabling it.", cd->fullfilename, host->hostname);
@@ -382,16 +383,38 @@ inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int
383 break;
384 }
385
385 - if(unlikely(!value || !*value)) value = NULL;
386 + if(value && *value) {
387 + if((strcmp(value, "GLOBAL") == 0 || strcmp(value, "HOST") == 0)) {
388 + global = 1;
389 + value = words[3];
390 + }
391 + else if((strcmp(value, "LOCAL") == 0 || strcmp(value, "CHART") == 0)) {
392 + global = 0;
393 + value = words[3];
394 + }
395 + }
396 +
397 + if(unlikely(!value || !*value))
398 + value = NULL;
399
400 if(value) {
401 calculated_number v = (calculated_number)str2ld(value, NULL);
389 - RRDVAR *rv = rrdvar_custom_host_variable_create(host, name);
390 - if(rv)
391 - rrdvar_custom_host_variable_set(host, rv, v);
402 +
403 + if(global) {
404 + RRDVAR *rv = rrdvar_custom_host_variable_create(host, name);
405 + if (rv) rrdvar_custom_host_variable_set(host, rv, v);
406 + else error("PLUGINSD: '%s': cannot find/create HOST VARIABLE '%s' on host '%s'", cd->fullfilename, name, host->hostname);
407 + }
408 + else if(st) {
409 + RRDVAR *rv = rrdvar_custom_chart_variable_create(st, name);
410 + if (rv) rrdvar_custom_chart_variable_set(st, rv, v);
411 + else error("PLUGINSD: '%s': cannot find/create CHART VARIABLE '%s' on host '%s', chart '%s'", cd->fullfilename, name, host->hostname, st->id);
412 + }
413 else
393 - error("PLUGINSD: '%s': cannot find/create VARIABLE '%s' on host '%s'", cd->fullfilename, name, host->hostname);
414 + error("PLUGINSD: '%s': cannot find/create CHART VARIABLE '%s' on host '%s' without a chart", cd->fullfilename, name, host->hostname);
415 }
416 + else
417 + error("PLUGINSD: '%s': cannot set %s VARIABLE '%s' on host '%s' to an empty value", cd->fullfilename, (global)?"HOST":"CHART", name, host->hostname);
418 }
419 else if(likely(hash == FLUSH_HASH && !strcmp(s, PLUGINSD_KEYWORD_FLUSH))) {
420 debug(D_PLUGINSD, "PLUGINSD: '%s' is requesting a FLUSH", cd->fullfilename);
src/rrd.h
+12 -12
@@ -87,7 +87,7 @@ struct rrdfamily {
87
88 size_t use_count;
89
90 - avl_tree_lock variables_root_index;
90 + avl_tree_lock rrdvar_root_index;
91 };
92 typedef struct rrdfamily RRDFAMILY;
93
@@ -266,9 +266,9 @@ struct rrdset {
266 char *units; // units of measurement
267
268 char *context; // the template of this data set
269 - uint32_t hash_context;
269 + uint32_t hash_context; // the hash of the chart's context
270
271 - RRDSET_TYPE chart_type;
271 + RRDSET_TYPE chart_type; // line, area, stacked
272
273 int update_every; // every how many seconds is this updated?
274
@@ -282,7 +282,7 @@ struct rrdset {
282 int gap_when_lost_iterations_above; // after how many lost iterations a gap should be stored
283 // netdata will interpolate values for gaps lower than this
284
285 - long priority;
285 + long priority; // the sorting priority of this chart
286
287
288 // ------------------------------------------------------------------------
@@ -319,20 +319,20 @@ struct rrdset {
319 total_number collected_total; // used internally to calculate percentages
320 total_number last_collected_total; // used internally to calculate percentages
321
322 - RRDFAMILY *rrdfamily;
323 - struct rrdhost *rrdhost;
322 + RRDFAMILY *rrdfamily; // pointer to RRDFAMILY this chart belongs to
323 + struct rrdhost *rrdhost; // pointer to RRDHOST this chart belongs to
324
325 struct rrdset *next; // linking of rrdsets
326
327 // ------------------------------------------------------------------------
328 // local variables
329
330 - calculated_number green;
331 - calculated_number red;
330 + calculated_number green; // green threshold for this chart
331 + calculated_number red; // red threshold for this chart
332
333 - avl_tree_lock variables_root_index;
334 - RRDSETVAR *variables;
335 - RRDCALC *alarms;
333 + avl_tree_lock rrdvar_root_index; // RRDVAR index for this chart
334 + RRDSETVAR *variables; // RRDSETVAR linked list for this chart (one RRDSETVAR, many RRDVARs)
335 + RRDCALC *alarms; // RRDCALC linked list for this chart
336
337 // ------------------------------------------------------------------------
338 // members for checking the data when loading from disk
@@ -504,7 +504,7 @@ struct rrdhost {
504 avl_tree_lock rrdset_root_index_name; // the host's charts index (by name)
505
506 avl_tree_lock rrdfamily_root_index; // the host's chart families index
507 - avl_tree_lock variables_root_index; // the host's chart variables index
507 + avl_tree_lock rrdvar_root_index; // the host's chart variables index
508
509 struct rrdhost *next;
510 };
src/rrdcalc.c
+8 -8
@@ -62,15 +62,15 @@ static void rrdsetcalc_link(RRDSET *st, RRDCALC *rc) {
62 st->red = rc->red;
63 }
64
65 - rc->local = rrdvar_create_and_index("local", &st->variables_root_index, rc->name, RRDVAR_TYPE_CALCULATED, &rc->value);
66 - rc->family = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rc->name, RRDVAR_TYPE_CALCULATED, &rc->value);
65 + rc->local = rrdvar_create_and_index("local", &st->rrdvar_root_index, rc->name, RRDVAR_TYPE_CALCULATED, &rc->value);
66 + rc->family = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rc->name, RRDVAR_TYPE_CALCULATED, &rc->value);
67
68 char fullname[RRDVAR_MAX_LENGTH + 1];
69 snprintfz(fullname, RRDVAR_MAX_LENGTH, "%s.%s", st->id, rc->name);
70 - rc->hostid = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, fullname, RRDVAR_TYPE_CALCULATED, &rc->value);
70 + rc->hostid = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, fullname, RRDVAR_TYPE_CALCULATED, &rc->value);
71
72 snprintfz(fullname, RRDVAR_MAX_LENGTH, "%s.%s", st->name, rc->name);
73 - rc->hostname = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, fullname, RRDVAR_TYPE_CALCULATED, &rc->value);
73 + rc->hostname = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, fullname, RRDVAR_TYPE_CALCULATED, &rc->value);
74
75 if(!rc->units) rc->units = strdupz(st->units);
76
@@ -173,16 +173,16 @@ inline void rrdsetcalc_unlink(RRDCALC *rc) {
173
174 rc->rrdset_prev = rc->rrdset_next = NULL;
175
176 - rrdvar_free(st->rrdhost, &st->variables_root_index, rc->local);
176 + rrdvar_free(st->rrdhost, &st->rrdvar_root_index, rc->local);
177 rc->local = NULL;
178
179 - rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rc->family);
179 + rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rc->family);
180 rc->family = NULL;
181
182 - rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rc->hostid);
182 + rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rc->hostid);
183 rc->hostid = NULL;
184
185 - rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rc->hostname);
185 + rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rc->hostname);
186 rc->hostname = NULL;
187
188 rc->rrdset = NULL;
src/rrddimvar.c
+20 -20
@@ -13,38 +13,38 @@ static inline void rrddimvar_free_variables(RRDDIMVAR *rs) {
13
14 // CHART VARIABLES FOR THIS DIMENSION
15
16 - rrdvar_free(st->rrdhost, &st->variables_root_index, rs->var_local_id);
16 + rrdvar_free(st->rrdhost, &st->rrdvar_root_index, rs->var_local_id);
17 rs->var_local_id = NULL;
18
19 - rrdvar_free(st->rrdhost, &st->variables_root_index, rs->var_local_name);
19 + rrdvar_free(st->rrdhost, &st->rrdvar_root_index, rs->var_local_name);
20 rs->var_local_name = NULL;
21
22 // FAMILY VARIABLES FOR THIS DIMENSION
23
24 - rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rs->var_family_id);
24 + rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family_id);
25 rs->var_family_id = NULL;
26
27 - rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rs->var_family_name);
27 + rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family_name);
28 rs->var_family_name = NULL;
29
30 - rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rs->var_family_contextid);
30 + rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family_contextid);
31 rs->var_family_contextid = NULL;
32
33 - rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rs->var_family_contextname);
33 + rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family_contextname);
34 rs->var_family_contextname = NULL;
35
36 // HOST VARIABLES FOR THIS DIMENSION
37
38 - rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rs->var_host_chartidid);
38 + rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host_chartidid);
39 rs->var_host_chartidid = NULL;
40
41 - rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rs->var_host_chartidname);
41 + rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host_chartidname);
42 rs->var_host_chartidname = NULL;
43
44 - rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rs->var_host_chartnameid);
44 + rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host_chartnameid);
45 rs->var_host_chartnameid = NULL;
46
47 - rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rs->var_host_chartnamename);
47 + rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host_chartnamename);
48 rs->var_host_chartnamename = NULL;
49
50 // KEYS
@@ -115,8 +115,8 @@ static inline void rrddimvar_create_variables(RRDDIMVAR *rs) {
115 // - $id
116 // - $name
117
118 - rs->var_local_id = rrdvar_create_and_index("local", &st->variables_root_index, rs->key_id, rs->type, rs->value);
119 - rs->var_local_name = rrdvar_create_and_index("local", &st->variables_root_index, rs->key_name, rs->type, rs->value);
118 + rs->var_local_id = rrdvar_create_and_index("local", &st->rrdvar_root_index, rs->key_id, rs->type, rs->value);
119 + rs->var_local_name = rrdvar_create_and_index("local", &st->rrdvar_root_index, rs->key_name, rs->type, rs->value);
120
121 // FAMILY VARIABLES FOR THIS DIMENSION
122 // -----------------------------------
@@ -127,10 +127,10 @@ static inline void rrddimvar_create_variables(RRDDIMVAR *rs) {
127 // - $chart-context.id
128 // - $chart-context.name
129
130 - rs->var_family_id = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rs->key_id, rs->type, rs->value);
131 - rs->var_family_name = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rs->key_name, rs->type, rs->value);
132 - rs->var_family_contextid = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rs->key_contextid, rs->type, rs->value);
133 - rs->var_family_contextname = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rs->key_contextname, rs->type, rs->value);
130 + rs->var_family_id = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_id, rs->type, rs->value);
131 + rs->var_family_name = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_name, rs->type, rs->value);
132 + rs->var_family_contextid = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_contextid, rs->type, rs->value);
133 + rs->var_family_contextname = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_contextname, rs->type, rs->value);
134
135 // HOST VARIABLES FOR THIS DIMENSION
136 // -----------------------------------
@@ -141,10 +141,10 @@ static inline void rrddimvar_create_variables(RRDDIMVAR *rs) {
141 // - $chart-name.id
142 // - $chart-name.name
143
144 - rs->var_host_chartidid = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->key_fullidid, rs->type, rs->value);
145 - rs->var_host_chartidname = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->key_fullidname, rs->type, rs->value);
146 - rs->var_host_chartnameid = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->key_fullnameid, rs->type, rs->value);
147 - rs->var_host_chartnamename = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->key_fullnamename, rs->type, rs->value);
144 + rs->var_host_chartidid = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullidid, rs->type, rs->value);
145 + rs->var_host_chartidname = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullidname, rs->type, rs->value);
146 + rs->var_host_chartnameid = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullnameid, rs->type, rs->value);
147 + rs->var_host_chartnamename = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullnamename, rs->type, rs->value);
148 }
149
150 RRDDIMVAR *rrddimvar_create(RRDDIM *rd, RRDVAR_TYPE type, const char *prefix, const char *suffix, void *value, RRDVAR_OPTIONS options) {
src/rrdfamily.c
+2 -2
@@ -30,7 +30,7 @@ RRDFAMILY *rrdfamily_create(RRDHOST *host, const char *id) {
30 rc->hash_family = simple_hash(rc->family);
31
32 // initialize the variables index
33 - avl_init_lock(&rc->variables_root_index, rrdvar_compare);
33 + avl_init_lock(&rc->rrdvar_root_index, rrdvar_compare);
34
35 RRDFAMILY *ret = rrdfamily_index_add(host, rc);
36 if(ret != rc)
@@ -48,7 +48,7 @@ void rrdfamily_free(RRDHOST *host, RRDFAMILY *rc) {
48 if(ret != rc)
49 fatal("RRDFAMILY: INTERNAL ERROR: Expected to DELETE RRDFAMILY '%s' from index, but deleted '%s'.", rc->family, (ret)?ret->family:"NONE");
50
51 - if(rc->variables_root_index.avl_tree.root != NULL)
51 + if(rc->rrdvar_root_index.avl_tree.root != NULL)
52 fatal("RRDFAMILY: INTERNAL ERROR: Variables index of RRDFAMILY '%s' that is freed, is not empty.", rc->family);
53
54 freez((void *)rc->family);
src/rrdhost.c
+2 -2
@@ -151,7 +151,7 @@ RRDHOST *rrdhost_create(const char *hostname,
151 avl_init_lock(&(host->rrdset_root_index), rrdset_compare);
152 avl_init_lock(&(host->rrdset_root_index_name), rrdset_compare_name);
153 avl_init_lock(&(host->rrdfamily_root_index), rrdfamily_compare);
154 - avl_init_lock(&(host->variables_root_index), rrdvar_compare);
154 + avl_init_lock(&(host->rrdvar_root_index), rrdvar_compare);
155
156 if(config_get_boolean(CONFIG_SECTION_GLOBAL, "delete obsolete charts files", 1))
157 rrdhost_flag_set(host, RRDHOST_FLAG_DELETE_OBSOLETE_CHARTS);
@@ -496,7 +496,7 @@ void rrdhost_free(RRDHOST *host) {
496 while(host->templates)
497 rrdcalctemplate_unlink_and_free(host, host->templates);
498
499 - rrdvar_free_remaining_variables(host);
499 + rrdvar_free_remaining_variables(host, &host->rrdvar_root_index);
500
501 health_alarm_log_free(host);
502
src/rrdset.c
+4 -2
@@ -316,6 +316,8 @@ void rrdset_free(RRDSET *st) {
316
317 rrdfamily_free(st->rrdhost, st->rrdfamily);
318
319 + rrdvar_free_remaining_variables(st->rrdhost, &st->rrdvar_root_index);
320 +
321 // ------------------------------------------------------------------------
322 // unlink it from the host
323
@@ -506,7 +508,7 @@ RRDSET *rrdset_create_custom(
508 if(st) {
509 memset(&st->avl, 0, sizeof(avl));
510 memset(&st->avlname, 0, sizeof(avl));
509 - memset(&st->variables_root_index, 0, sizeof(avl_tree_lock));
511 + memset(&st->rrdvar_root_index, 0, sizeof(avl_tree_lock));
512 memset(&st->dimensions_index, 0, sizeof(avl_tree_lock));
513 memset(&st->rrdset_rwlock, 0, sizeof(netdata_rwlock_t));
514
@@ -640,7 +642,7 @@ RRDSET *rrdset_create_custom(
642 st->upstream_resync_time = 0;
643
644 avl_init_lock(&st->dimensions_index, rrddim_compare);
643 - avl_init_lock(&st->variables_root_index, rrdvar_compare);
645 + avl_init_lock(&st->rrdvar_root_index, rrdvar_compare);
646
647 netdata_rwlock_init(&st->rrdset_rwlock);
648
src/rrdsetvar.c
+10 -10
@@ -10,23 +10,23 @@ static inline void rrdsetvar_free_variables(RRDSETVAR *rs) {
10
11 // CHART
12
13 - rrdvar_free(st->rrdhost, &st->variables_root_index, rs->var_local);
13 + rrdvar_free(st->rrdhost, &st->rrdvar_root_index, rs->var_local);
14 rs->var_local = NULL;
15
16 // FAMILY
17
18 - rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rs->var_family);
18 + rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family);
19 rs->var_family = NULL;
20
21 - rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rs->var_host);
21 + rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host);
22 rs->var_host = NULL;
23
24 // HOST
25
26 - rrdvar_free(st->rrdhost, &st->rrdfamily->variables_root_index, rs->var_family_name);
26 + rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family_name);
27 rs->var_family_name = NULL;
28
29 - rrdvar_free(st->rrdhost, &st->rrdhost->variables_root_index, rs->var_host_name);
29 + rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host_name);
30 rs->var_host_name = NULL;
31
32 // KEYS
@@ -54,17 +54,17 @@ static inline void rrdsetvar_create_variables(RRDSETVAR *rs) {
54
55 // CHART
56
57 - rs->var_local = rrdvar_create_and_index("local", &st->variables_root_index, rs->variable, rs->type, rs->value);
57 + rs->var_local = rrdvar_create_and_index("local", &st->rrdvar_root_index, rs->variable, rs->type, rs->value);
58
59 // FAMILY
60
61 - rs->var_family = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rs->key_fullid, rs->type, rs->value);
62 - rs->var_family_name = rrdvar_create_and_index("family", &st->rrdfamily->variables_root_index, rs->key_fullname, rs->type, rs->value);
61 + rs->var_family = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_fullid, rs->type, rs->value);
62 + rs->var_family_name = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_fullname, rs->type, rs->value);
63
64 // HOST
65
66 - rs->var_host = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->key_fullid, rs->type, rs->value);
67 - rs->var_host_name = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->key_fullname, rs->type, rs->value);
66 + rs->var_host = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullid, rs->type, rs->value);
67 + rs->var_host_name = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullname, rs->type, rs->value);
68
69 }
70
src/rrdvar.c
+41 -45
@@ -56,7 +56,7 @@ inline void rrdvar_free(RRDHOST *host, avl_tree_lock *tree, RRDVAR *rv) {
56 if(tree) {
57 debug(D_VARIABLES, "Deleting variable '%s'", rv->name);
58 if(unlikely(!rrdvar_index_del(tree, rv)))
59 - error("Attempted to delete variable '%s' from host '%s', but it is not found.", rv->name, host->hostname);
59 + error("RRDVAR: Attempted to delete variable '%s' from host '%s', but it is not found.", rv->name, host->hostname);
60 }
61
62 if(rv->type == RRDVAR_TYPE_CALCULATED_ALLOCATED)
@@ -105,18 +105,27 @@ inline RRDVAR *rrdvar_create_and_index(const char *scope, avl_tree_lock *tree, c
105 return rv;
106 }
107
108 +void rrdvar_free_remaining_variables(RRDHOST *host, avl_tree_lock *tree_lock) {
109 + // FIXME: this is not bullet proof - avl should support some means to destroy it
110 + // with a callback for each item already in the index
111 + while(host->rrdvar_root_index.avl_tree.root) {
112 + RRDVAR *rv = (RRDVAR *)tree_lock->avl_tree.root;
113 + rrdvar_free(host, tree_lock, rv);
114 + }
115 +}
116 +
117 // ----------------------------------------------------------------------------
118 // CUSTOM VARIABLES
119
120 inline int rrdvar_callback_for_all_variables(RRDHOST *host, int (*callback)(void *rrdvar, void *data), void *data) {
112 - return avl_traverse_lock(&host->variables_root_index, callback, data);
121 + return avl_traverse_lock(&host->rrdvar_root_index, callback, data);
122 }
123
115 -RRDVAR *rrdvar_custom_host_variable_create(RRDHOST *host, const char *name) {
124 +static RRDVAR *rrdvar_custom_variable_create(const char *scope, avl_tree_lock *tree_lock, const char *name) {
125 calculated_number *v = callocz(1, sizeof(calculated_number));
126 *v = NAN;
127
119 - RRDVAR *rv = rrdvar_create_and_index("host", &host->variables_root_index, name, RRDVAR_TYPE_CALCULATED_ALLOCATED, v);
128 + RRDVAR *rv = rrdvar_create_and_index(scope, tree_lock, name, RRDVAR_TYPE_CALCULATED_ALLOCATED, v);
129 if(unlikely(!rv)) {
130 free(v);
131 debug(D_VARIABLES, "Requested variable '%s' already exists - possibly 2 plugins are updating it at the same time.", name);
@@ -125,7 +134,7 @@ RRDVAR *rrdvar_custom_host_variable_create(RRDHOST *host, const char *name) {
134 rrdvar_fix_name(variable);
135 uint32_t hash = simple_hash(variable);
136
128 - rv = rrdvar_index_find(&host->variables_root_index, variable, hash);
137 + rv = rrdvar_index_find(tree_lock, variable, hash);
138
139 freez(variable);
140 }
@@ -133,52 +142,39 @@ RRDVAR *rrdvar_custom_host_variable_create(RRDHOST *host, const char *name) {
142 return rv;
143 }
144
136 -void rrdvar_free_remaining_variables(RRDHOST *host) {
137 - // FIXME: this is not bullet proof - avl should support some means to destroy it
138 - // with a callback for each item already in the index
139 - while(host->variables_root_index.avl_tree.root) {
140 - RRDVAR *rv = (RRDVAR *)host->variables_root_index.avl_tree.root;
141 - rrdvar_free(host, &host->variables_root_index, rv);
142 - }
145 +RRDVAR *rrdvar_custom_host_variable_create(RRDHOST *host, const char *name) {
146 + return rrdvar_custom_variable_create("host", &host->rrdvar_root_index, name);
147 }
148
145 -void rrdvar_custom_host_variable_destroy(RRDHOST *host, const char *name) {
146 - char *variable = strdupz(name);
147 - rrdvar_fix_name(variable);
148 - uint32_t hash = simple_hash(variable);
149 -
150 - RRDVAR *rv = rrdvar_index_find(&host->variables_root_index, variable, hash);
151 - freez(variable);
152 -
153 - if(!rv) {
154 - error("Attempted to remove variable '%s' from host '%s', but it does not exist.", name, host->hostname);
155 - return;
156 - }
149 +RRDVAR *rrdvar_custom_chart_variable_create(RRDSET *st, const char *name) {
150 + return rrdvar_custom_variable_create("local", &st->rrdvar_root_index, name);
151 +}
152
158 - if(rv->type != RRDVAR_TYPE_CALCULATED_ALLOCATED) {
159 - error("Attempted to remove variable '%s' from host '%s', but it does not a custom allocated variable.", name, host->hostname);
160 - return;
161 - }
153 +void rrdvar_custom_host_variable_set(RRDHOST *host, RRDVAR *rv, calculated_number value) {
154 + if(rv->type != RRDVAR_TYPE_CALCULATED_ALLOCATED)
155 + error("requested to set variable '%s' to value " CALCULATED_NUMBER_FORMAT " but the variable is not a custom one.", rv->name, value);
156 + else {
157 + calculated_number *v = rv->value;
158 + if(*v != value) {
159 + *v = value;
160
163 - if(!rrdvar_index_del(&host->variables_root_index, rv)) {
164 - error("Attempted to remove variable '%s' from host '%s', but it cannot be found.", name, host->hostname);
165 - return;
161 + // if the host is streaming, send this variable upstream immediately
162 + rrdpush_sender_send_this_variable_now(host, rv);
163 + }
164 }
167 -
168 - freez(rv->name);
169 - freez(rv->value);
170 - freez(rv);
165 }
166
173 -void rrdvar_custom_host_variable_set(RRDHOST *host, RRDVAR *rv, calculated_number value) {
167 +void rrdvar_custom_chart_variable_set(RRDSET *st, RRDVAR *rv, calculated_number value) {
168 if(rv->type != RRDVAR_TYPE_CALCULATED_ALLOCATED)
169 error("requested to set variable '%s' to value " CALCULATED_NUMBER_FORMAT " but the variable is not a custom one.", rv->name, value);
170 else {
171 calculated_number *v = rv->value;
178 - *v = value;
172 + if(*v != value) {
173 + *v = value;
174
180 - // if the host is streaming, send this variable upstream immediately
181 - rrdpush_sender_send_this_variable_now(host, rv);
175 + // mark the chart to be sent upstream
176 + rrdset_flag_clear(st, RRDSET_FLAG_EXPOSED_UPSTREAM);
177 + }
178 }
179 }
180
@@ -225,19 +221,19 @@ int health_variable_lookup(const char *variable, uint32_t hash, RRDCALC *rc, cal
221
222 if(!st) return 0;
223
228 - rv = rrdvar_index_find(&st->variables_root_index, variable, hash);
224 + rv = rrdvar_index_find(&st->rrdvar_root_index, variable, hash);
225 if(rv) {
226 *result = rrdvar2number(rv);
227 return 1;
228 }
229
234 - rv = rrdvar_index_find(&st->rrdfamily->variables_root_index, variable, hash);
230 + rv = rrdvar_index_find(&st->rrdfamily->rrdvar_root_index, variable, hash);
231 if(rv) {
232 *result = rrdvar2number(rv);
233 return 1;
234 }
235
240 - rv = rrdvar_index_find(&st->rrdhost->variables_root_index, variable, hash);
236 + rv = rrdvar_index_find(&st->rrdhost->rrdvar_root_index, variable, hash);
237 if(rv) {
238 *result = rrdvar2number(rv);
239 return 1;
@@ -276,13 +272,13 @@ void health_api_v1_chart_variables2json(RRDSET *st, BUFFER *buf) {
272 };
273
274 buffer_sprintf(buf, "{\n\t\"chart\": \"%s\",\n\t\"chart_name\": \"%s\",\n\t\"chart_context\": \"%s\",\n\t\"chart_variables\": {", st->id, st->name, st->context);
279 - avl_traverse_lock(&st->variables_root_index, single_variable2json, (void *)&helper);
275 + avl_traverse_lock(&st->rrdvar_root_index, single_variable2json, (void *)&helper);
276 buffer_sprintf(buf, "\n\t},\n\t\"family\": \"%s\",\n\t\"family_variables\": {", st->family);
277 helper.counter = 0;
282 - avl_traverse_lock(&st->rrdfamily->variables_root_index, single_variable2json, (void *)&helper);
278 + avl_traverse_lock(&st->rrdfamily->rrdvar_root_index, single_variable2json, (void *)&helper);
279 buffer_sprintf(buf, "\n\t},\n\t\"host\": \"%s\",\n\t\"host_variables\": {", st->rrdhost->hostname);
280 helper.counter = 0;
285 - avl_traverse_lock(&st->rrdhost->variables_root_index, single_variable2json, (void *)&helper);
281 + avl_traverse_lock(&st->rrdhost->rrdvar_root_index, single_variable2json, (void *)&helper);
282 buffer_strcat(buf, "\n\t}\n}\n");
283 }
284