]> arthur.barton.de Git - netdata.git/blobdiff - src/health.c
added support for custom variables that can be exposed to alarm expressions without...
[netdata.git] / src / health.c
index 5dc6586d3e7b19ef913dc4232cf57d858b710da1..876acac56bd1a0dd498ee2f527c6a1b44b901887 100644 (file)
@@ -488,14 +488,15 @@ static inline void rrdvar_free(RRDHOST *host, avl_tree_lock *tree, RRDVAR *rv) {
 
     if(tree) {
         debug(D_VARIABLES, "Deleting variable '%s'", rv->name);
-        rrdvar_index_del(tree, rv);
+        if(unlikely(!rrdvar_index_del(tree, rv)))
+            error("Attempted to delete variable '%s' from host '%s', but it is not found.", rv->name, host->hostname);
     }
 
     freez(rv->name);
     freez(rv);
 }
 
-static inline RRDVAR *rrdvar_create_and_index(const char *scope, avl_tree_lock *tree, const char *name, int type, calculated_number *value) {
+static inline RRDVAR *rrdvar_create_and_index(const char *scope, avl_tree_lock *tree, const char *name, int type, void *value) {
     char *variable = strdupz(name);
     rrdvar_fix_name(variable);
     uint32_t hash = simple_hash(variable);
@@ -533,11 +534,70 @@ static inline RRDVAR *rrdvar_create_and_index(const char *scope, avl_tree_lock *
     return rv;
 }
 
+// ----------------------------------------------------------------------------
+// CUSTOM VARIABLES
+
+RRDVAR *rrdvar_custom_host_variable_create(RRDHOST *host, const char *name) {
+    calculated_number *v = callocz(1, sizeof(calculated_number));
+    *v = NAN;
+    RRDVAR *rv = rrdvar_create_and_index("host", &host->variables_root_index, name, RRDVAR_TYPE_CALCULATED_ALLOCATED, v);
+    if(unlikely(!rv)) {
+        free(v);
+        error("Requested variable '%s' already exists - possibly 2 plugins will be updating it at the same time", name);
+
+        char *variable = strdupz(name);
+        rrdvar_fix_name(variable);
+        uint32_t hash = simple_hash(variable);
+
+        rv = rrdvar_index_find(&host->variables_root_index, variable, hash);
+    }
+
+    return rv;
+}
+
+void rrdvar_custom_host_variable_destroy(RRDHOST *host, const char *name) {
+    char *variable = strdupz(name);
+    rrdvar_fix_name(variable);
+    uint32_t hash = simple_hash(variable);
+
+    RRDVAR *rv = rrdvar_index_find(&host->variables_root_index, variable, hash);
+    freez(variable);
+
+    if(!rv) {
+        error("Attempted to remove variable '%s' from host '%s', but it does not exist.", name, host->hostname);
+        return;
+    }
+
+    if(rv->type != RRDVAR_TYPE_CALCULATED_ALLOCATED) {
+        error("Attempted to remove variable '%s' from host '%s', but it does not a custom allocated variable.", name, host->hostname);
+        return;
+    }
+
+    if(!rrdvar_index_del(&host->variables_root_index, rv)) {
+        error("Attempted to remove variable '%s' from host '%s', but it cannot be found.", name, host->hostname);
+        return;
+    }
+
+    freez(rv->name);
+    freez(rv->value);
+    freez(rv);
+}
+
+void rrdvar_custom_host_variable_set(RRDVAR *rv, calculated_number value) {
+    if(rv->type != RRDVAR_TYPE_CALCULATED_ALLOCATED)
+        error("requested to set variable '%s' to value " CALCULATED_NUMBER_FORMAT " but the variable is not a custom one.", rv->name, value);
+    else {
+        calculated_number *v = rv->value;
+        *v = value;
+    }
+}
+
 // ----------------------------------------------------------------------------
 // RRDVAR lookup
 
 static calculated_number rrdvar2number(RRDVAR *rv) {
     switch(rv->type) {
+        case RRDVAR_TYPE_CALCULATED_ALLOCATED:
         case RRDVAR_TYPE_CALCULATED: {
             calculated_number *n = (calculated_number *)rv->value;
             return *n;