From 4bf37db76e7dda93e57a9730958c6d467a85c622 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 8 Jul 2019 22:14:49 +0200 Subject: Merging upstream version 1.16.0. Signed-off-by: Daniel Baumann --- web/README.md | 2 +- web/api/health/README.md | 49 +++++++ web/api/health/health_cmdapi.c | 172 ++++++++++++++--------- web/api/health/health_cmdapi.h | 2 +- web/api/netdata-swagger.json | 110 ++++++++++++++- web/api/netdata-swagger.yaml | 77 ++++++++++- web/gui/Makefile.am | 7 +- web/gui/console.html | 72 ++++++++++ web/gui/console/index.html | 72 ---------- web/gui/dashboard_info.js | 37 ++++- web/gui/demosites.html | 1 + web/gui/favicon.ico | Bin 34494 -> 1150 bytes web/gui/images/android-icon-144x144.png | Bin 5534 -> 2721 bytes web/gui/images/android-icon-192x192.png | Bin 6680 -> 3923 bytes web/gui/images/android-icon-36x36.png | Bin 1668 -> 539 bytes web/gui/images/android-icon-48x48.png | Bin 1932 -> 762 bytes web/gui/images/android-icon-72x72.png | Bin 2716 -> 1153 bytes web/gui/images/android-icon-96x96.png | Bin 3500 -> 1747 bytes web/gui/images/apple-icon-114x114.png | Bin 4248 -> 3651 bytes web/gui/images/apple-icon-120x120.png | Bin 4471 -> 2315 bytes web/gui/images/apple-icon-144x144.png | Bin 5534 -> 4001 bytes web/gui/images/apple-icon-152x152.png | Bin 5883 -> 5026 bytes web/gui/images/apple-icon-180x180.png | Bin 7297 -> 3645 bytes web/gui/images/apple-icon-57x57.png | Bin 2212 -> 1250 bytes web/gui/images/apple-icon-60x60.png | Bin 2246 -> 1052 bytes web/gui/images/apple-icon-72x72.png | Bin 2716 -> 1427 bytes web/gui/images/apple-icon-76x76.png | Bin 2751 -> 1711 bytes web/gui/images/apple-icon-precomposed.png | Bin 7254 -> 3926 bytes web/gui/images/apple-icon.png | Bin 7254 -> 3926 bytes web/gui/images/banner-icon-144x144.png | Bin 5534 -> 2724 bytes web/gui/images/favicon-128.png | Bin 0 -> 2436 bytes web/gui/images/favicon-16x16.png | Bin 1096 -> 285 bytes web/gui/images/favicon-196x196.png | Bin 0 -> 10025 bytes web/gui/images/favicon-32x32.png | Bin 1575 -> 454 bytes web/gui/images/favicon-96x96.png | Bin 3500 -> 1925 bytes web/gui/images/favicon.ico | Bin 1150 -> 1150 bytes web/gui/images/ms-icon-144x144.png | Bin 5534 -> 4001 bytes web/gui/images/ms-icon-150x150.png | Bin 5772 -> 2867 bytes web/gui/images/ms-icon-310x150.png | Bin 0 -> 3632 bytes web/gui/images/ms-icon-310x310.png | Bin 16102 -> 7215 bytes web/gui/images/ms-icon-36x36.png | Bin 0 -> 536 bytes web/gui/images/ms-icon-70x70.png | Bin 2523 -> 2436 bytes web/gui/images/netdata-logomark.svg | 11 +- web/gui/index.html | 7 +- web/gui/main.css | 1 + web/gui/main.js | 17 ++- web/gui/static/static/img/netdata-logomark.svg | 3 - web/gui/tv.html | 14 +- web/server/README.md | 71 +++++++++- web/server/static/static-threaded.c | 68 ++++++++- web/server/web_client.c | 182 +++++++++++++++++++++++-- web/server/web_client.h | 4 + web/server/web_client_cache.c | 38 ++++++ web/server/web_server.c | 2 - 54 files changed, 818 insertions(+), 201 deletions(-) create mode 100644 web/gui/console.html delete mode 100644 web/gui/console/index.html create mode 100644 web/gui/images/favicon-128.png create mode 100644 web/gui/images/favicon-196x196.png create mode 100644 web/gui/images/ms-icon-310x150.png create mode 100644 web/gui/images/ms-icon-36x36.png delete mode 100644 web/gui/static/static/img/netdata-logomark.svg (limited to 'web') diff --git a/web/README.md b/web/README.md index c110ef651..5c1a06f59 100644 --- a/web/README.md +++ b/web/README.md @@ -14,7 +14,7 @@ For our convenience, Netdata provides 2 more layers: Charts information is stored at /usr/share/netdata/web/[dashboard_info.js](gui/dashboard_info.js). This file includes information that is rendered on the dashboard, controls chart colors, section and subsection heading, titles, etc. -If you change that file, your changes will be overwritten when Netdata is updated. You can preserve your settings by creating a new such file (there is /usr/share/netdata/web/[dashboard_info_custom.example.js](gui/dashboard_info_custom_example.js) you can use to start with). +If you change that file, your changes will be overwritten when Netdata is updated. You can preserve your settings by creating a new such file (there is /usr/share/netdata/web/[dashboard_info_custom_example.js](gui/dashboard_info_custom_example.js) you can use to start with). You have to copy the example file under a new name, so that it will not be overwritten with Netdata updates. diff --git a/web/api/health/README.md b/web/api/health/README.md index 2003a61e0..66a80d5f6 100644 --- a/web/api/health/README.md +++ b/web/api/health/README.md @@ -45,6 +45,7 @@ The following will return an SVG badge of the alarm named `NAME`, attached to th ## Health Management API Netdata v1.12 and beyond provides a command API to control health checks and notifications at runtime. The feature is especially useful for maintenance periods, during which you receive meaningless alarms. +From Netdata v1.16.0 and beyond, the configuration controlled via the API commands is [persisted across netdata restarts](#persistence). Specifically, the API allows you to: - Disable health checks completely. Alarm conditions will not be evaluated at all and no entries will be added to the alarm log. @@ -142,6 +143,43 @@ Example 2.2: Add one more selector, to also silence alarms for cpu1 and cpu2 http://localhost/api/v1/manage/health?families=cpu1 cpu2 ``` +### List silencers + +The command `LIST` was added in netdata v1.16.0 and returns a JSON with the current status of the silencers. + +``` + curl "http://myserver/api/v1/manage/health?cmd=LIST" -H "X-Auth-Token: Mytoken" +``` + +As an example, the following response shows that we have two silencers configured, one for an alarm called `samplealarm` and one for alarms with context `random` on host `myhost` +``` +json +{ + "all": false, + "type": "SILENCE", + "silencers": [ + { + "alarm": "samplealarm" + }, + { + "context": "random", + "hosts": "myhost" + } + ] +} +``` + +The response below shows that we have disabled all health checks. + +``` +json +{ + "all": true, + "type": "DISABLE", + "silencers": [] +} + + ### Responses - "Auth Error" : Token authentication failed @@ -155,6 +193,17 @@ http://localhost/api/v1/manage/health?families=cpu1 cpu2 - "WARNING: Added alarm selector to silence/disable alarms without a SILENCE or DISABLE command." : Added to the response if a selector is added without a selector-specific command. - "WARNING: SILENCE or DISABLE command is ineffective without defining any alarm selectors." : Added to the response if a selector-specific command is issued without a selector. +### Persistence + +From netdata v1.16.0 and beyond, the silencers configuration is persisted to disk and loaded when netdata starts. +The JSON string returned by the [LIST command](#list-silencers) is automatically saved to the `silencers file`, every time a command alters the silencers configuration. +The file's location is configurable in `netdata.conf`. The default is shown below: + +``` +[health] + # silencers file = /var/lib/netdata/health.silencers.json +``` + ### Further reading The test script under [tests/health_mgmtapi](../../../tests/health_mgmtapi) contains a series of tests that you can either run or read through to understand the various calls and responses better. diff --git a/web/api/health/health_cmdapi.c b/web/api/health/health_cmdapi.c index ec177751b..468054c67 100644 --- a/web/api/health/health_cmdapi.c +++ b/web/api/health/health_cmdapi.c @@ -1,17 +1,16 @@ // -// Created by christopher on 11/12/18. +// Created by Christopher on 11/12/18. // #include "health_cmdapi.h" - -static SILENCER *create_silencer(void) { - SILENCER *t = callocz(1, sizeof(SILENCER)); - debug(D_HEALTH, "HEALTH command API: Created empty silencer"); - - return t; -} - +/** + * Free Silencers + * + * Clean the silencer structure + * + * @param t is the structure that will be cleaned. + */ void free_silencers(SILENCER *t) { if (!t) return; if (t->next) free_silencers(t->next); @@ -31,38 +30,104 @@ void free_silencers(SILENCER *t) { return; } +/** + * Silencers to JSON Entry + * + * Fill the buffer with the other values given. + * + * @param wb a pointer to the output buffer + * @param var the json variable + * @param val the json value + * @param hasprev has it a previous value? + * + * @return + */ +int health_silencers2json_entry(BUFFER *wb, char* var, char* val, int hasprev) { + if (val) { + buffer_sprintf(wb, "%s\n\t\t\t\"%s\": \"%s\"", (hasprev)?",":"", var, val); + return 1; + } else { + return hasprev; + } +} +/** + * Silencer to JSON + * + * Write the silencer values using JSON format inside a buffer. + * + * @param wb is the buffer to write the silencers. + */ +void health_silencers2json(BUFFER *wb) { + buffer_sprintf(wb, "{\n\t\"all\": %s," + "\n\t\"type\": \"%s\"," + "\n\t\"silencers\": [", + (silencers->all_alarms)?"true":"false", + (silencers->stype == STYPE_NONE)?"None":((silencers->stype == STYPE_DISABLE_ALARMS)?"DISABLE":"SILENCE")); + + SILENCER *silencer; + int i = 0, j = 0; + for(silencer = silencers->silencers; silencer ; silencer = silencer->next) { + if(likely(i)) buffer_strcat(wb, ","); + buffer_strcat(wb, "\n\t\t{"); + j=health_silencers2json_entry(wb, HEALTH_ALARM_KEY, silencer->alarms, j); + j=health_silencers2json_entry(wb, HEALTH_CHART_KEY, silencer->charts, j); + j=health_silencers2json_entry(wb, HEALTH_CONTEXT_KEY, silencer->contexts, j); + j=health_silencers2json_entry(wb, HEALTH_HOST_KEY, silencer->hosts, j); + health_silencers2json_entry(wb, HEALTH_FAMILIES_KEY, silencer->families, j); + j=0; + buffer_strcat(wb, "\n\t\t}"); + i++; + } + if(likely(i)) buffer_strcat(wb, "\n\t"); + buffer_strcat(wb, "]\n}\n"); +} +/** + * Silencer to FILE + * + * Write the sliencer buffer to a file. + * @param wb + */ +void health_silencers2file(BUFFER *wb) { + if (wb->len == 0) return; + + FILE *fd = fopen(silencers_filename, "wb"); + if(fd) { + size_t written = (size_t)fprintf(fd, "%s", wb->buffer) ; + if (written == wb->len ) { + info("Silencer changes written to %s", silencers_filename); + } + fclose(fd); + return; + } + error("Silencer changes could not be written to %s. Error %s", silencers_filename, strerror(errno)); +} + +/** + * Request V1 MGMT Health + * + * Function called by api to management the health. + * + * @param host main structure with client information! + * @param w is the structure with all information of the client request. + * @param url is the url that netdata is working + * + * @return It returns 200 on success and another code otherwise. + */ int web_client_api_request_v1_mgmt_health(RRDHOST *host, struct web_client *w, char *url) { int ret = 400; (void) host; - - BUFFER *wb = w->response.data; buffer_flush(wb); wb->contenttype = CT_TEXT_PLAIN; buffer_flush(w->response.data); - static uint32_t - hash_alarm = 0, - hash_template = 0, - hash_chart = 0, - hash_context = 0, - hash_host = 0, - hash_families = 0; - - if (unlikely(!hash_alarm)) { - hash_alarm = simple_uhash(HEALTH_ALARM_KEY); - hash_template = simple_uhash(HEALTH_TEMPLATE_KEY); - hash_chart = simple_uhash(HEALTH_CHART_KEY); - hash_context = simple_uhash(HEALTH_CONTEXT_KEY); - hash_host = simple_uhash(HEALTH_HOST_KEY); - hash_families = simple_uhash(HEALTH_FAMILIES_KEY); - } - + //Local instance of the silencer SILENCER *silencer = NULL; + int config_changed = 1; if (!w->auth_bearer_token) { buffer_strcat(wb, HEALTH_CMDAPI_MSG_AUTHERROR); @@ -105,50 +170,17 @@ int web_client_api_request_v1_mgmt_health(RRDHOST *host, struct web_client *w, c free_silencers(silencers->silencers); silencers->silencers = NULL; buffer_strcat(wb, HEALTH_CMDAPI_MSG_RESET); + } else if (!strcmp(value, HEALTH_CMDAPI_CMD_LIST)) { + w->response.data->contenttype = CT_APPLICATION_JSON; + health_silencers2json(wb); + config_changed=0; } } else { - uint32_t hash = simple_uhash(key); - if (unlikely(silencer == NULL)) { - if ( - (hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) || - (hash == hash_template && !strcasecmp(key, HEALTH_TEMPLATE_KEY)) || - (hash == hash_chart && !strcasecmp(key, HEALTH_CHART_KEY)) || - (hash == hash_context && !strcasecmp(key, HEALTH_CONTEXT_KEY)) || - (hash == hash_host && !strcasecmp(key, HEALTH_HOST_KEY)) || - (hash == hash_families && !strcasecmp(key, HEALTH_FAMILIES_KEY)) - ) { - silencer = create_silencer(); - } - } - - if (hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) { - silencer->alarms = strdupz(value); - silencer->alarms_pattern = simple_pattern_create(silencer->alarms, NULL, SIMPLE_PATTERN_EXACT); - } else if (hash == hash_chart && !strcasecmp(key, HEALTH_CHART_KEY)) { - silencer->charts = strdupz(value); - silencer->charts_pattern = simple_pattern_create(silencer->charts, NULL, SIMPLE_PATTERN_EXACT); - } else if (hash == hash_context && !strcasecmp(key, HEALTH_CONTEXT_KEY)) { - silencer->contexts = strdupz(value); - silencer->contexts_pattern = simple_pattern_create(silencer->contexts, NULL, SIMPLE_PATTERN_EXACT); - } else if (hash == hash_host && !strcasecmp(key, HEALTH_HOST_KEY)) { - silencer->hosts = strdupz(value); - silencer->hosts_pattern = simple_pattern_create(silencer->hosts, NULL, SIMPLE_PATTERN_EXACT); - } else if (hash == hash_families && !strcasecmp(key, HEALTH_FAMILIES_KEY)) { - silencer->families = strdupz(value); - silencer->families_pattern = simple_pattern_create(silencer->families, NULL, SIMPLE_PATTERN_EXACT); - } else { - buffer_strcat(wb, HEALTH_CMDAPI_MSG_INVALID_KEY); - } + silencer = health_silencers_addparam(silencer, key, value); } - } if (likely(silencer)) { - // Add the created instance to the linked list in silencers - silencer->next = silencers->silencers; - silencers->silencers = silencer; - debug(D_HEALTH, "HEALTH command API: Added silencer %s:%s:%s:%s:%s", silencer->alarms, - silencer->charts, silencer->contexts, silencer->hosts, silencer->families - ); + health_silencers_add(silencer); buffer_strcat(wb, HEALTH_CMDAPI_MSG_ADDED); if (silencers->stype == STYPE_NONE) { buffer_strcat(wb, HEALTH_CMDAPI_MSG_STYPEWARNING); @@ -162,5 +194,11 @@ int web_client_api_request_v1_mgmt_health(RRDHOST *host, struct web_client *w, c } w->response.data = wb; buffer_no_cacheable(w->response.data); + if (ret == 200 && config_changed) { + BUFFER *jsonb = buffer_create(200); + health_silencers2json(jsonb); + health_silencers2file(jsonb); + } + return ret; } diff --git a/web/api/health/health_cmdapi.h b/web/api/health/health_cmdapi.h index d0f30401c..d8ec6aaa0 100644 --- a/web/api/health/health_cmdapi.h +++ b/web/api/health/health_cmdapi.h @@ -12,6 +12,7 @@ #define HEALTH_CMDAPI_CMD_SILENCE "SILENCE" #define HEALTH_CMDAPI_CMD_DISABLE "DISABLE" #define HEALTH_CMDAPI_CMD_RESET "RESET" +#define HEALTH_CMDAPI_CMD_LIST "LIST" #define HEALTH_CMDAPI_MSG_AUTHERROR "Auth Error\n" #define HEALTH_CMDAPI_MSG_SILENCEALL "All alarm notifications are silenced\n" @@ -20,7 +21,6 @@ #define HEALTH_CMDAPI_MSG_DISABLE "Health checks disabled for alarms matching the selectors\n" #define HEALTH_CMDAPI_MSG_SILENCE "Alarm notifications silenced for alarms matching the selectors\n" #define HEALTH_CMDAPI_MSG_ADDED "Alarm selector added\n" -#define HEALTH_CMDAPI_MSG_INVALID_KEY "Invalid key. Ignoring it.\n" #define HEALTH_CMDAPI_MSG_STYPEWARNING "WARNING: Added alarm selector to silence/disable alarms without a SILENCE or DISABLE command.\n" #define HEALTH_CMDAPI_MSG_NOSELECTORWARNING "WARNING: SILENCE or DISABLE command is ineffective without defining any alarm selectors.\n" diff --git a/web/api/netdata-swagger.json b/web/api/netdata-swagger.json index 2fa55c4fa..63bc5638d 100644 --- a/web/api/netdata-swagger.json +++ b/web/api/netdata-swagger.json @@ -77,6 +77,39 @@ } } }, + "/alarm_variables": { + "get": { + "summary": "List variables available to configure alarms for a chart", + "description": "Returns the basic information of a chart and all the variables that can be used in alarm and template health configurations for the particular chart or family", + "parameters": [ + { + "name": "chart", + "in": "query", + "description": "The id of the chart as returned by the /charts call.", + "required": true, + "type": "string", + "format": "as returned by /charts" + } + ], + "responses": { + "200": { + "description": "A javascript object with information about the chart and the available variables", + "schema": { + "$ref": "#/definitions/alarm_variables" + } + }, + "400": { + "description": "Bad request - the body will include a message stating what is wrong." + }, + "404": { + "description": "No chart with the given id is found." + }, + "500": { + "description": "Internal server error. This usually means the server is out of memory." + } + } + } + }, "/data": { "get": { "summary": "Get collected data for a specific chart", @@ -631,7 +664,7 @@ { "name": "cmd", "in": "query", - "description": "DISABLE ALL: No alarm criteria are evaluated, nothing is written in the alarm log. SILENCE ALL: No notifications are sent. RESET: Return to the default state. DISABLE/SILENCE: Set the mode to be used for the alarms matching the criteria of the alarm selectors.", + "description": "DISABLE ALL: No alarm criteria are evaluated, nothing is written in the alarm log. SILENCE ALL: No notifications are sent. RESET: Return to the default state. DISABLE/SILENCE: Set the mode to be used for the alarms matching the criteria of the alarm selectors. LIST: Show active configuration.", "required": false, "type": "string", "enum": [ @@ -639,7 +672,8 @@ "SILENCE ALL", "DISABLE", "SILENCE", - "RESET" + "RESET", + "LIST" ] }, { @@ -951,6 +985,70 @@ } } }, + "alarm_variables": { + "type": "object", + "properties": { + "chart": { + "type": "string", + "description": "The unique id of the chart" + }, + "chart_name": { + "type": "string", + "description": "The name of the chart" + }, + "cnart_context": { + "type": "string", + "description": "The context of the chart. It is shared across multiple monitored software or hardware instances and used in alarm templates" + }, + "family": { + "type": "string", + "description": "The family of the chart." + }, + "host": { + "type": "string", + "description": "The host containing the chart." + }, + "chart_variables": { + "type": "object", + "properties": { + "varname1": { + "type": "number", + "format": "float" + }, + "varname2": { + "type": "number", + "format": "float" + } + } + }, + "family_variables": { + "type": "object", + "properties": { + "varname1": { + "type": "number", + "format": "float" + }, + "varname2": { + "type": "number", + "format": "float" + } + } + }, + "host_variables": { + "type": "object", + "properties": { + "varname1": { + "type": "number", + "format": "float" + }, + "varname2": { + "type": "number", + "format": "float" + } + } + } + } + }, "dimension": { "type": "object", "properties": { @@ -1208,6 +1306,14 @@ "crit_parsed": { "type": "string" }, + "warn_repeat_every": { + "type": "integer", + "format": "int32" + }, + "crit_repeat_every": { + "type": "integer", + "format": "int32" + }, "green": { "type": "string", "format": "nullable" diff --git a/web/api/netdata-swagger.yaml b/web/api/netdata-swagger.yaml index c021efefa..3386e01a7 100644 --- a/web/api/netdata-swagger.yaml +++ b/web/api/netdata-swagger.yaml @@ -63,6 +63,28 @@ paths: $ref: '#/definitions/chart' '404': description: 'No chart with the given id is found.' + /alarm_variables: + get: + summary: 'List variables available to configure alarms for a chart' + description: 'Returns the basic information of a chart and all the variables that can be used in alarm and template health configurations for the particular chart or family' + parameters: + - name: chart + in: query + description: 'The id of the chart as returned by the /charts call.' + required: true + type: string + format: 'as returned by /charts' + responses: + '200': + description: 'A javascript object with information about the chart and the available variables' + schema: + $ref: '#/definitions/alarm_variables' + '400': + description: 'Bad request - the body will include a message stating what is wrong.' + '404': + description: 'No chart with the given id is found.' + '500': + description: 'Internal server error. This usually means the server is out of memory.' /data: get: summary: 'Get collected data for a specific chart' @@ -415,10 +437,10 @@ paths: parameters: - name: cmd in: query - description: 'DISABLE ALL: No alarm criteria are evaluated, nothing is written in the alarm log. SILENCE ALL: No notifications are sent. RESET: Return to the default state. DISABLE/SILENCE: Set the mode to be used for the alarms matching the criteria of the alarm selectors.' + description: 'DISABLE ALL: No alarm criteria are evaluated, nothing is written in the alarm log. SILENCE ALL: No notifications are sent. RESET: Return to the default state. DISABLE/SILENCE: Set the mode to be used for the alarms matching the criteria of the alarm selectors. LIST: Show active configuration.' required: false type: string - enum: ['DISABLE ALL', 'SILENCE ALL', 'DISABLE', 'SILENCE', 'RESET'] + enum: ['DISABLE ALL', 'SILENCE ALL', 'DISABLE', 'SILENCE', 'RESET', 'LIST'] - name: alarm in: query description: 'The expression provided will match both `alarm` and `template` names.' @@ -638,6 +660,51 @@ definitions: red: type: number description: 'Chart health red trheshold' + alarm_variables: + type: object + properties: + chart: + type: string + description: 'The unique id of the chart' + chart_name: + type: string + description: 'The name of the chart' + cnart_context: + type: string + description: 'The context of the chart. It is shared across multiple monitored software or hardware instances and used in alarm templates' + family: + type: string + description: 'The family of the chart.' + host: + type: string + description: 'The host containing the chart.' + chart_variables: + type: object + properties: + varname1: + type: number + format: float + varname2: + type: number + format: float + family_variables: + type: object + properties: + varname1: + type: number + format: float + varname2: + type: number + format: float + host_variables: + type: object + properties: + varname1: + type: number + format: float + varname2: + type: number + format: float dimension: type: object properties: @@ -825,6 +892,12 @@ definitions: type: string crit_parsed: type: string + warn_repeat_every: + type: integer + format: int32 + crit_repeat_every: + type: integer + format: int32 green: type: string format: nullable diff --git a/web/gui/Makefile.am b/web/gui/Makefile.am index 7d1ceef91..ef8aa05fd 100644 --- a/web/gui/Makefile.am +++ b/web/gui/Makefile.am @@ -61,6 +61,7 @@ dist_web_DATA = \ index.html \ main.css \ main.js \ + console.html \ infographic.html \ robots.txt \ refresh-badges.js \ @@ -69,12 +70,6 @@ dist_web_DATA = \ version.txt \ $(NULL) - -webconsoledir=$(webdir)/console -dist_webconsole_DATA = \ - console/index.html \ - $(NULL) - webstaticdir=$(webdir)/static/img dist_webstatic_DATA = \ static/img/netdata-logomark.svg \ diff --git a/web/gui/console.html b/web/gui/console.html new file mode 100644 index 000000000..942c8c3cd --- /dev/null +++ b/web/gui/console.html @@ -0,0 +1,72 @@ + + + + + Netdata Console + + + + + + + + + + + + + + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/web/gui/console/index.html b/web/gui/console/index.html deleted file mode 100644 index 723201919..000000000 --- a/web/gui/console/index.html +++ /dev/null @@ -1,72 +0,0 @@ - - - - - Netdata Console - - - - - - - - - - - - - - - - - - - -
- - - - - - \ No newline at end of file diff --git a/web/gui/dashboard_info.js b/web/gui/dashboard_info.js index aab11ba34..0013311e8 100644 --- a/web/gui/dashboard_info.js +++ b/web/gui/dashboard_info.js @@ -267,6 +267,12 @@ netdataDashboard.menu = { info: 'Performance metrics for RetroShare. RetroShare is open source software for encrypted filesharing, serverless email, instant messaging, online chat, and BBS, based on a friend-to-friend network built on GNU Privacy Guard (GPG).' }, + 'riakkv': { + title: 'Riak KV', + icon: '', + info: 'Metrics for Riak KV, the distributed key-value store.' + }, + 'ipfs': { title: 'IPFS', icon: '', @@ -279,6 +285,13 @@ netdataDashboard.menu = { info: 'Performance metrics for PHP-FPM, an alternative FastCGI implementation for PHP.' }, + 'pihole': { + title: 'Pi-hole', + icon: '', + info: 'Metrics for Pi-hole, a black hole for Internet advertisements.' + + ' The metrics returned by Pi-Hole API is all from the last 24 hours.' + }, + 'portcheck': { title: 'Port Check', icon: '', @@ -324,7 +337,7 @@ netdataDashboard.menu = { 'web_log': { title: undefined, icon: '', - info: 'Information extracted from a server log file. web_log plugin incrementally parses the server log file to provide, in real-time, a break down of key server performance metrics. For web servers, an extended log file format may optionally be used (for nginx and apache) offering timing information and bandwidth for both requests and responses. web_log plugin may also be configured to provide a break down of requests per URL pattern (check /etc/netdata/python.d/web_log.conf).' + info: 'Information extracted from a server log file. web_log plugin incrementally parses the server log file to provide, in real-time, a break down of key server performance metrics. For web servers, an extended log file format may optionally be used (for nginx and apache) offering timing information and bandwidth for both requests and responses. web_log plugin may also be configured to provide a break down of requests per URL pattern (check /etc/netdata/python.d/web_log.conf).' }, 'named': { @@ -461,6 +474,18 @@ netdataDashboard.menu = { title: '', icon: '', info: 'Xen domain resource utilization metrics. Netdata reads this information using xenstat library which gives access to the resource usage information (CPU, memory, disk I/O, network) for a virtual machine.' + }, + + 'wmi': { + title: 'wmi', + icon: '', + info: undefined + }, + + 'perf': { + title: 'Perf Counters', + icon: '', + info: 'Performance Monitoring Counters (PMC). Data collected using perf_event_open() system call which utilises Hardware Performance Monitoring Units (PMU).' } }; @@ -515,7 +540,7 @@ netdataDashboard.submenu = { }, 'web_log.urls': { - info: 'Number of requests for each URL pattern defined in /etc/netdata/python.d/web_log.conf. This chart counts all requests matching the URL patterns defined, independently of the web server response codes (i.e. both successful and unsuccessful).' + info: 'Number of requests for each URL pattern defined in /etc/netdata/python.d/web_log.conf. This chart counts all requests matching the URL patterns defined, independently of the web server response codes (i.e. both successful and unsuccessful).' }, 'web_log.clients': { @@ -1163,6 +1188,10 @@ netdataDashboard.context = { '' }, + 'mysql.innodb_deadlocks': { + info: 'A deadlock happens when two or more transactions mutually hold and request for locks, creating a cycle of dependencies. For more information about how to minimize and handle deadlocks.' + }, + // ------------------------------------------------------------------------ // POSTGRESQL @@ -1806,7 +1835,7 @@ netdataDashboard.context = { }, 'web_log.clients_all': { - info: 'Unique client IPs accessing the web server since the last restart of netdata. This plugin keeps in memory all the unique IPs that have accessed the web server. On very busy web servers (several millions of unique IPs) you may want to disable this chart (check /etc/netdata/python.d/web_log.conf).' + info: 'Unique client IPs accessing the web server since the last restart of netdata. This plugin keeps in memory all the unique IPs that have accessed the web server. On very busy web servers (several millions of unique IPs) you may want to disable this chart (check /etc/netdata/python.d/web_log.conf).' }, // ------------------------------------------------------------------------ @@ -1937,7 +1966,7 @@ netdataDashboard.context = { }, 'web_log.squid_clients_all': { - info: 'Unique client IPs accessing squid since the last restart of netdata. This plugin keeps in memory all the unique IPs that have accessed the server. On very busy squid servers (several millions of unique IPs) you may want to disable this chart (check /etc/netdata/python.d/web_log.conf).' + info: 'Unique client IPs accessing squid since the last restart of netdata. This plugin keeps in memory all the unique IPs that have accessed the server. On very busy squid servers (several millions of unique IPs) you may want to disable this chart (check /etc/netdata/python.d/web_log.conf).' }, 'web_log.squid_transport_methods': { diff --git a/web/gui/demosites.html b/web/gui/demosites.html index f908e0b4c..e00fbbfdd 100644 --- a/web/gui/demosites.html +++ b/web/gui/demosites.html @@ -2,6 +2,7 @@ + NetData: Get control of your Linux Servers. Simple. Effective. Awesome. diff --git a/web/gui/favicon.ico b/web/gui/favicon.ico index 857c582d1..064032aee 100644 Binary files a/web/gui/favicon.ico and b/web/gui/favicon.ico differ diff --git a/web/gui/images/android-icon-144x144.png b/web/gui/images/android-icon-144x144.png index c3013cc96..69efa5a23 100644 Binary files a/web/gui/images/android-icon-144x144.png and b/web/gui/images/android-icon-144x144.png differ diff --git a/web/gui/images/android-icon-192x192.png b/web/gui/images/android-icon-192x192.png index 77d18d9cc..e57443575 100644 Binary files a/web/gui/images/android-icon-192x192.png and b/web/gui/images/android-icon-192x192.png differ diff --git a/web/gui/images/android-icon-36x36.png b/web/gui/images/android-icon-36x36.png index 74576f6ba..4ba804d9c 100644 Binary files a/web/gui/images/android-icon-36x36.png and b/web/gui/images/android-icon-36x36.png differ diff --git a/web/gui/images/android-icon-48x48.png b/web/gui/images/android-icon-48x48.png index 5666fa102..04970d4bb 100644 Binary files a/web/gui/images/android-icon-48x48.png and b/web/gui/images/android-icon-48x48.png differ diff --git a/web/gui/images/android-icon-72x72.png b/web/gui/images/android-icon-72x72.png index 7f7043f14..5cbc701e2 100644 Binary files a/web/gui/images/android-icon-72x72.png and b/web/gui/images/android-icon-72x72.png differ diff --git a/web/gui/images/android-icon-96x96.png b/web/gui/images/android-icon-96x96.png index 1bbf594de..21f27cea8 100644 Binary files a/web/gui/images/android-icon-96x96.png and b/web/gui/images/android-icon-96x96.png differ diff --git a/web/gui/images/apple-icon-114x114.png b/web/gui/images/apple-icon-114x114.png index 7d093e856..7993e055d 100644 Binary files a/web/gui/images/apple-icon-114x114.png and b/web/gui/images/apple-icon-114x114.png differ diff --git a/web/gui/images/apple-icon-120x120.png b/web/gui/images/apple-icon-120x120.png index d4c38e7b1..3fbe8fda3 100644 Binary files a/web/gui/images/apple-icon-120x120.png and b/web/gui/images/apple-icon-120x120.png differ diff --git a/web/gui/images/apple-icon-144x144.png b/web/gui/images/apple-icon-144x144.png index c3013cc96..8d465692b 100644 Binary files a/web/gui/images/apple-icon-144x144.png and b/web/gui/images/apple-icon-144x144.png differ diff --git a/web/gui/images/apple-icon-152x152.png b/web/gui/images/apple-icon-152x152.png index c92f38172..11a10723d 100644 Binary files a/web/gui/images/apple-icon-152x152.png and b/web/gui/images/apple-icon-152x152.png differ diff --git a/web/gui/images/apple-icon-180x180.png b/web/gui/images/apple-icon-180x180.png index 1a58fdbb2..314efb122 100644 Binary files a/web/gui/images/apple-icon-180x180.png and b/web/gui/images/apple-icon-180x180.png differ diff --git a/web/gui/images/apple-icon-57x57.png b/web/gui/images/apple-icon-57x57.png index 36c273ced..852836161 100644 Binary files a/web/gui/images/apple-icon-57x57.png and b/web/gui/images/apple-icon-57x57.png differ diff --git a/web/gui/images/apple-icon-60x60.png b/web/gui/images/apple-icon-60x60.png index c3c48c8bd..2662e85d6 100644 Binary files a/web/gui/images/apple-icon-60x60.png and b/web/gui/images/apple-icon-60x60.png differ diff --git a/web/gui/images/apple-icon-72x72.png b/web/gui/images/apple-icon-72x72.png index 7f7043f14..4a6b056e0 100644 Binary files a/web/gui/images/apple-icon-72x72.png and b/web/gui/images/apple-icon-72x72.png differ diff --git a/web/gui/images/apple-icon-76x76.png b/web/gui/images/apple-icon-76x76.png index b5e73cd4e..c2bf6c9f5 100644 Binary files a/web/gui/images/apple-icon-76x76.png and b/web/gui/images/apple-icon-76x76.png differ diff --git a/web/gui/images/apple-icon-precomposed.png b/web/gui/images/apple-icon-precomposed.png index f69945bf9..9c3e73ef4 100644 Binary files a/web/gui/images/apple-icon-precomposed.png and b/web/gui/images/apple-icon-precomposed.png differ diff --git a/web/gui/images/apple-icon.png b/web/gui/images/apple-icon.png index f69945bf9..9c3e73ef4 100644 Binary files a/web/gui/images/apple-icon.png and b/web/gui/images/apple-icon.png differ diff --git a/web/gui/images/banner-icon-144x144.png b/web/gui/images/banner-icon-144x144.png index c3013cc96..fef3dca16 100644 Binary files a/web/gui/images/banner-icon-144x144.png and b/web/gui/images/banner-icon-144x144.png differ diff --git a/web/gui/images/favicon-128.png b/web/gui/images/favicon-128.png new file mode 100644 index 000000000..5371f920c Binary files /dev/null and b/web/gui/images/favicon-128.png differ diff --git a/web/gui/images/favicon-16x16.png b/web/gui/images/favicon-16x16.png index 43eb188fe..5729f5a2d 100644 Binary files a/web/gui/images/favicon-16x16.png and b/web/gui/images/favicon-16x16.png differ diff --git a/web/gui/images/favicon-196x196.png b/web/gui/images/favicon-196x196.png new file mode 100644 index 000000000..a208c27fa Binary files /dev/null and b/web/gui/images/favicon-196x196.png differ diff --git a/web/gui/images/favicon-32x32.png b/web/gui/images/favicon-32x32.png index e657e9212..cdb0a4806 100644 Binary files a/web/gui/images/favicon-32x32.png and b/web/gui/images/favicon-32x32.png differ diff --git a/web/gui/images/favicon-96x96.png b/web/gui/images/favicon-96x96.png index 1bbf594de..dbe7dea24 100644 Binary files a/web/gui/images/favicon-96x96.png and b/web/gui/images/favicon-96x96.png differ diff --git a/web/gui/images/favicon.ico b/web/gui/images/favicon.ico index 7ed957252..064032aee 100644 Binary files a/web/gui/images/favicon.ico and b/web/gui/images/favicon.ico differ diff --git a/web/gui/images/ms-icon-144x144.png b/web/gui/images/ms-icon-144x144.png index c3013cc96..8d465692b 100644 Binary files a/web/gui/images/ms-icon-144x144.png and b/web/gui/images/ms-icon-144x144.png differ diff --git a/web/gui/images/ms-icon-150x150.png b/web/gui/images/ms-icon-150x150.png index f0cf41287..4683d56a3 100644 Binary files a/web/gui/images/ms-icon-150x150.png and b/web/gui/images/ms-icon-150x150.png differ diff --git a/web/gui/images/ms-icon-310x150.png b/web/gui/images/ms-icon-310x150.png new file mode 100644 index 000000000..5d4ac57b6 Binary files /dev/null and b/web/gui/images/ms-icon-310x150.png differ diff --git a/web/gui/images/ms-icon-310x310.png b/web/gui/images/ms-icon-310x310.png index 4f5f7e621..bdb591b24 100644 Binary files a/web/gui/images/ms-icon-310x310.png and b/web/gui/images/ms-icon-310x310.png differ diff --git a/web/gui/images/ms-icon-36x36.png b/web/gui/images/ms-icon-36x36.png new file mode 100644 index 000000000..e251302ed Binary files /dev/null and b/web/gui/images/ms-icon-36x36.png differ diff --git a/web/gui/images/ms-icon-70x70.png b/web/gui/images/ms-icon-70x70.png index 70012c61f..5371f920c 100644 Binary files a/web/gui/images/ms-icon-70x70.png and b/web/gui/images/ms-icon-70x70.png differ diff --git a/web/gui/images/netdata-logomark.svg b/web/gui/images/netdata-logomark.svg index 87fb2bda7..18152fb7f 100644 --- a/web/gui/images/netdata-logomark.svg +++ b/web/gui/images/netdata-logomark.svg @@ -1,3 +1,8 @@ - - - + + + + + + + + \ No newline at end of file diff --git a/web/gui/index.html b/web/gui/index.html index c9dd89b22..4a8647dd9 100644 --- a/web/gui/index.html +++ b/web/gui/index.html @@ -15,8 +15,7 @@ - - + Redirecting to safety connection, case your browser does not support redirection, please click here."); + w->response.code = 301; + break; + } +#endif case HTTP_VALIDATION_NOT_SUPPORTED: debug(D_WEB_CLIENT_ACCESS, "%llu: Cannot understand '%s'.", w->id, w->response.data->buffer); @@ -1373,9 +1510,11 @@ ssize_t web_client_send_chunk_header(struct web_client *w, size_t len) { debug(D_DEFLATE, "%llu: OPEN CHUNK of %zu bytes (hex: %zx).", w->id, len, len); char buf[24]; - sprintf(buf, "%zX\r\n", len); - - ssize_t bytes = send(w->ofd, buf, strlen(buf), 0); + ssize_t bytes; + bytes = (ssize_t)sprintf(buf, "%zX\r\n", len); + buf[bytes] = 0x00; + + bytes = web_client_send_data(w,buf,strlen(buf),0); if(bytes > 0) { debug(D_DEFLATE, "%llu: Sent chunk header %zd bytes.", w->id, bytes); w->stats_sent_bytes += bytes; @@ -1397,7 +1536,8 @@ ssize_t web_client_send_chunk_close(struct web_client *w) { //debug(D_DEFLATE, "%llu: CLOSE CHUNK.", w->id); - ssize_t bytes = send(w->ofd, "\r\n", 2, 0); + ssize_t bytes; + bytes = web_client_send_data(w,"\r\n",2,0); if(bytes > 0) { debug(D_DEFLATE, "%llu: Sent chunk suffix %zd bytes.", w->id, bytes); w->stats_sent_bytes += bytes; @@ -1419,7 +1559,8 @@ ssize_t web_client_send_chunk_finalize(struct web_client *w) { //debug(D_DEFLATE, "%llu: FINALIZE CHUNK.", w->id); - ssize_t bytes = send(w->ofd, "\r\n0\r\n\r\n", 7, 0); + ssize_t bytes; + bytes = web_client_send_data(w,"\r\n0\r\n\r\n",7,0); if(bytes > 0) { debug(D_DEFLATE, "%llu: Sent chunk suffix %zd bytes.", w->id, bytes); w->stats_sent_bytes += bytes; @@ -1533,7 +1674,7 @@ ssize_t web_client_send_deflate(struct web_client *w) debug(D_WEB_CLIENT, "%llu: Sending %zu bytes of data (+%zd of chunk header).", w->id, w->response.zhave - w->response.zsent, t); - len = send(w->ofd, &w->response.zbuffer[w->response.zsent], (size_t) (w->response.zhave - w->response.zsent), MSG_DONTWAIT); + len = web_client_send_data(w,&w->response.zbuffer[w->response.zsent], (size_t) (w->response.zhave - w->response.zsent), MSG_DONTWAIT); if(len > 0) { w->stats_sent_bytes += len; w->response.zsent += len; @@ -1589,7 +1730,7 @@ ssize_t web_client_send(struct web_client *w) { return 0; } - bytes = send(w->ofd, &w->response.data->buffer[w->response.sent], w->response.data->len - w->response.sent, MSG_DONTWAIT); + bytes = web_client_send_data(w,&w->response.data->buffer[w->response.sent], w->response.data->len - w->response.sent, MSG_DONTWAIT); if(likely(bytes > 0)) { w->stats_sent_bytes += bytes; w->response.sent += bytes; @@ -1664,11 +1805,26 @@ ssize_t web_client_receive(struct web_client *w) if(unlikely(w->mode == WEB_CLIENT_MODE_FILECOPY)) return web_client_read_file(w); + ssize_t bytes; + ssize_t left = w->response.data->size - w->response.data->len; + // do we have any space for more data? buffer_need_bytes(w->response.data, NETDATA_WEB_REQUEST_RECEIVE_SIZE); - ssize_t left = w->response.data->size - w->response.data->len; - ssize_t bytes = recv(w->ifd, &w->response.data->buffer[w->response.data->len], (size_t) (left - 1), MSG_DONTWAIT); +#ifdef ENABLE_HTTPS + if ( (!web_client_check_unix(w)) && (netdata_srv_ctx) ) { + if ( ( w->ssl.conn ) && (!w->ssl.flags)) { + bytes = SSL_read(w->ssl.conn, &w->response.data->buffer[w->response.data->len], (size_t) (left - 1)); + }else { + bytes = recv(w->ifd, &w->response.data->buffer[w->response.data->len], (size_t) (left - 1), MSG_DONTWAIT); + } + } + else{ + bytes = recv(w->ifd, &w->response.data->buffer[w->response.data->len], (size_t) (left - 1), MSG_DONTWAIT); + } +#else + bytes = recv(w->ifd, &w->response.data->buffer[w->response.data->len], (size_t) (left - 1), MSG_DONTWAIT); +#endif if(likely(bytes > 0)) { w->stats_received_bytes += bytes; diff --git a/web/server/web_client.h b/web/server/web_client.h index 4263e252a..0a57e8d8e 100644 --- a/web/server/web_client.h +++ b/web/server/web_client.h @@ -129,6 +129,7 @@ struct web_client { char decoded_url[NETDATA_WEB_REQUEST_URL_SIZE + 1]; // we decode the URL in this buffer char last_url[NETDATA_WEB_REQUEST_URL_SIZE+1]; // we keep a copy of the decoded URL here + char host[256]; struct timeval tv_in, tv_ready; @@ -153,6 +154,9 @@ struct web_client { // STATIC-THREADED WEB SERVER MEMBERS size_t pollinfo_slot; // POLLINFO slot of the web client size_t pollinfo_filecopy_slot; // POLLINFO slot of the file read +#ifdef ENABLE_HTTPS + struct netdata_ssl ssl; +#endif }; extern uid_t web_files_uid(void); diff --git a/web/server/web_client_cache.c b/web/server/web_client_cache.c index ab470560e..763e7e96a 100644 --- a/web/server/web_client_cache.c +++ b/web/server/web_client_cache.c @@ -6,6 +6,18 @@ // ---------------------------------------------------------------------------- // allocate and free web_clients +#ifdef ENABLE_HTTPS + +static void web_client_reuse_ssl(struct web_client *w) { + if (netdata_srv_ctx) { + if (w->ssl.conn) { + SSL_clear(w->ssl.conn); + } + } +} +#endif + + static void web_client_zero(struct web_client *w) { // zero everything about it - but keep the buffers @@ -35,6 +47,14 @@ static void web_client_free(struct web_client *w) { buffer_free(w->response.header); buffer_free(w->response.data); freez(w->user_agent); +#ifdef ENABLE_HTTPS + if ((!web_client_check_unix(w)) && ( netdata_srv_ctx )) { + if (w->ssl.conn) { + SSL_free(w->ssl.conn); + w->ssl.conn = NULL; + } + } +#endif freez(w); } @@ -159,12 +179,25 @@ struct web_client *web_client_get_from_cache_or_allocate() { if(w->prev) w->prev->next = w->next; if(w->next) w->next->prev = w->prev; web_clients_cache.avail_count--; +#ifdef ENABLE_HTTPS + web_client_reuse_ssl(w); + SSL *ssl = w->ssl.conn; +#endif web_client_zero(w); web_clients_cache.reused++; +#ifdef ENABLE_HTTPS + w->ssl.conn = ssl; + w->ssl.flags = NETDATA_SSL_START; + debug(D_WEB_CLIENT_ACCESS,"Reusing SSL structure with (w->ssl = NULL, w->accepted = %d)",w->ssl.flags); +#endif } else { // allocate it w = web_client_alloc(); +#ifdef ENABLE_HTTPS + w->ssl.flags = NETDATA_SSL_START; + debug(D_WEB_CLIENT_ACCESS,"Starting SSL structure with (w->ssl = NULL, w->accepted = %d)",w->ssl.flags); +#endif web_clients_cache.allocated++; } @@ -205,6 +238,11 @@ void web_client_release(struct web_client *w) { if (w->ifd != -1) close(w->ifd); if (w->ofd != -1 && w->ofd != w->ifd) close(w->ofd); w->ifd = w->ofd = -1; +#ifdef ENABLE_HTTPS + web_client_reuse_ssl(w); + w->ssl.flags = NETDATA_SSL_START; +#endif + } // unlink it from the used diff --git a/web/server/web_server.c b/web/server/web_server.c index 11f7edf8a..9e51c81fe 100644 --- a/web/server/web_server.c +++ b/web/server/web_server.c @@ -138,5 +138,3 @@ void web_client_initialize_connection(struct web_client *w) { web_client_cache_verify(0); } - - -- cgit v1.2.3