@cryptotaxi247 / netdata-1 / commits / 62bc37ed5

Add alarm status counter api call (#6554)

##### Summary This is implementation of a prerequisite for the requested feature #6536 (Generate an overall status badge/chart for the health of category) ##### Component Name web/api/ health/ ##### Details Provide a new, `alarm_count` API call that returns the total number of alarms for given contexts and alarm states. Default is the total number of raised alarms, for all contexts.

Valentin Rakush committed Aug 23, 2019 at 13:29 UTC 62bc37ed5f6cf64459deafc11c7d6d938158c447
6 files changed +171
health/health.h
+1
@@ -58,6 +58,7 @@ extern void *health_main(void *ptr);
58 extern void health_reload(void);
59
60 extern int health_variable_lookup(const char *variable, uint32_t hash, RRDCALC *rc, calculated_number *result);
61 +extern void health_aggregate_alarms(RRDHOST *host, BUFFER *wb, BUFFER* context, RRDCALC_STATUS status);
62 extern void health_alarms2json(RRDHOST *host, BUFFER *wb, int all);
63 extern void health_alarm_log2json(RRDHOST *host, BUFFER *wb, uint32_t after);
64
health/health_json.c
+37
@@ -231,6 +231,43 @@ static inline void health_rrdcalc2json_nolock(RRDHOST *host, BUFFER *wb, RRDCALC
231 //
232 //}
233
234 +void health_aggregate_alarms(RRDHOST *host, BUFFER *wb, BUFFER* contexts, RRDCALC_STATUS status) {
235 + RRDCALC *rc;
236 + int numberOfAlarms = 0;
237 + char *tok = NULL;
238 + char *p = NULL;
239 +
240 + rrdhost_rdlock(host);
241 +
242 + if (contexts) {
243 + p = (char*)buffer_tostring(contexts);
244 + while(p && *p && (tok = mystrsep(&p, ", |"))) {
245 + if(!*tok) continue;
246 +
247 + for(rc = host->alarms; rc ; rc = rc->next) {
248 + if(unlikely(!rc->rrdset || !rc->rrdset->last_collected_time.tv_sec))
249 + continue;
250 + if(unlikely(rc->rrdset && rc->rrdset->hash_context == simple_hash(tok)
251 + && !strcmp(rc->rrdset->context, tok)
252 + && ((status==RRDCALC_STATUS_RAISED)?(rc->status >= RRDCALC_STATUS_WARNING):rc->status == status)))
253 + numberOfAlarms++;
254 + }
255 + }
256 + }
257 + else {
258 + for(rc = host->alarms; rc ; rc = rc->next) {
259 + if(unlikely(!rc->rrdset || !rc->rrdset->last_collected_time.tv_sec))
260 + continue;
261 +
262 + if(unlikely((status==RRDCALC_STATUS_RAISED)?(rc->status >= RRDCALC_STATUS_WARNING):rc->status == status))
263 + numberOfAlarms++;
264 + }
265 + }
266 +
267 + buffer_sprintf(wb, "%d", numberOfAlarms);
268 + rrdhost_unlock(host);
269 +}
270 +
271 void health_alarms2json(RRDHOST *host, BUFFER *wb, int all) {
272 int i;
273
web/api/netdata-swagger.json
+55
@@ -657,6 +657,61 @@
657 }
658 }
659 },
660 + "/alarm_count": {
661 + "get": {
662 + "summary": "Get an overall status of the chart",
663 + "description": "Checks multiple charts with the same context and counts number of alarms with given status.",
664 + "parameters": [
665 + {
666 + "in": "query",
667 + "name": "context",
668 + "description": "Specify context which should be checked",
669 + "required": false,
670 + "allowEmptyValue": true,
671 + "type": "array",
672 + "items": {
673 + "type": "string",
674 + "collectionFormat": "pipes"
675 + },
676 + "default": [
677 + "system.cpu"
678 + ]
679 + },
680 + {
681 + "in": "query",
682 + "name": "status",
683 + "description": "Specify alarm status to count",
684 + "required": false,
685 + "allowEmptyValue": true,
686 + "type": "string",
687 + "enum": [
688 + "REMOVED",
689 + "UNDEFINED",
690 + "UNINITIALIZED",
691 + "CLEAR",
692 + "RAISED",
693 + "WARNING",
694 + "CRITICAL"
695 + ],
696 + "default": "RAISED"
697 + }
698 + ],
699 + "responses": {
700 + "200": {
701 + "description": "An object containing a count of alarms with given status for given contexts",
702 + "schema": {
703 + "type": "array",
704 + "items": {
705 + "type": "number"
706 + }
707 + }
708 + },
709 + "500": {
710 + "description": "Internal server error. This usually means the server is out of memory."
711 + }
712 + }
713 + }
714 + },
715 "/manage/health": {
716 "get": {
717 "summary": "Accesses the health management API to control health checks and notifications at runtime.",
web/api/netdata-swagger.yaml
+32
@@ -430,6 +430,38 @@ paths:
430 type: array
431 items:
432 $ref: '#/definitions/alarm_log_entry'
433 + /alarm_count:
434 + get:
435 + summary: 'Get an overall status of the chart'
436 + description: "Checks multiple charts with the same context and counts number of alarms with given status."
437 + parameters:
438 + - in: query
439 + name: context
440 + description: "Specify context which should be checked"
441 + required: false
442 + allowEmptyValue: true
443 + type: array
444 + items:
445 + type: string
446 + collectionFormat: pipes
447 + default: ['system.cpu']
448 + - in: query
449 + name: status
450 + description: "Specify alarm status to count"
451 + required: false
452 + allowEmptyValue: true
453 + type: string
454 + enum: ['REMOVED', 'UNDEFINED', 'UNINITIALIZED', 'CLEAR', 'RAISED', 'WARNING', 'CRITICAL']
455 + default: 'RAISED'
456 + responses:
457 + '200':
458 + description: 'An object containing a count of alarms with given status for given contexts'
459 + schema:
460 + type: array
461 + items:
462 + type: number
463 + '500':
464 + description: 'Internal server error. This usually means the server is out of memory.'
465 /manage/health:
466 get:
467 summary: 'Accesses the health management API to control health checks and notifications at runtime.'
web/api/web_api_v1.c
+45
@@ -213,6 +213,50 @@ inline int web_client_api_request_v1_alarms(RRDHOST *host, struct web_client *w,
213 return 200;
214 }
215
216 +inline int web_client_api_request_v1_alarm_count(RRDHOST *host, struct web_client *w, char *url) {
217 + RRDCALC_STATUS status = RRDCALC_STATUS_RAISED;
218 + BUFFER *contexts = NULL;
219 +
220 + buffer_flush(w->response.data);
221 + buffer_sprintf(w->response.data, "[");
222 +
223 + while(url) {
224 + char *value = mystrsep(&url, "&");
225 + if(!value || !*value) continue;
226 +
227 + char *name = mystrsep(&value, "=");
228 + if(!name || !*name) continue;
229 + if(!value || !*value) continue;
230 +
231 + debug(D_WEB_CLIENT, "%llu: API v1 alarm_count query param '%s' with value '%s'", w->id, name, value);
232 +
233 + char* p = value;
234 + if(!strcmp(name, "status")) {
235 + while ((*p = toupper(*p))) p++;
236 + if (!strcmp("CRITICAL", value)) status = RRDCALC_STATUS_CRITICAL;
237 + else if (!strcmp("WARNING", value)) status = RRDCALC_STATUS_WARNING;
238 + else if (!strcmp("UNINITIALIZED", value)) status = RRDCALC_STATUS_UNINITIALIZED;
239 + else if (!strcmp("UNDEFINED", value)) status = RRDCALC_STATUS_UNDEFINED;
240 + else if (!strcmp("REMOVED", value)) status = RRDCALC_STATUS_REMOVED;
241 + else if (!strcmp("CLEAR", value)) status = RRDCALC_STATUS_CLEAR;
242 + }
243 + else if(!strcmp(name, "context") || !strcmp(name, "ctx")) {
244 + if(!contexts) contexts = buffer_create(255);
245 + buffer_strcat(contexts, "|");
246 + buffer_strcat(contexts, value);
247 + }
248 + }
249 +
250 + health_aggregate_alarms(host, w->response.data, contexts, status);
251 +
252 + buffer_sprintf(w->response.data, "]\n");
253 + w->response.data->contenttype = CT_APPLICATION_JSON;
254 + buffer_no_cacheable(w->response.data);
255 +
256 + buffer_free(contexts);
257 + return 200;
258 +}
259 +
260 inline int web_client_api_request_v1_alarm_log(RRDHOST *host, struct web_client *w, char *url) {
261 uint32_t after = 0;
262
@@ -780,6 +824,7 @@ static struct api_command {
824 { "alarms", 0, WEB_CLIENT_ACL_DASHBOARD, web_client_api_request_v1_alarms },
825 { "alarm_log", 0, WEB_CLIENT_ACL_DASHBOARD, web_client_api_request_v1_alarm_log },
826 { "alarm_variables", 0, WEB_CLIENT_ACL_DASHBOARD, web_client_api_request_v1_alarm_variables },
827 + { "alarm_count", 0, WEB_CLIENT_ACL_DASHBOARD, web_client_api_request_v1_alarm_count },
828 { "allmetrics", 0, WEB_CLIENT_ACL_DASHBOARD, web_client_api_request_v1_allmetrics },
829 { "manage/health", 0, WEB_CLIENT_ACL_MGMT, web_client_api_request_v1_mgmt_health },
830 // terminator
web/api/web_api_v1.h
+1
@@ -16,6 +16,7 @@ extern int web_client_api_request_v1_alarms(RRDHOST *host, struct web_client *w,
16 extern int web_client_api_request_v1_alarm_log(RRDHOST *host, struct web_client *w, char *url);
17 extern int web_client_api_request_single_chart(RRDHOST *host, struct web_client *w, char *url, void callback(RRDSET *st, BUFFER *buf));
18 extern int web_client_api_request_v1_alarm_variables(RRDHOST *host, struct web_client *w, char *url);
19 +extern int web_client_api_request_v1_alarm_count(RRDHOST *host, struct web_client *w, char *url);
20 extern int web_client_api_request_v1_charts(RRDHOST *host, struct web_client *w, char *url);
21 extern int web_client_api_request_v1_chart(RRDHOST *host, struct web_client *w, char *url);
22 extern int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, char *url);