summaryrefslogtreecommitdiffstats
path: root/web/gui
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2019-10-13 08:37:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2019-10-13 08:38:18 +0000
commitca540a730c0b880922e86074f994a95b8d413bea (patch)
tree1364a1b82cfcc68f51aabf9b2545e6a06059d6bb /web/gui
parentReleasing debian version 1.17.1-1. (diff)
downloadnetdata-ca540a730c0b880922e86074f994a95b8d413bea.tar.xz
netdata-ca540a730c0b880922e86074f994a95b8d413bea.zip
Merging upstream version 1.18.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'web/gui')
-rw-r--r--web/gui/README.md18
-rw-r--r--web/gui/dash-example.html2
-rw-r--r--web/gui/dashboard_info.js103
-rw-r--r--web/gui/goto-host-from-alarm.html2
-rw-r--r--web/gui/main.css4
-rw-r--r--web/gui/main.js55
6 files changed, 165 insertions, 19 deletions
diff --git a/web/gui/README.md b/web/gui/README.md
index 876d499fc..cb7dc8987 100644
--- a/web/gui/README.md
+++ b/web/gui/README.md
@@ -7,7 +7,7 @@ toolkit. You've probably seen it before:
dashboard](https://user-images.githubusercontent.com/2662304/48307727-9175c800-e55b-11e8-92d8-a581d60a4889.gif)
Learn more about how dashboards work and how they're populated using the
-`dashboards.js` file in our [web dashboards overview](../README.md).
+`dashboards.js` file in our [web dashboards overview](../).
By default, Netdata starts a web server for its dashboard at port `19999`. Open
up your web browser of choice and navigate to `http://SERVER-IP:19999`, or
@@ -34,8 +34,8 @@ dashboard](https://user-images.githubusercontent.com/1153921/62810777-ef681980-b
Netdata is broken up into multiple **sections**, such as **System Overview**,
**CPU**, **Disk**, and more. Inside each section you'll find a number of charts,
-broken down into [contexts](../README.md#contexts) and
-[families](../README.md#families).
+broken down into [contexts](../#contexts) and
+[families](../#families).
An example of the **Memory** section on a Linux desktop system.
@@ -56,7 +56,7 @@ associated with.
menu](https://user-images.githubusercontent.com/1153921/62811361-38b96880-bab6-11e9-8d41-4d9b29778e86.png)
Most menu items will contain several **submenu** entries, which represent any
-[families](../README.md#families) from that section. Netdata automatically
+[families](../#families) from that section. Netdata automatically
generates these submenu entries.
Here's a **Disks** menu with several submenu entries for each disk drive and
@@ -129,11 +129,11 @@ Edit the file with your customizations. For example:
```javascript
customDashboard.menu = {
- 'system': {
- title: 'Testing, testing, 1 2 3',
+ system: {
+ title: "Testing, testing, 1 2 3",
icon: '<i class="fas fa-thumbs-up"></i>',
- info: 'This is overwritten info for the system overview section!'
- },
+ info: "This is overwritten info for the system overview section!"
+ }
};
```
@@ -156,4 +156,4 @@ file](https://user-images.githubusercontent.com/1153921/62798924-570e6c80-ba94-1
For information on creating custom dashboards from scratch, see the [custom
dashboards](custom/) or [Atlassian Confluence dashboards](confluence/) guides.
-[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fgui%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>)
+[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fweb%2Fgui%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]()
diff --git a/web/gui/dash-example.html b/web/gui/dash-example.html
index 55cd6400c..231fec8ce 100644
--- a/web/gui/dash-example.html
+++ b/web/gui/dash-example.html
@@ -412,8 +412,6 @@ class PickNSort {
constructor (base_url, link_base_url) {
this.base_url = base_url; // URL of netdata host, with port
this.link_base_url = link_base_url || base_url; // Reverse proxy URL (Optional)
- this.link_base_url;
- this.netdata_info;
this.current_alarms = {};
this.new_alarms = {};
this.first_build = true;
diff --git a/web/gui/dashboard_info.js b/web/gui/dashboard_info.js
index 130162be3..774577a04 100644
--- a/web/gui/dashboard_info.js
+++ b/web/gui/dashboard_info.js
@@ -213,6 +213,12 @@ netdataDashboard.menu = {
info: 'Network latency statistics, via <b>fping</b>. <b>fping</b> is a program to send ICMP echo probes to network hosts, similar to <code>ping</code>, but much better performing when pinging multiple hosts. fping versions after 3.15 can be directly used as netdata plugins.'
},
+ 'gearman': {
+ title: 'Gearman',
+ icon: '<i class="fas fa-tasks"></i>',
+ info: 'Gearman is a job server that allows you to do work in parallel, to load balance processing, and to call functions between languages.'
+ },
+
'ioping': {
title: 'ioping',
icon: '<i class="fas fa-exchange-alt"></i>',
@@ -492,6 +498,24 @@ netdataDashboard.menu = {
title: 'vSphere',
icon: '<i class="fas fa-server"></i>',
info: 'Performance statistics for ESXI hosts and virtual machines. Data collected from <a href="https://www.vmware.com/products/vcenter-server.html">VMware vCenter Server</a> using <code><a href="https://github.com/vmware/govmomi"> govmomi</a></code> library.'
+ },
+
+ 'vcsa': {
+ title: 'VCSA',
+ icon: '<i class="fas fa-server"></i>',
+ info: 'vCenter Server Appliance health statistics. Data collected from <a href="https://vmware.github.io/vsphere-automation-sdk-rest/vsphere/index.html#SVC_com.vmware.appliance.health">Health API</a>.'
+ },
+
+ 'zookeeper': {
+ title: 'Zookeeper',
+ icon: '<i class="fas fa-database"></i>',
+ info: 'Provides health statistics for <b><a href="https://zookeeper.apache.org/">Zookeeper</a></b> server. Data collected through the command port using <code><a href="https://zookeeper.apache.org/doc/r3.5.5/zookeeperAdmin.html#sc_zkCommands">mntr</a></code> command.'
+ },
+
+ 'hdfs': {
+ title: 'HDFS',
+ icon: '<i class="fas fa-folder-open"></i>',
+ info: 'Provides <b><a href="https://hadoop.apache.org/docs/r3.2.0/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html">Hadoop Distributed File System</a></b> performance statistics. Module collects metrics over <code>Java Management Extensions</code> through the web interface of an <code>HDFS</code> daemon.'
}
};
@@ -1236,6 +1260,39 @@ netdataDashboard.context = {
info: 'A deadlock happens when two or more transactions mutually hold and request for locks, creating a cycle of dependencies. For more information about <a href="https://dev.mysql.com/doc/refman/5.7/en/innodb-deadlocks-handling.html" target="_blank">how to minimize and handle deadlocks</a>.'
},
+ 'mysql.galera_cluster_status': {
+ info:
+ '<code>-1</code>: unknown, ' +
+ '<code>0</code>: primary (primary group configuration, quorum present), ' +
+ '<code>1</code>: non-primary (non-primary group configuration, quorum lost), ' +
+ '<code>2</code>: disconnected(not connected to group, retrying).'
+ },
+
+ 'mysql.galera_cluster_state': {
+ info:
+ '<code>0</code>: undefined, ' +
+ '<code>1</code>: joining, ' +
+ '<code>2</code>: donor/desynced, ' +
+ '<code>3</code>: joined, ' +
+ '<code>4</code>: synced.'
+ },
+
+ 'mysql.galera_cluster_weight': {
+ info: 'The value is counted as a sum of <code>pc.weight</code> of the nodes in the current Primary Component.'
+ },
+
+ 'mysql.galera_connected': {
+ info: '<code>0</code> means that the node has not yet connected to any of the cluster components. ' +
+ 'This may be due to misconfiguration.'
+ },
+
+ 'mysql.open_transactions': {
+ info: 'The number of locally running transactions which have been registered inside the wsrep provider. ' +
+ 'This means transactions which have made operations which have caused write set population to happen. ' +
+ 'Transactions which are read only are not counted.'
+ },
+
+
// ------------------------------------------------------------------------
// POSTGRESQL
@@ -2581,5 +2638,49 @@ netdataDashboard.context = {
'vsphere.overall_status': {
info: '<code>0</code> is unknown, <code>1</code> is OK, <code>2</code> is might have a problem, <code>3</code> is definitely has a problem.'
- }
+ },
+
+ // ------------------------------------------------------------------------
+ // VCSA
+ 'vcsa.system_health': {
+ info:
+ '<code>-1</code>: unknown; ' +
+ '<code>0</code>: all components are healthy; ' +
+ '<code>1</code>: one or more components might become overloaded soon; ' +
+ '<code>2</code>: one or more components in the appliance might be degraded; ' +
+ '<code>3</code>: one or more components might be in an unusable status and the appliance might become unresponsive soon; ' +
+ '<code>4</code>: no health data is available.'
+ },
+
+ 'vcsa.components_health': {
+ info:
+ '<code>-1</code>: unknown; ' +
+ '<code>0</code>: healthy; ' +
+ '<code>1</code>: healthy, but may have some problems; ' +
+ '<code>2</code>: degraded, and may have serious problems; ' +
+ '<code>3</code>: unavailable, or will stop functioning soon; ' +
+ '<code>4</code>: no health data is available.'
+ },
+
+ 'vcsa.software_updates_health': {
+ info:
+ '<code>softwarepackages</code> represents information on available software updates available in the remote vSphere Update Manager repository.<br>' +
+ '<code>-1</code>: unknown; ' +
+ '<code>0</code>: no updates available; ' +
+ '<code>2</code>: non-security updates are available; ' +
+ '<code>3</code>: security updates are available; ' +
+ '<code>4</code>: an error retrieving information on software updates.'
+ },
+
+ // ------------------------------------------------------------------------
+ // Zookeeper
+
+ 'zookeeper.server_state': {
+ info:
+ '<code>0</code>: unknown, ' +
+ '<code>1</code>: leader, ' +
+ '<code>2</code>: follower, ' +
+ '<code>3</code>: observer, ' +
+ '<code>4</code>: standalone.'
+ }
};
diff --git a/web/gui/goto-host-from-alarm.html b/web/gui/goto-host-from-alarm.html
index ec53df084..7d12f8480 100644
--- a/web/gui/goto-host-from-alarm.html
+++ b/web/gui/goto-host-from-alarm.html
@@ -69,6 +69,7 @@ var urlOptions = {
alarm_unique_id: 0,
alarm_id: 0,
alarm_event_id: 0,
+ alarm_when: 0,
hasProperty: function(property) {
return typeof this[property] !== 'undefined';
}
@@ -101,6 +102,7 @@ function netdataURL(url) {
+ ';alarm_unique_id=' + urlOptions.alarm_unique_id.toString()
+ ';alarm_id=' + urlOptions.alarm_id.toString()
+ ';alarm_event_id=' + urlOptions.alarm_event_id.toString()
+ + ';alarm_when=' + urlOptions.alarm_when.toString()
;
}
diff --git a/web/gui/main.css b/web/gui/main.css
index b6ba95910..870a1fdd4 100644
--- a/web/gui/main.css
+++ b/web/gui/main.css
@@ -383,6 +383,10 @@ body.modal-open {
/* -------------------------------------------------------------------------- */
+#alarms_log_table tbody tr {
+ cursor: pointer;
+}
+
#my-netdata-dropdown-content {
width: 500px;
}
diff --git a/web/gui/main.js b/web/gui/main.js
index 71af6b59d..0635b07a7 100644
--- a/web/gui/main.js
+++ b/web/gui/main.js
@@ -71,6 +71,7 @@ var urlOptions = {
alarm_unique_id: 0,
alarm_id: 0,
alarm_event_id: 0,
+ alarm_when: 0,
hasProperty: function (property) {
// console.log('checking property ' + property + ' of type ' + typeof(this[property]));
@@ -139,7 +140,7 @@ var urlOptions = {
}
}
- var numeric = ['after', 'before', 'highlight_after', 'highlight_before'];
+ var numeric = ['after', 'before', 'highlight_after', 'highlight_before', 'alarm_when'];
len = numeric.length;
while (len--) {
if (typeof urlOptions[numeric[len]] === 'string') {
@@ -153,6 +154,22 @@ var urlOptions = {
}
}
+ if (urlOptions.alarm_when) {
+ // if alarm_when exists, create after/before params
+ // -/+ 2 minutes from the alarm, and reload the page
+ const alarmTime = new Date(urlOptions.alarm_when * 1000).valueOf();
+ const timeMarginMs = 120000; // 2 mins
+
+ const after = alarmTime - timeMarginMs;
+ const before = alarmTime + timeMarginMs;
+ const newHash = document.location.hash.replace(
+ /;alarm_when=[0-9]*/i,
+ ";after=" + after + ";before=" + before,
+ );
+ history.replaceState(null, '', newHash);
+ location.reload();
+ }
+
if (urlOptions.server !== null && urlOptions.server !== '') {
netdataServerStatic = document.location.origin.toString() + document.location.pathname.toString();
netdataServer = urlOptions.server;
@@ -708,7 +725,7 @@ function openAuthenticatedUrl(url) {
if (isSignedIn()) {
window.open(url);
} else {
- window.open(`${NETDATA.registry.cloudBaseURL}/account/sign-in-agent?id=${NETDATA.registry.machine_guid}&name=${encodeURIComponent(NETDATA.registry.hostname)}&origin=${encodeURIComponent(window.location.origin + "/")}&redirectUrl=${encodeURIComponent(window.location.origin + "/" + url)}`);
+ window.open(`${NETDATA.registry.cloudBaseURL}/account/sign-in-agent?id=${NETDATA.registry.machine_guid}&name=${encodeURIComponent(NETDATA.registry.hostname)}&origin=${encodeURIComponent(window.location.origin + "/")}&redirect_uri=${encodeURIComponent(window.location.origin + "/" + url)}`);
}
}
@@ -2094,7 +2111,7 @@ function alarmsUpdateModal() {
var badge_url = NETDATA.alarms.server + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto';
var action_buttons = '<br/>&nbsp;<br/>role: <b>' + alarm.recipient + '</b><br/>&nbsp;<br/>'
- + '<div class="action-button ripple" title="click to scroll the dashboard to the chart of this alarm" data-toggle="tooltip" data-placement="bottom" onClick="scrollToChartAfterHidingModal(\'' + alarm.chart + '\'); $(\'#alarmsModal\').modal(\'hide\'); return false;"><i class="fab fa-periscope"></i></div>'
+ + '<div class="action-button ripple" title="click to scroll the dashboard to the chart of this alarm" data-toggle="tooltip" data-placement="bottom" onClick="scrollToChartAfterHidingModal(\'' + alarm.chart + '\', ' + alarm.last_status_change * 1000 + ', \'' + alarm.status + '\'); $(\'#alarmsModal\').modal(\'hide\'); return false;"><i class="fab fa-periscope"></i></div>'
+ '<div class="action-button ripple" title="click to copy to the clipboard the URL of this badge" data-toggle="tooltip" data-placement="bottom" onClick="clipboardCopy(\'' + badge_url + '\'); return false;"><i class="far fa-copy"></i></div>'
+ '<div class="action-button ripple" title="click to copy to the clipboard an auto-refreshing <code>embed</code> html element for this badge" data-toggle="tooltip" data-placement="bottom" onClick="clipboardCopyBadgeEmbed(\'' + badge_url + '\'); return false;"><i class="fas fa-copy"></i></div>';
@@ -2335,6 +2352,18 @@ function alarmsUpdateModal() {
exportOptions: {
fileName: 'netdata_alarm_log'
},
+ onClickRow: function (row, $element,field) {
+ void (field);
+ void ($element);
+ let main_url;
+ let common_url = "&host=" + encodeURIComponent(row['hostname']) + "&chart=" + encodeURIComponent(row['chart']) + "&family=" + encodeURIComponent(row['family']) + "&alarm=" + encodeURIComponent(row['name']) + "&alarm_unique_id=" + row['unique_id'] + "&alarm_id=" + row['alarm_id'] + "&alarm_event_id=" + row['alarm_event_id'] + "&alarm_when=" + row['when'];
+ if (NETDATA.registry.isUsingGlobalRegistry() && NETDATA.registry.machine_guid != null) {
+ main_url = "https://netdata.cloud/alarms/redirect?agentID=" + NETDATA.registry.machine_guid + common_url;
+ } else {
+ main_url = NETDATA.registry.server + "/goto-host-from-alarm.html?" + common_url ;
+ }
+ window.open(main_url,"_blank");
+ },
rowStyle: function (row, index) {
void (index);
@@ -3965,9 +3994,21 @@ function scrollDashboardTo() {
var modalHiddenCallback = null;
-function scrollToChartAfterHidingModal(chart) {
+function scrollToChartAfterHidingModal(chart, alarmDate, alarmStatus) {
modalHiddenCallback = function () {
- NETDATA.alarms.scrollToChart(chart);
+ NETDATA.alarms.scrollToChart(chart, alarmDate);
+
+ if (['WARNING', 'CRITICAL'].includes(alarmStatus)) {
+ const currentChartState = NETDATA.options.targets.find(
+ (chartState) => chartState.id === chart,
+ )
+ const twoMinutes = 2 * 60 * 1000
+ NETDATA.globalPanAndZoom.setMaster(
+ currentChartState,
+ alarmDate - twoMinutes,
+ alarmDate + twoMinutes,
+ )
+ }
};
}
@@ -4914,8 +4955,8 @@ function handleSignInMessage(e) {
cloudToken = e.data.token;
netdataRegistryCallback(registryAgents);
- if (e.data.redirectUrl) {
- window.location.replace(e.data.redirectUrl);
+ if (e.data.redirectURI && !window.location.href.includes(e.data.redirectURI)) {
+ window.location.replace(e.data.redirectURI);
}
}