From: Costa Tsaousis Date: Thu, 25 Aug 2016 09:22:56 +0000 (+0300) Subject: alarms status API ready X-Git-Tag: v1.3.0~7^2~11 X-Git-Url: https://arthur.barton.de/gitweb/?a=commitdiff_plain;h=623869a428da7f68df5e6270f059f80a71e47801;p=netdata.git alarms status API ready --- diff --git a/src/health.c b/src/health.c index 234717b8..746392da 100644 --- a/src/health.c +++ b/src/health.c @@ -1414,83 +1414,112 @@ void health_init(void) { // ---------------------------------------------------------------------------- // JSON generation +static inline void health_string2json(BUFFER *wb, const char *prefix, const char *label, const char *value, const char *suffix) { + if(value && *value) + buffer_sprintf(wb, "%s\"%s\":\"%s\"%s", prefix, label, value, suffix); + else + buffer_sprintf(wb, "%s\"%s\":null%s", prefix, label, suffix); +} + static inline void health_rrdcalc2json_nolock(BUFFER *wb, RRDCALC *rc) { + buffer_sprintf(wb, - "\t\t\"%s.%s\": {" + "\t\t\"%s.%s\": {\n" "\t\t\t\"name\": \"%s\",\n" "\t\t\t\"chart\": \"%s\",\n" - "\t\t\t\"dimensions\": \"%s\",\n" "\t\t\t\"exec\": \"%s\",\n" "\t\t\t\"source\": \"%s\",\n" - "\t\t\t\"calc\": \"%s\",\n" - "\t\t\t\"calc_parsed\": \"%s\",\n" - "\t\t\t\"warn\": \"%s\",\n" - "\t\t\t\"warn_parsed\": \"%s\",\n" - "\t\t\t\"crit\": \"%s\",\n" - "\t\t\t\"crit_parsed\": \"%s\",\n" - "\t\t\t\"value\": %Lf,\n" - "\t\t\t\"value_after\": %lu,\n" - "\t\t\t\"value_before\": %lu,\n" - "\t\t\t\"green\": %Lf,\n" - "\t\t\t\"red\": %Lf,\n" "\t\t\t\"status\": \"%s\",\n" "\t\t\t\"last_status_change\": %lu,\n" "\t\t\t\"last_updated\": %lu,\n" "\t\t\t\"next_update\": %lu,\n" "\t\t\t\"update_every\": %d,\n" - "\t\t\t\"lookup_method\": \"%s\",\n" - "\t\t\t\"lookup_after\": %d,\n" - "\t\t\t\"lookup_before\": %d,\n" - "\t\t\t\"lookup_options\": \"" , rc->chart, rc->name , rc->name , rc->chart - , rc->dimensions?rc->dimensions:"" , rc->exec?rc->exec:health_default_exec , rc->source - , rc->calculation?rc->calculation->source:"" - , rc->calculation?rc->calculation->parsed_as:"" - , rc->warning?rc->warning->source:"" - , rc->warning?rc->warning->parsed_as:"" - , rc->critical?rc->critical->source:"" - , rc->critical?rc->critical->parsed_as:"" - , rc->value - , (unsigned long)rc->db_after - , (unsigned long)rc->db_before - , rc->green - , rc->red , rrdcalc_status2string(rc->status) , (unsigned long)rc->last_status_change , (unsigned long)rc->last_updated , (unsigned long)rc->next_update , rc->update_every - , group_method2string(rc->group) - , rc->after - , rc->before ); - buffer_data_options2string(wb, rc->options); - buffer_strcat(wb, "\"\n\t}"); + if(RRDCALC_HAS_DB_LOOKUP(rc)) { + if(rc->dimensions && *rc->dimensions) + health_string2json(wb, "\t\t\t", "lookup_dimensions", rc->dimensions, ",\n"); + + buffer_sprintf(wb, + "\t\t\t\"db_after\": %lu,\n" + "\t\t\t\"db_before\": %lu,\n" + "\t\t\t\"lookup_method\": \"%s\",\n" + "\t\t\t\"lookup_after\": %d,\n" + "\t\t\t\"lookup_before\": %d,\n" + "\t\t\t\"lookup_options\": \"", + (unsigned long) rc->db_after, + (unsigned long) rc->db_before, + group_method2string(rc->group), + rc->after, + rc->before + ); + buffer_data_options2string(wb, rc->options); + buffer_strcat(wb, "\",\n"); + } + + if(rc->calculation) { + health_string2json(wb, "\t\t\t", "calc", rc->calculation->source, ",\n"); + health_string2json(wb, "\t\t\t", "calc_parsed", rc->calculation->parsed_as, ",\n"); + } + + if(rc->warning) { + health_string2json(wb, "\t\t\t", "warn", rc->warning->source, ",\n"); + health_string2json(wb, "\t\t\t", "warn_parsed", rc->warning->parsed_as, ",\n"); + } + + if(rc->critical) { + health_string2json(wb, "\t\t\t", "crit", rc->critical->source, ",\n"); + health_string2json(wb, "\t\t\t", "crit_parsed", rc->critical->parsed_as, ",\n"); + } + + buffer_strcat(wb, "\t\t\t\"green\":"); + buffer_rrd_value(wb, rc->green); + buffer_strcat(wb, ",\n"); + + buffer_strcat(wb, "\t\t\t\"red\":"); + buffer_rrd_value(wb, rc->red); + buffer_strcat(wb, ",\n"); + + buffer_strcat(wb, "\t\t\t\"value\":"); + buffer_rrd_value(wb, rc->value); + buffer_strcat(wb, "\n"); + + buffer_strcat(wb, "\t\t}"); } //void health_rrdcalctemplate2json_nolock(BUFFER *wb, RRDCALCTEMPLATE *rt) { // //} -void health_json(RRDHOST *host, BUFFER *wb) { +void health_alarms2json(RRDHOST *host, BUFFER *wb) { + int i; rrdhost_rdlock(&localhost); - buffer_strcat(wb, "{\n\t\"alarms\": {"); + buffer_strcat(wb, "{\n\t\"alarms\": {\n"); RRDCALC *rc; - for(rc = host->alarms; rc ; rc = rc->next) + for(i = 0, rc = host->alarms; rc ; rc = rc->next, i++) { + if(likely(i)) buffer_strcat(wb, ",\n"); health_rrdcalc2json_nolock(wb, rc); + } - buffer_strcat(wb, "\n},\n\t\"templates\": {"); + buffer_strcat(wb, "\n\t},\n\t\"templates\": {"); // RRDCALCTEMPLATE *rt; // for(rt = host->templates; rt ; rt = rt->next) // health_rrdcalctemplate2json_nolock(wb, rt); + buffer_strcat(wb, "\n\t}"); + buffer_sprintf(wb, ",\n\t\"now\": %lu", (unsigned long)time(NULL)); buffer_strcat(wb, "\n}\n"); rrdhost_unlock(&localhost); } diff --git a/src/health.h b/src/health.h index 54a8ec63..045ddf1a 100644 --- a/src/health.h +++ b/src/health.h @@ -263,5 +263,6 @@ extern void *health_main(void *ptr); extern void health_reload(void); extern int health_variable_lookup(const char *variable, uint32_t hash, RRDCALC *rc, calculated_number *result); +extern void health_alarms2json(RRDHOST *host, BUFFER *wb); #endif //NETDATA_HEALTH_H diff --git a/src/web_buffer.c b/src/web_buffer.c index 5b4f2462..b2285fad 100644 --- a/src/web_buffer.c +++ b/src/web_buffer.c @@ -117,7 +117,7 @@ void buffer_strcat(BUFFER *wb, const char *txt) buffer_need_bytes(wb, 1); char *s = &wb->buffer[wb->len], *start, *end = &wb->buffer[wb->size]; - long len = wb->len; + size_t len = wb->len; start = s; while(*txt && s != end) @@ -213,7 +213,13 @@ void buffer_sprintf(BUFFER *wb, const char *fmt, ...) void buffer_rrd_value(BUFFER *wb, calculated_number value) { buffer_need_bytes(wb, 50); - wb->len += print_calculated_number(&wb->buffer[wb->len], value); + + if(isnan(value) || isinf(value)) { + buffer_strcat(wb, "null"); + return; + } + else + wb->len += print_calculated_number(&wb->buffer[wb->len], value); // terminate it buffer_need_bytes(wb, 1); diff --git a/src/web_client.c b/src/web_client.c index eebb73ac..7f74ac5a 100644 --- a/src/web_client.c +++ b/src/web_client.c @@ -617,6 +617,9 @@ uint32_t web_client_api_request_v1_data_google_format(char *name) const char *group_method2string(int group) { switch(group) { + case GROUP_UNDEFINED: + return ""; + case GROUP_AVERAGE: return "average"; @@ -657,6 +660,16 @@ int web_client_api_request_v1_data_group(char *name, int def) return def; } +int web_client_api_request_v1_alarms(struct web_client *w, char *url) +{ + (void)url; + + buffer_flush(w->response.data); + w->response.data->contenttype = CT_APPLICATION_JSON; + health_alarms2json(&localhost, w->response.data); + return 200; +} + int web_client_api_request_v1_charts(struct web_client *w, char *url) { if(url) { ; } @@ -713,7 +726,7 @@ cleanup: return ret; } -int web_client_api_v1_badge(struct web_client *w, char *url) { +int web_client_api_request_v1_badge(struct web_client *w, char *url) { int ret = 400; buffer_flush(w->response.data); @@ -1311,7 +1324,7 @@ int web_client_api_request_v1_registry(struct web_client *w, char *url) } int web_client_api_request_v1(struct web_client *w, char *url) { - static uint32_t hash_data = 0, hash_chart = 0, hash_charts = 0, hash_registry = 0, hash_badge = 0; + static uint32_t hash_data = 0, hash_chart = 0, hash_charts = 0, hash_registry = 0, hash_badge = 0, hash_alarms = 0; if(unlikely(hash_data == 0)) { hash_data = simple_hash("data"); @@ -1319,6 +1332,7 @@ int web_client_api_request_v1(struct web_client *w, char *url) { hash_charts = simple_hash("charts"); hash_registry = simple_hash("registry"); hash_badge = simple_hash("badge.svg"); + hash_alarms = simple_hash("alarms"); } // get the command @@ -1340,7 +1354,10 @@ int web_client_api_request_v1(struct web_client *w, char *url) { return web_client_api_request_v1_registry(w, url); else if(hash == hash_badge && !strcmp(tok, "badge.svg")) - return web_client_api_v1_badge(w, url); + return web_client_api_request_v1_badge(w, url); + + else if(hash == hash_alarms && !strcmp(tok, "alarms")) + return web_client_api_request_v1_alarms(w, url); else { buffer_flush(w->response.data);