summaryrefslogtreecommitdiffstats
path: root/database/rrdcalctemplate.c
blob: 4ba96082acb67b9f3cc31fc3c2e7869bcfa53399 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// SPDX-License-Identifier: GPL-3.0-or-later

#define NETDATA_HEALTH_INTERNALS
#include "rrd.h"

// ----------------------------------------------------------------------------
// RRDCALCTEMPLATE management
/**
 * RRDCALC TEMPLATE LINK MATCHING
 *
 * @param rt is the template used to create the chart.
 * @param st is the chart where the alarm will be attached.
 */
void rrdcalctemplate_check_conditions_and_link(RRDCALCTEMPLATE *rt, RRDSET *st, RRDHOST *host) {
    if(rt->context != st->context)
        return;

    if (rt->charts_pattern && !simple_pattern_matches(rt->charts_pattern, rrdset_name(st)))
        return;

    if (rt->family_pattern && !simple_pattern_matches(rt->family_pattern, rrdset_family(st)))
        return;

    if (rt->module_pattern && !simple_pattern_matches(rt->module_pattern, rrdset_module_name(st)))
        return;

    if (rt->plugin_pattern && !simple_pattern_matches(rt->plugin_pattern, rrdset_plugin_name(st)))
        return;

    if(host->host_labels && rt->host_labels_pattern && !rrdlabels_match_simple_pattern_parsed(host->host_labels, rt->host_labels_pattern, '='))
        return;

    RRDCALC *rc = rrdcalc_create_from_template(host, rt, rrdset_id(st));
    if (unlikely(!rc))
        info("Health tried to create alarm from template '%s' on chart '%s' of host '%s', but it failed", rrdcalctemplate_name(rt), rrdset_id(st), rrdhost_hostname(host));
#ifdef NETDATA_INTERNAL_CHECKS
    else if (rc->rrdset != st && !rc->foreachdim) //When we have a template with foreachdim, the child will be added to the index late
        error("Health alarm '%s.%s' should be linked to chart '%s', but it is not", rrdcalc_chart_name(rc), rrdcalc_name(rc), rrdset_id(st));
#endif
}

void rrdcalctemplate_link_matching(RRDSET *st) {
    RRDHOST *host = st->rrdhost;
    RRDCALCTEMPLATE *rt;

    foreach_rrdcalctemplate_in_rrdhost(host, rt)
        rrdcalctemplate_check_conditions_and_link(rt, st, host);
}

inline void rrdcalctemplate_free(RRDCALCTEMPLATE *rt) {
    if(unlikely(!rt)) return;

    expression_free(rt->calculation);
    expression_free(rt->warning);
    expression_free(rt->critical);

    string_freez(rt->family_match);
    simple_pattern_free(rt->family_pattern);

    string_freez(rt->plugin_match);
    simple_pattern_free(rt->plugin_pattern);

    string_freez(rt->module_match);
    simple_pattern_free(rt->module_pattern);

    string_freez(rt->charts_match);
    simple_pattern_free(rt->charts_pattern);

    string_freez(rt->name);
    string_freez(rt->exec);
    string_freez(rt->recipient);
    string_freez(rt->classification);
    string_freez(rt->component);
    string_freez(rt->type);
    string_freez(rt->context);
    string_freez(rt->source);
    string_freez(rt->units);
    string_freez(rt->info);
    string_freez(rt->dimensions);
    string_freez(rt->foreachdim);
    string_freez(rt->host_labels);
    simple_pattern_free(rt->spdim);
    simple_pattern_free(rt->host_labels_pattern);
    freez(rt);
}

inline void rrdcalctemplate_unlink_and_free(RRDHOST *host, RRDCALCTEMPLATE *rt) {
    if(unlikely(!rt)) return;

    debug(D_HEALTH, "Health removing template '%s' of host '%s'", rrdcalctemplate_name(rt), rrdhost_hostname(host));

    DOUBLE_LINKED_LIST_REMOVE_UNSAFE(host->alarms_templates, rt, prev, next);

    rrdcalctemplate_free(rt);
}