46
47
rc->id = rrdcalc_get_unique_id(host, rc->chart, rc->name, &rc->next_event_id);
48
49
- debug(D_HEALTH, "Health configuration adding alarm '%s.%s' (%u): exec '%s', recipient '%s', green " CALCULATED_NUMBER_FORMAT_AUTO ", red " CALCULATED_NUMBER_FORMAT_AUTO ", lookup: group %d, after %d, before %d, options %u, dimensions '%s', update every %d, calculation '%s', warning '%s', critical '%s', source '%s', delay up %d, delay down %d, delay max %d, delay_multiplier %f, warn_repeat_every %u, crit_repeat_every %u",
49
+ debug(D_HEALTH, "Health configuration adding alarm '%s.%s' (%u): exec '%s', recipient '%s', green " CALCULATED_NUMBER_FORMAT_AUTO ", red " CALCULATED_NUMBER_FORMAT_AUTO ", lookup: group %d, after %d, before %d, options %u, dimensions '%s', for each dimension '%s', update every %d, calculation '%s', warning '%s', critical '%s', source '%s', delay up %d, delay down %d, delay max %d, delay_multiplier %f, warn_repeat_every %u, crit_repeat_every %u",
50
rc->chart?rc->chart:"NOCHART",
51
rc->name,
52
rc->id,
59
rc->before,
60
rc->options,
61
(rc->dimensions)?rc->dimensions:"NONE",
62
+ (rc->foreachdim)?rc->foreachdim:"NONE",
63
rc->update_every,
64
(rc->calculation)?rc->calculation->parsed_as:"NONE",
65
(rc->warning)?rc->warning->parsed_as:"NONE",
74
);
75
76
rrdcalc_add_to_host(host, rc);
77
+
78
return 1;
79
}
80
95
}
96
97
RRDCALCTEMPLATE *t, *last = NULL;
96
- for (t = host->templates; t ; last = t, t = t->next) {
97
- if(unlikely(t->hash_name == rt->hash_name
98
- && !strcmp(t->name, rt->name)
99
- && !strcmp(t->family_match?t->family_match:"*", rt->family_match?rt->family_match:"*")
100
- )) {
101
- error("Health configuration template '%s' already exists for host '%s'.", rt->name, host->hostname);
102
- return 0;
98
+ if(!rt->foreachdim) {
99
+ for (t = host->templates; t ; last = t, t = t->next) {
100
+ if(unlikely(t->hash_name == rt->hash_name
101
+ && !strcmp(t->name, rt->name)
102
+ && !strcmp(t->family_match?t->family_match:"*", rt->family_match?rt->family_match:"*")
103
+ )) {
104
+ error("Health configuration template '%s' already exists for host '%s'.", rt->name, host->hostname);
105
+ return 0;
106
+ }
107
+ }
108
+
109
+ if(likely(last)) {
110
+ last->next = rt;
111
+ }
112
+ else {
113
+ rt->next = host->templates;
114
+ host->templates = rt;
115
+ }
116
+ } else {
117
+ for (t = host->alarms_template_with_foreach; t ; last = t, t = t->next) {
118
+ if(unlikely(t->hash_name == rt->hash_name
119
+ && !strcmp(t->name, rt->name)
120
+ && !strcmp(t->family_match?t->family_match:"*", rt->family_match?rt->family_match:"*")
121
+ )) {
122
+ error("Health configuration template '%s' already exists for host '%s'.", rt->name, host->hostname);
123
+ return 0;
124
+ }
125
+ }
126
+
127
+ if(likely(last)) {
128
+ last->next = rt;
129
+ }
130
+ else {
131
+ rt->next = host->alarms_template_with_foreach;
132
+ host->alarms_template_with_foreach = rt;
133
}
134
}
135
106
- debug(D_HEALTH, "Health configuration adding template '%s': context '%s', exec '%s', recipient '%s', green " CALCULATED_NUMBER_FORMAT_AUTO ", red " CALCULATED_NUMBER_FORMAT_AUTO ", lookup: group %d, after %d, before %d, options %u, dimensions '%s', update every %d, calculation '%s', warning '%s', critical '%s', source '%s', delay up %d, delay down %d, delay max %d, delay_multiplier %f, warn_repeat_every %u, crit_repeat_every %u",
107
- rt->name,
108
- (rt->context)?rt->context:"NONE",
109
- (rt->exec)?rt->exec:"DEFAULT",
110
- (rt->recipient)?rt->recipient:"DEFAULT",
111
- rt->green,
112
- rt->red,
113
- (int)rt->group,
114
- rt->after,
115
- rt->before,
116
- rt->options,
117
- (rt->dimensions)?rt->dimensions:"NONE",
118
- rt->update_every,
119
- (rt->calculation)?rt->calculation->parsed_as:"NONE",
120
- (rt->warning)?rt->warning->parsed_as:"NONE",
121
- (rt->critical)?rt->critical->parsed_as:"NONE",
122
- rt->source,
123
- rt->delay_up_duration,
124
- rt->delay_down_duration,
125
- rt->delay_max_duration,
126
- rt->delay_multiplier,
127
- rt->warn_repeat_every,
128
- rt->crit_repeat_every
136
+ debug(D_HEALTH, "Health configuration adding template '%s': context '%s', exec '%s', recipient '%s', green " CALCULATED_NUMBER_FORMAT_AUTO ", red " CALCULATED_NUMBER_FORMAT_AUTO ", lookup: group %d, after %d, before %d, options %u, dimensions '%s', for each dimension '%s', update every %d, calculation '%s', warning '%s', critical '%s', source '%s', delay up %d, delay down %d, delay max %d, delay_multiplier %f, warn_repeat_every %u, crit_repeat_every %u",
137
+ rt->name,
138
+ (rt->context)?rt->context:"NONE",
139
+ (rt->exec)?rt->exec:"DEFAULT",
140
+ (rt->recipient)?rt->recipient:"DEFAULT",
141
+ rt->green,
142
+ rt->red,
143
+ (int)rt->group,
144
+ rt->after,
145
+ rt->before,
146
+ rt->options,
147
+ (rt->dimensions)?rt->dimensions:"NONE",
148
+ (rt->foreachdim)?rt->foreachdim:"NONE",
149
+ rt->update_every,
150
+ (rt->calculation)?rt->calculation->parsed_as:"NONE",
151
+ (rt->warning)?rt->warning->parsed_as:"NONE",
152
+ (rt->critical)?rt->critical->parsed_as:"NONE",
153
+ rt->source,
154
+ rt->delay_up_duration,
155
+ rt->delay_down_duration,
156
+ rt->delay_max_duration,
157
+ rt->delay_multiplier,
158
+ rt->warn_repeat_every,
159
+ rt->crit_repeat_every
160
);
161
131
- if(likely(last)) {
132
- last->next = rt;
133
- }
134
- else {
135
- rt->next = host->templates;
136
- host->templates = rt;
137
- }
162
163
return 1;
164
}
315
return 1;
316
}
317
318
+/**
319
+ * Health pattern from Foreach
320
+ *
321
+ * Create a new simple pattern using the user input
322
+ *
323
+ * @param s the string that will be used to create the simple pattern.
324
+ */
325
+SIMPLE_PATTERN *health_pattern_from_foreach(char *s) {
326
+ char *convert= strdupz(s);
327
+ SIMPLE_PATTERN *val = NULL;
328
+ if(convert) {
329
+ dimension_remove_pipe_comma(convert);
330
+ val = simple_pattern_create(convert, NULL, SIMPLE_PATTERN_EXACT);
331
+
332
+ freez(convert);
333
+ }
334
+
335
+ return val;
336
+}
337
338
static inline int health_parse_db_lookup(
339
size_t line, const char *filename, char *string,
340
RRDR_GROUPING *group_method, int *after, int *before, int *every,
298
- uint32_t *options, char **dimensions
341
+ uint32_t *options, char **dimensions, char **foreachdim
342
) {
343
debug(D_HEALTH, "Health configuration parsing database lookup %zu@%s: %s", line, filename, string);
344
345
if(*dimensions) freez(*dimensions);
346
+ if(*foreachdim) freez(*foreachdim);
347
*dimensions = NULL;
348
+ *foreachdim = NULL;
349
*after = 0;
350
*before = 0;
351
*every = 0;
432
*options |= RRDR_OPTION_MATCH_NAMES;
433
}
434
else if(!strcasecmp(key, "of")) {
390
- if(*s && strcasecmp(s, "all") != 0)
435
+ char *find = NULL;
436
+ if(*s && strcasecmp(s, "all") != 0) {
437
+ find = strcasestr(s, " foreach");
438
+ if(find) {
439
+ *find = '\0';
440
+ }
441
*dimensions = strdupz(s);
442
+ }
443
+
444
+ if(!find) {
445
+ break;
446
+ }
447
+ s = ++find;
448
+ }
449
+ else if(!strcasecmp(key, HEALTH_FOREACH_KEY )) {
450
+ *foreachdim = strdupz(s);
451
break;
452
}
453
else {
580
uint32_t hash = simple_uhash(key);
581
582
if(hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) {
524
- if (rc && (ignore_this || !rrdcalc_add_alarm_from_config(host, rc)))
525
- rrdcalc_free(rc);
583
+ if(rc) {
584
+ if(ignore_this || !rrdcalc_add_alarm_from_config(host, rc)) {
585
+ rrdcalc_free(rc);
586
+ }
587
+ // health_add_alarms_loop(host, rc, ignore_this) ;
588
+ }
589
590
if(rt) {
591
if (ignore_this || !rrdcalctemplate_add_template_from_config(host, rt))
615
}
616
else if(hash == hash_template && !strcasecmp(key, HEALTH_TEMPLATE_KEY)) {
617
if(rc) {
555
- if(ignore_this || !rrdcalc_add_alarm_from_config(host, rc))
618
+// health_add_alarms_loop(host, rc, ignore_this) ;
619
+ if(ignore_this || !rrdcalc_add_alarm_from_config(host, rc)) {
620
rrdcalc_free(rc);
621
+ }
622
623
rc = NULL;
624
}
625
561
- if(rt && (ignore_this || !rrdcalctemplate_add_template_from_config(host, rt)))
562
- rrdcalctemplate_free(rt);
626
+ if(rt) {
627
+ if(ignore_this || !rrdcalctemplate_add_template_from_config(host, rt))
628
+ rrdcalctemplate_free(rt);
629
+ }
630
631
rt = callocz(1, sizeof(RRDCALCTEMPLATE));
632
rt->name = strdupz(value);
689
}
690
else if(hash == hash_lookup && !strcasecmp(key, HEALTH_LOOKUP_KEY)) {
691
health_parse_db_lookup(line, filename, value, &rc->group, &rc->after, &rc->before,
625
- &rc->update_every,
626
- &rc->options, &rc->dimensions);
692
+ &rc->update_every, &rc->options, &rc->dimensions, &rc->foreachdim);
693
+ if(rc->foreachdim) {
694
+ rc->spdim = health_pattern_from_foreach(rc->foreachdim);
695
+ }
696
}
697
else if(hash == hash_every && !strcasecmp(key, HEALTH_EVERY_KEY)) {
698
if(!config_parse_duration(value, &rc->update_every))
821
}
822
else if(hash == hash_lookup && !strcasecmp(key, HEALTH_LOOKUP_KEY)) {
823
health_parse_db_lookup(line, filename, value, &rt->group, &rt->after, &rt->before,
755
- &rt->update_every, &rt->options, &rt->dimensions);
824
+ &rt->update_every, &rt->options, &rt->dimensions, &rt->foreachdim);
825
+ if(rt->foreachdim) {
826
+ rt->spdim = health_pattern_from_foreach(rt->foreachdim);
827
+ }
828
}
829
else if(hash == hash_every && !strcasecmp(key, HEALTH_EVERY_KEY)) {
830
if(!config_parse_duration(value, &rt->update_every))
938
}
939
}
940
869
- if(rc && (ignore_this || !rrdcalc_add_alarm_from_config(host, rc)))
870
- rrdcalc_free(rc);
941
+ if(rc) {
942
+ //health_add_alarms_loop(host, rc, ignore_this) ;
943
+ if(ignore_this || !rrdcalc_add_alarm_from_config(host, rc)) {
944
+ rrdcalc_free(rc);
945
+ }
946
+ }
947
872
- if(rt && (ignore_this || !rrdcalctemplate_add_template_from_config(host, rt)))
873
- rrdcalctemplate_free(rt);
948
+ if(rt) {
949
+ if(ignore_this || !rrdcalctemplate_add_template_from_config(host, rt))
950
+ rrdcalctemplate_free(rt);
951
+ }
952
953
fclose(fp);
954
return 1;
959
debug(D_HEALTH, "CONFIG health is not enabled for host '%s'", host->hostname);
960
return;
961
}
962
+
963
recursive_config_double_dir_load(user_path, stock_path, subpath, health_readfile, (void *) host, 0);
964
}