diff options
Diffstat (limited to 'web/gui')
-rw-r--r-- | web/gui/README.md | 18 | ||||
-rw-r--r-- | web/gui/dash-example.html | 2 | ||||
-rw-r--r-- | web/gui/dashboard_info.js | 103 | ||||
-rw-r--r-- | web/gui/goto-host-from-alarm.html | 2 | ||||
-rw-r--r-- | web/gui/main.css | 4 | ||||
-rw-r--r-- | web/gui/main.js | 55 |
6 files changed, 165 insertions, 19 deletions
diff --git a/web/gui/README.md b/web/gui/README.md index 876d499f..cb7dc898 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 55cd6400..231fec8c 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 130162be..774577a0 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 ec53df08..7d12f848 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 b6ba9591..870a1fdd 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 71af6b59..0635b07a 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/> <br/>role: <b>' + alarm.recipient + '</b><br/> <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); } } |