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