4 <title>netdata dashboard</title>
5 <meta name="application-name" content="netdata">
7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
9 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
10 <meta name="viewport" content="width=device-width, initial-scale=1">
11 <meta name="apple-mobile-web-app-capable" content="yes">
12 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
13 <meta name="author" content="costa@tsaousis.gr">
15 <link rel="shortcut icon" href="images/seo-performance-multi-size.ico">
17 <link rel="apple-touch-icon" href="images/seo-performance-72.png">
18 <link rel="apple-touch-icon" sizes="72x72" href="images/seo-performance-72.png">
19 <link rel="apple-touch-icon" sizes="114x114" href="images/seo-performance-114.png">
21 <link rel="icon" type="image/png" sizes="512x512" href="images/seo-performance-512.png">
22 <link rel="icon" type="image/png" sizes="256x256" href="images/seo-performance-256.png">
23 <link rel="icon" type="image/png" sizes="128x128" href="images/seo-performance-128.png">
24 <link rel="icon" type="image/png" sizes="64x64" href="images/seo-performance-64.png">
25 <link rel="icon" type="image/png" sizes="48x48" href="images/seo-performance-48.png">
26 <link rel="icon" type="image/png" sizes="32x32" href="images/seo-performance-32.png">
27 <link rel="icon" type="image/png" sizes="24x24" href="images/seo-performance-24.png">
28 <link rel="icon" type="image/png" sizes="16x16" href="images/seo-performance-16.png">
30 <meta property="og:locale" content="en_US" />
31 <meta property="og:image" content="http://my-netdata.io/images/post.png"/>
32 <meta property="og:url" content="http://my-netdata.io/"/>
33 <meta property="og:type" content="website"/>
34 <meta property="og:site_name" content="netdata"/>
35 <meta property="og:title" content="netdata - real-time performance monitoring, done right!"/>
36 <meta property="og:description" content="Stunning real-time dashboards, blazingly fast and extremely interactive. Zero configuration, zero dependencies, zero maintenance." />
40 /* prevent body from hiding under the navbar */
53 font-family: sans-serif;
54 padding: 40vh 0 40vh 0;
59 .modal-wide .modal-dialog {
63 /* fix # anchors scrolling under the navbar
64 https://github.com/twbs/bootstrap/issues/1768#issuecomment-46519033
74 h1:before, h2:before {
105 width: 90% !important;
118 /* fix the navbar shifting when a modal is open */
119 /* https://github.com/twbs/bootstrap/issues/14040#issuecomment-159891033 */
121 width: 100% !important;
122 padding-right: 0 !important;
123 /* overflow-y: scroll !important; */
124 /* position: fixed !important;*/
128 /* make accordion use the whole header bar for expand/collapse */
138 * Scrollspy and affixed enhanced navigation to highlight sections and secondary
139 * sections of docs content.
144 top: 70px !important;
153 max-height: calc(100% - 70px) !important;
155 /*width: 220px !important;*/
158 /* By default it's not affixed in mobile views, so undo that */
159 .dashboard-sidebar.affix {
163 @media (min-width: 768px) {
169 /* First level of nav */
175 /* All levels of nav */
176 .dashboard-sidebar .nav > li > a {
183 .dashboard-sidebar .nav > li > a:hover,
184 .dashboard-sidebar .nav > li > a:focus {
187 text-decoration: none;
188 background-color: transparent;
189 border-left: 1px solid #563d7c;
191 .dashboard-sidebar .nav > .active > a,
192 .dashboard-sidebar .nav > .active:hover > a,
193 .dashboard-sidebar .nav > .active:focus > a {
197 background-color: transparent;
198 border-left: 2px solid #563d7c;
201 /* Nav: second level (shown on .active) */
202 .dashboard-sidebar .nav .nav {
203 display: none; /* Hide by default, but at >768px, show it */
204 padding-bottom: 10px;
206 .dashboard-sidebar .nav .nav > li > a {
213 .dashboard-sidebar .nav .nav > li > a:hover,
214 .dashboard-sidebar .nav .nav > li > a:focus {
217 .dashboard-sidebar .nav .nav > .active > a,
218 .dashboard-sidebar .nav .nav > .active:hover > a,
219 .dashboard-sidebar .nav .nav > .active:focus > a {
227 .dropdown-menu.columns-2 {
232 .dropdown-menu li a {
236 .dropdown-menu.multi-column {
239 .multi-column-dropdown {
243 .multi-column-dropdown li a {
246 line-height: 1.428571429;
249 .multi-column-dropdown li a:hover {
250 text-decoration: none;
252 background-color: #262626;
260 /* Back to top (hidden on mobile) */
262 .dashboard-theme-toggle {
272 .dashboard-theme-toggle:hover {
274 text-decoration: none;
276 .dashboard-theme-toggle {
280 @media (min-width: 768px) {
282 .dashboard-theme-toggle {
286 /* Widen the fixed sidebar */
287 .dashboard-sidebar.affix,
288 .dashboard-sidebar.affix-top,
289 .dashboard-sidebar.affix-bottom {
290 width: 200px !important;
293 .dashboard-sidebar.affix {
294 position: fixed; /* Undo the static from mobile first approach */
298 .dashboard-sidebar.affix-bottom {
299 position: absolute; /* Undo the static from mobile first approach */
302 .dashboard-sidebar.affix-bottom .dashboard-sidenav,
303 .dashboard-sidebar.affix .dashboard-sidenav {
309 /* Show and affix the side nav when space allows it */
310 @media (min-width: 992px) {
311 .dashboard-sidebar .nav > .active > ul {
315 /* Widen the fixed sidebar */
316 .dashboard-sidebar.affix,
317 .dashboard-sidebar.affix-top,
318 .dashboard-sidebar.affix-bottom {
319 width: 200px !important;
321 .dashboard-sidebar.affix {
322 position: fixed; /* Undo the static from mobile first approach */
325 .dashboard-sidebar.affix-bottom {
326 position: absolute; /* Undo the static from mobile first approach */
328 .dashboard-sidebar.affix-bottom .dashboard-sidenav,
329 .dashboard-sidebar.affix .dashboard-sidenav {
335 @media (min-width: 1200px) {
336 /* Widen the fixed sidebar again */
337 .dashboard-sidebar.affix-bottom,
338 .dashboard-sidebar.affix-top,
339 .dashboard-sidebar.affix {
345 <!-- check which theme to use -->
346 <script type="text/javascript">
347 var netdataShowNotifications = true;
348 var netdataShowAlarms = true;
350 // --------------------------------------------------------------------
361 hasProperty: function(property) {
362 // console.log('checking property ' + property + ' of type ' + typeof(this[property]));
363 return typeof this[property] !== 'undefined';
367 function netdataPanAndZoomCallback(status, after, before) {
368 urlOptions.pan_and_zoom = status;
369 urlOptions.after = after;
370 urlOptions.before = before;
374 function netdataHashUpdate() {
375 history.replaceState(null, '', netdataHash());
378 function netdataHash() {
379 var hash = urlOptions.hash;
381 if(urlOptions.pan_and_zoom === true) {
382 hash += ';after=' + urlOptions.after.toString() +
383 ';before=' + urlOptions.before.toString();
386 if(urlOptions.theme !== null)
387 hash += ';theme=' + urlOptions.theme.toString();
389 if(urlOptions.help !== null)
390 hash += ';help=' + urlOptions.help.toString();
395 function netdataHashParse() {
396 var variables = document.location.hash.split(';');
397 var len = variables.length;
400 var p = variables[len].split('=');
401 if(urlOptions.hasProperty(p[0]) && typeof p[1] !== 'undefined')
402 urlOptions[p[0]] = p[1];
405 if(variables[len].length > 0)
406 urlOptions.hash = variables[len];
410 if(urlOptions.before > 0 && urlOptions.after > 0)
411 urlOptions.pan_and_zoom = true;
413 // console.log(urlOptions);
418 // --------------------------------------------------------------------
419 // check options that should be processed before loading netdata.js
421 function loadLocalStorage(name) {
425 if(typeof Storage !== "undefined" && typeof localStorage === 'object')
426 ret = localStorage.getItem(name);
432 if(typeof ret === 'undefined' || ret === null)
435 // console.log('loaded: ' + name.toString() + ' = ' + ret.toString());
440 function saveLocalStorage(name, value) {
441 // console.log('saving: ' + name.toString() + ' = ' + value.toString());
443 if(typeof Storage !== "undefined" && typeof localStorage === 'object') {
444 localStorage.setItem(name, value.toString());
455 function getTheme(def) {
456 var ret = loadLocalStorage('netdataTheme');
457 if(typeof ret === 'undefined' || ret === null || ret === 'undefined')
463 function setTheme(theme) {
464 if(theme === netdataTheme) return false;
465 return saveLocalStorage('netdataTheme', theme);
468 var netdataTheme = getTheme('slate');
469 var netdataShowHelp = true;
471 if(urlOptions.theme !== null) {
472 setTheme(urlOptions.theme);
473 netdataTheme = urlOptions.theme;
476 urlOptions.theme = netdataTheme;
478 if(urlOptions.help !== null) {
479 saveLocalStorage('options.show_help', urlOptions.help);
480 netdataShowHelp = urlOptions.help;
483 urlOptions.help = loadLocalStorage('options.show_help');
486 // --------------------------------------------------------------------
487 // registry call back to render my-netdata menu
489 var netdataRegistryCallback = function(machines_array) {
495 function name_comparator_desc(a, b) {
496 if (a.name > b.name) return -1;
497 if (a.name < b.name) return 1;
501 var machines = machines_array.sort(name_comparator_desc);
502 var len = machines.length;
504 var u = machines[len];
506 el += '<li id="registry_server_' + u.guid + '"><a class="registry_link" href="' + u.url + '" onClick="return gotoServerModalHandler(\'' + u.guid + '\');">' + u.name + '</a></li>';
507 a1 += '<li id="registry_action_' + u.guid + '"><a href="#" onclick="deleteRegistryModalHandler(\'' + u.guid + '\',\'' + u.name + '\',\'' + u.url + '\'); return false;"><i class="fa fa-trash-o" aria-hidden="true" style="color: #999;"></i></a></li>';
513 el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #666;" target="_blank">your netdata server list is empty...</a></li>';
515 el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #666;" target="_blank">failed to contact the registry...</a></li>';
517 a1 += '<li><a href="#" onClick="return false;"> </a></li>';
519 el += '<li role="separator" class="divider"></li>' +
520 '<li><a href="//london.netdata.rocks/default.html">EU - London (DigitalOcean.com)</a></li>' +
521 '<li><a href="//atlanta.netdata.rocks/default.html">US - Atlanta (CDN77.com)</a></li>' +
522 '<li><a href="//athens.netdata.rocks/default.html">EU - Athens</a></li>';
523 a1 += '<li role="separator" class="divider"></li>' +
524 '<li><a href="#"> </a></li>' +
525 '<li><a href="#"> </a></li>'+
526 '<li><a href="#"> </a></li>';
529 el += '<li role="separator" class="divider"></li>';
530 a1 += '<li role="separator" class="divider"></li>';
532 el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #999;" target="_blank">What is this?</a></li>';
533 a1 += '<li><a href="#" style="color: #999;" onclick="switchRegistryModalHandler(); return false;"><i class="fa fa-sliders" aria-hidden="true" style="color: #999;"></i></a></li>'
535 document.getElementById('mynetdata_servers').innerHTML = el;
536 document.getElementById('mynetdata_servers2').innerHTML = el;
537 document.getElementById('mynetdata_actions1').innerHTML = a1;
544 <!-- load the dashboard manager - it will do the rest -->
545 <script type="text/javascript" src="dashboard.js?v44"></script>
547 <body data-spy="scroll" data-target="#sidebar">
548 <div id="loadOverlay" class="loadOverlay" style="background-color: #888; color: #888;">
549 netdata<br/><div style="font-size: 3vh;">Real-time performance monitoring, done right!</div>
551 <script type="text/javascript">
552 // change the loadOverlay colors ASAP to match the theme
553 document.getElementById('loadOverlay').style = (urlOptions.theme === 'slate')?"background-color:#272b30; color: #373b40;":"background-color:#fff; color: #ddd;";
555 <nav class="navbar navbar-default navbar-fixed-top" role="banner">
556 <div class="container">
557 <nav id="mynetdata_nav" class="collapse navbar-collapse navbar-left hidden-sm hidden-xs" role="navigation" style="padding-right: 20px;">
558 <ul class="nav navbar-nav">
559 <li class="dropdown">
560 <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
561 <ul class="dropdown-menu scrollable-menu inpagemenu multi-column columns-2" role="menu">
563 <div class="col-sm-6" style="width: 85%; padding-right: 0;">
564 <ul id="mynetdata_servers" class="multi-column-dropdown">
565 <li><a href="#" onclick="return false;" style="color: #999;">loading...</a></li>
568 <div class="col-sm-3 hidden-xs" style="width: 15%; padding-left: 0;">
569 <ul id="mynetdata_actions1" class="multi-column-dropdown">
570 <li style="color: #999;"> </li>
578 <div class="navbar-header">
579 <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-collapse">
580 <span class="sr-only">Toggle navigation</span>
581 <span class="icon-bar"></span>
582 <span class="icon-bar"></span>
583 <span class="icon-bar"></span>
585 <a href="/" class="navbar-brand" id="hostname" title="reload the dashboard">netdata</a>
587 <nav class="collapse navbar-collapse navbar-right" role="navigation">
588 <ul class="nav navbar-nav">
589 <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#alarmsModal" title="alarms"><i class="fa fa-bell"></i><span id="alarms_count_badge" class="badge"></span></a></li>
590 <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal" title="dashboard settings"><i class="fa fa-sliders"></i></a></li>
591 <li class="hidden-sm"><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank" title="netdata community"><i class="fa fa-github"></i></a></li>
592 <li class="hidden-sm" id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal" title="check for update"><i class="fa fa-cloud-download"></i><span id="update_badge" class="badge"></span></a></li>
593 <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#helpModal" title="dashboard help"><i class="fa fa-question-circle"></i></a></li>
594 <li class="dropdown hidden-md hidden-lg hidden-xs">
595 <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">Menu <strong class="caret"></strong></a>
596 <ul class="dropdown-menu scrollable-menu inpagemenu" role="menu">
597 <li><a href="#" class="btn" data-toggle="modal" data-target="#alarmsModal"><i class="fa fa-bell"></i> alarms</a></li>
598 <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fa fa-sliders"></i> settings</a></li>
599 <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fa fa-github"></i> community</a></li>
600 <li><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fa fa-question-circle"></i> help</a></li>
603 <li class="dropdown hidden-sm hidden-md hidden-lg">
604 <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
605 <ul id="mynetdata_servers2" class="dropdown-menu scrollable-menu inpagemenu" role="menu">
606 <li><a href="#" onclick="return false;" style="color: #999;">loading...</a></li>
615 <div id="masthead" style="display: none;">
616 <div class="container">
618 <div class="col-md-7">
620 <p class="lead">Real-time performance monitoring, in the greatest possible detail</p>
623 <div class="col-md-5">
624 <div class="well well-lg">
626 <div class="col-md-6">
627 <b>Drag</b> charts to pan.
628 <b>Shift + wheel</b> on them, to zoom in and out.
629 <b>Double-click</b> on them, to reset.
630 <b>Hover</b> on them too!
632 <div class="col-md-6">
633 <div data-netdata="system.intr" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-dygraph-type="line" data-dygraph-strokewidth="3" data-dygraph-smooth="true" data-dygraph-highlightcirclesize="6" data-after="-90" data-height="60px" data-colors="#C66"></div>
642 <div class="container">
644 <div class="col-md-10" role="main">
645 <div id="charts_div"></div>
647 <div class="col-md-2" role="complementary">
648 <nav class="dashboard-sidebar hidden-print hidden-xs hidden-sm" id="sidebar" role="menu"></nav>
653 <div id="footer" class="container" style="display: none;">
655 <div class="col-md-10" role="main">
657 <big><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></big><br/>
658 <i class="fa fa-copyright"></i> Copyright 2016, Costa Tsaousis.<br/>
659 Released under <a href="http://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">GPL v3 or later</a>.<br/>
663 <a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a> re-distributes these software tools:
665 <i class="fa fa-circle"></i> The excellent <a href="http://dygraphs.com/" target="_blank">Dygraphs.com</a> web chart library,
666 <i class="fa fa-copyright"></i> Copyright 2009, Dan Vanderkam, <a href="http://dygraphs.com/legal.html" target="_blank">MIT License</a>
668 <i class="fa fa-circle"></i> <a href="http://omnipotent.net/jquery.sparkline/" target="_blank">jQuery Sparklines</a> web chart library,
669 <i class="fa fa-copyright"></i> Copyright 2009-2012, Splunk Inc., <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">New BSD License</a>
671 <i class="fa fa-circle"></i> <a href="http://benpickles.github.io/peity/" target="_blank">Peity</a> web chart library,
672 <i class="fa fa-copyright"></i> Copyright 2009-2015, Ben Pickles, <a href="https://github.com/benpickles/peity/blob/master/MIT-LICENCE" target="_blank">MIT License</a>
674 <i class="fa fa-circle"></i> <a href="https://rendro.github.io/easy-pie-chart/" target="_blank">Easy Pie Chart</a> web chart library,
675 <i class="fa fa-copyright"></i> Copyright 2013, Robert Fleischmann, <a href="https://github.com/rendro/easy-pie-chart/blob/master/LICENSE" target="_blank">MIT License</a>
677 <i class="fa fa-circle"></i> <a href="http://bernii.github.io/gauge.js/" target="_blank">Gauge.js</a> web chart library,
678 <i class="fa fa-copyright"></i> Copyright, Bernard Kobos, <a href="http://bernii.github.io/gauge.js/" target="_blank">MIT License</a>
680 <i class="fa fa-circle"></i> <a href="https://jquery.org/" target="_blank">jQuery</a>,
681 <i class="fa fa-copyright"></i> Copyright 2015, jQuery Foundation, <a href="https://jquery.org/license/" target="_blank">MIT License</a>
683 <i class="fa fa-circle"></i> <a href="http://getbootstrap.com/getting-started/" target="_blank">Bootstrap</a>,
684 <i class="fa fa-copyright"></i> Copyright 2015, Twitter, <a href="http://getbootstrap.com/getting-started/#license-faqs" target="_blank">MIT License</a>
686 <i class="fa fa-circle"></i> <a href="http://www.bootstraptoggle.com/" target="_blank">Bootstrap Toggle</a>,
687 <i class="fa fa-copyright"></i> Copyright (c) 2011-2014 Min Hur, The New York Times Company, <a href="https://github.com/minhur/bootstrap-toggle/blob/master/LICENSE" target="_blank">MIT License</a>
689 <i class="fa fa-circle"></i> <a href="https://jamesflorentino.github.io/nanoScrollerJS/" target="_blank">NanoScroller</a>,
690 <i class="fa fa-copyright"></i> Copyright 2012, James Florentino, <a href="https://github.com/jamesflorentino/nanoScrollerJS/blob/master/LICENSE" target="_blank">MIT License</a>
692 <i class="fa fa-circle"></i> <a href="https://github.com/marcj/css-element-queries" target="_blank">CSS Element Queries</a>,
693 <i class="fa fa-copyright"></i> Copyright Marc J. Schmidt, <a href="https://github.com/marcj/css-element-queries/blob/master/LICENSE" target="_blank">MIT License</a>
695 <i class="fa fa-circle"></i> <a href="https://fortawesome.github.io/Font-Awesome/" target="_blank">FontAwesome</a>,
696 <i class="fa fa-copyright"></i> Created by Dave Gandy, Font: <a href="http://scripts.sil.org/OFL" target="_blank">SIL OFL 1.1 License</a>, CSS: <a href="http://opensource.org/licenses/mit-license.html" target="_blank">MIT License</a>
698 <i class="fa fa-circle"></i> <a href="http://www.iconsdb.com/soylent-red-icons/seo-performance-icon.html" target="_blank">IconsDB.com Icons</a>, Icons provided as CC0 1.0 Universal (CC0 1.0) Public Domain Dedication.
700 <i class="fa fa-circle"></i> <a href="http://morrisjs.github.io/morris.js/" target="_blank">morris.js</a>,
701 <i class="fa fa-copyright"></i> Copyright 2013, Olly Smith, <a href="http://morrisjs.github.io/morris.js/" target="_blank">Simplified BSD License</a>
703 <i class="fa fa-circle"></i> <a href="http://raphaeljs.com/" target="_blank">Raphaël</a>,
704 <i class="fa fa-copyright"></i> Copyright 2008, Dmitry Baranovskiy, <a href="http://raphaeljs.com/license.html" target="_blank">MIT License</a>
706 <i class="fa fa-circle"></i> <a href="http://C3js.org/" target="_blank">C3</a>,
707 <i class="fa fa-copyright"></i> Copyright 2013, Masayuki Tanaka, <a href="https://github.com/masayuki0812/c3/blob/master/LICENSE" target="_blank">MIT License</a>
709 <i class="fa fa-circle"></i> <a href="http://D3js.org/" target="_blank">D3</a>,
710 <i class="fa fa-copyright"></i> Copyright 2015, Mike Bostock, <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">BSD License</a>
718 <div class="modal fade" id="welcomeModal" tabindex="-1" role="dialog" aria-labelledby="welcomeModalLabel">
719 <div class="modal-dialog modal-lg" role="document">
720 <div class="modal-content">
721 <div class="modal-header">
722 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
723 <h4 class="modal-title" id="welcomeModalLabel">Welcome!</h4>
725 <div class="modal-body">
727 <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> is the fastest way to visualize metrics. It is a resource efficient, highly optimized system for collecting and visualizing any type of real-time time series data, from CPU usage, disk activity, SQL queries, API calls, web site visitors, etc.
730 <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> tries to visualize the truth of <b>now</b>, in its <b>greatest detail</b>, so that you can get insights of what is happening now and what just happened, on your systems and applications.
733 To make a chart in <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b>, you just need a <b>number</b>. Just a number you can read somehow. <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> will turn this number to a real time, interactive, web chart. For collecting these numbers, it supports <a href="https://github.com/firehol/netdata/wiki/External-Plugins" target="_blank">external plugins</a>, even <a href="https://github.com/firehol/netdata/wiki/General-Info---charts.d" target="_blank">shell</a> or <a href="https://github.com/firehol/netdata/wiki/General-Info---charts.d" target="_blank">node.js</a> plugins. Any computer program, in any language, that can print a few lines of text on its standard output, can be a netdata data collector.
736 <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> can embed charts everywhere, like this one <div data-netdata="system.cpu" data-dimensions="system" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-show-value-of-system-at="system.cpu.system.modal.1"></div> (my CPU system usage which is <span id="system.cpu.system.modal.1" style="display: inline-block; width: 40px; text-align: right;"></span>%),
737 or this one <div data-netdata="ipv4.tcppackets" data-dimensions="received" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-show-value-of-received-at="ipv4.tcppackets.received.modal.1"></div> (my IPv4 received TCP packets, which are <span id="ipv4.tcppackets.received.modal.1" style="display: inline-block; width: 60px; text-align: right;"></span>/second).
740 You can have <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> charts on your site too. Just give it a <code>div</code> and a real time chart, zoomable and draggable will appear (try it even on these tiny ones - <b>drag</b> them to pan horizontally, <b>shift + drag</b> to zoom in, on <b>chrome shift + mouse wheel</b> to zoom in/out, <b>double click</b> on them to reset them - don't be afraid of <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> performance - <a href="https://github.com/firehol/netdata/wiki/Performance" target="_blank">a raspberry pi 2 can sustain 300 charts updates per second</a>!).
743 For more information please refer to the <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata wiki</a></b>.
746 <div class="modal-footer">
747 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
753 <div class="modal fade" id="helpModal" tabindex="-1" role="dialog" aria-labelledby="helpModalLabel">
754 <div class="modal-dialog modal-lg" role="document">
755 <div class="modal-content">
756 <div class="modal-header">
757 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
758 <h4 class="modal-title" id="helpModalLabel">Dashboard Help</h4>
760 <div class="modal-body">
762 <h4>Dygraphs (line, area and stacked area charts)</h4>
765 <ul class="nav nav-tabs" role="tablist">
766 <li role="presentation" class="active"><a href="#help_mouse" aria-controls="help_mouse" role="tab" data-toggle="tab">Mouse Interface</a></li>
767 <li role="presentation"><a href="#help_touch" aria-controls="help_touch" role="tab" data-toggle="tab">Touch Interface</a></li>
771 <div class="tab-content">
772 <div role="tabpanel" class="tab-pane active" id="help_mouse">
774 <h4>Mouse Over / Hover</h4>
775 Mouse over on a chart to show, at its legend, the values for the timestamp under the mouse (the chart will also highlight the point at the chart).
777 All the other visible charts will also show and highlight their values for the same timestamp.
781 <h4>Drag Chart Contents</h4>
782 Drag the contents of a chart to pan it horizontally.
784 All the charts will follow soon after you let the chart alone (this little delay is by design: it speeds up your browser and lets you focus on what you are exploring).
786 Once a chart is panned, auto refreshing stops for all charts. To enable it again, <b>double click</b> a panned chart.
790 <h4>Double Click</h4>
791 Double Click a chart to reset all the charts to their default auto-refreshing state.
795 <h4>SHIFT + Drag</h4>
796 While pressing the shift key, click on the contents of a chart and move the mouse to select an area, to zoom in. The other charts will follow too. Zooming is performed in two phases:
798 <li>The already loaded chart contents are zoomed (low resolution)</li>
799 <li>New data are transferred from the netdata server, to refresh the chart with possibly more detail.</li>
801 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
805 <h4>SHIFT + Mouse Wheel <small>(does not work on firefox and IE/Edge)</small></h4>
806 While pressing the shift key and the mouse pointer is over the contents of a chart, scroll the mouse wheel to zoom in or out. This kind of zooming is aligned to center below the mouse pointer. The other charts will follow too.
808 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
812 <h4>Legend Operations</h4>
813 Click on the label or value of a dimension, will select / un-select this dimension.
815 You can press any of the SHIFT or CONTROL keys and then click on legend labels or values, to select / un-select multiple dimensions.
818 <div role="tabpanel" class="tab-pane" id="help_touch">
821 Single Tap on the contents of a chart to show, at its legend, the values for the timestamp tapped (the chart will also highlight the point at the chart).
823 All the other visible charts will also show and highlight their values for the same timestamp.
827 <h4>Drag Chart Contents</h4>
828 Touch and Drag the contents of a chart to pan it horizontally.
830 All the charts will follow soon after you let the chart alone (this little delay is by design: it speeds up your browser and lets you focus on what you are exploring).
832 Once a chart is panned, auto refreshing stops for all charts. To enable it again, <b>double tap</b> a panned chart.
837 Double tap a chart to reset all the charts to their default auto-refreshing state.
841 <h4>Zoom <small>(does not work on firefox and IE/Edge)</small></h4>
842 With two fingers, zoom in or out.
844 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
848 <h4>Legend Operations</h4>
849 Tap on the label or value of a dimension, will select / un-select this dimension.
854 <div class="modal-footer">
855 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
861 <div class="modal fade" id="alarmsModal" tabindex="-1" role="dialog" aria-labelledby="alarmsModalLabel">
862 <div class="modal-dialog modal-lg" role="document">
863 <div class="modal-content">
864 <div class="modal-header">
865 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
866 <h4 class="modal-title" id="alarmsModalLabel">netdata alarms</h4>
868 <div class="modal-body">
870 <ul class="nav nav-tabs" role="tablist">
871 <li role="presentation" class="active"><a href="#alarms_active" aria-controls="alarms_active" role="tab" data-toggle="tab">Active</a></li>
872 <li role="presentation"><a href="#alarms_all" aria-controls="alarms_all" role="tab" data-toggle="tab">All</a></li>
873 <li role="presentation"><a href="#alarms_log" aria-controls="alarms_log" role="tab" data-toggle="tab">Log</a></li>
877 <div class="tab-content">
878 <div role="tabpanel" class="tab-pane active" id="alarms_active">
881 <div role="tabpanel" class="tab-pane" id="alarms_all">
884 <div role="tabpanel" class="tab-pane" id="alarms_log">
889 <div class="modal-footer">
890 <!-- <a href="#" onclick="alarmsUpdateModal(); return false;" type="button" class="btn btn-default">Update</a> -->
891 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
897 <div class="modal fade" id="optionsModal" tabindex="-1" role="dialog" aria-labelledby="optionsModalLabel">
898 <div class="modal-dialog modal-lg" role="document">
899 <div class="modal-content">
900 <div class="modal-header">
901 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
902 <h4 class="modal-title" id="optionsModalLabel">netdata dashboard options</h4>
904 <div class="modal-body">
906 <small style="color: #BBBBBB;">These are browser settings. Each viewer has its own. They do not affect the operation of your netdata server.
908 Settings take effect immediately and are saved permanently to browser local storage (except the refresh on focus / always option).
910 To reset all options (including charts sizes) to their defaults, click <a href="#" onclick="resetDashboardOptions(); return false;">here</a>.</small>
912 <div style="padding: 10px;"></div>
915 <ul class="nav nav-tabs" role="tablist">
916 <li role="presentation" class="active"><a href="#settings_performance" aria-controls="settings_performance" role="tab" data-toggle="tab">Performance</a></li>
917 <li role="presentation"><a href="#settings_sync" aria-controls="settings_sync" role="tab" data-toggle="tab">Synchronization</a></li>
918 <li role="presentation"><a href="#settings_visual" aria-controls="settings_visual" role="tab" data-toggle="tab">Visual</a></li>
922 <div class="tab-content">
923 <div role="tabpanel" class="tab-pane active" id="settings_performance">
924 <form id="optionsForm1" method="get" class="form-horizontal">
925 <div class="form-group">
927 <tr class="option-row">
928 <td class="option-control"><input id="stop_updates_when_focus_is_lost" type="checkbox" checked data-toggle="toggle" data-offstyle="danger" data-onstyle="success" data-on="On Focus" data-off="Always" data-width="110px"></td>
929 <td class="option-info"><strong>When to refresh the charts?</strong><br/>
930 <small>When set to <b>On Focus</b>, the charts will stop being updated if the page / tab does not have the focus of the user. When set to <b>Always</b>, the charts will always be refreshed. Set it to <b>On Focus</b> it to lower the CPU requirements of the browser (and extend the battery of laptops and tablets) when this page does not have your focus. Set to <b>Always</b> to work on another window (i.e. change the settings of something) and have the charts auto-refresh in this window.</small>
933 <tr class="option-row">
934 <td class="option-control">
935 <input id="eliminate_zero_dimensions" type="checkbox" checked data-toggle="toggle" data-on="Non Zero" data-off="All" data-width="110px">
937 <td class="option-info"><strong>Which dimensions to show?</strong><br/>
938 <small>When set to <b>Non Zero</b>, dimensions that have all their values (within the current view) set to zero will not be transferred from the netdata server (except if all dimensions of the chart are zero, in which case this setting does nothing - all dimensions are transferred and shown). When set to <b>All</b>, all dimensions will always be shown. Set it to <b>Non Zero</b> to lower the data transferred between netdata and your browser, lower the CPU requirements of your browser (fewer lines to draw) and increase the focus on the legends (fewer entries at the legends).</small>
941 <tr class="option-row">
942 <td class="option-control"><input id="destroy_on_hide" type="checkbox" data-toggle="toggle" data-on="Destroy" data-off="Hide" data-width="110px"></td>
943 <td class="option-info"><strong>How to handle hidden charts?</strong><br/>
944 <small>When set to <b>Destroy</b>, charts that are not in the current viewport of the browser (are above, or below the visible area of the page), will be destroyed and re-created if and when they become visible again. When set to <b>Hide</b>, the not-visible charts will be just hidden, to simplify the DOM and speed up your browser. Set it to <b>Destroy</b>, to lower the memory requirements of your browser. Set it to <b>Hide</b> for smoother page scrolling.</small>
951 <div role="tabpanel" class="tab-pane" id="settings_sync">
952 <form id="optionsForm2" method="get" class="form-horizontal">
953 <div class="form-group">
955 <tr class="option-row">
956 <td class="option-control"><input id="parallel_refresher" type="checkbox" checked data-toggle="toggle" data-on="Parallel" data-off="Sequential" data-width="110px"></td>
957 <td class="option-info"><strong>Which chart refresh policy to use?</strong><br/>
958 <small>When set to <b>parallel</b>, visible charts are refreshed in parallel (all queries are sent to netdata server in parallel) and are rendered asynchronously. When set to <b>sequential</b> charts are refreshed one after another. Set it to parallel if your browser can cope with it (most modern browsers do), set it to sequential if you work on an older/slower computer.</small>
961 <tr class="option-row" id="concurrent_refreshes_row">
962 <td class="option-control"></td>
963 <td class="option-info">
965 <tr class="option-row">
966 <td class="option-control">
967 <input id="concurrent_refreshes" type="checkbox" checked data-toggle="toggle" data-on="Resync" data-off="Best Effort" data-width="110px">
969 <td class="option-info">
970 <strong>Shall we re-sync chart refreshes?</strong><br/>
971 <small>When set to <b>Resync</b>, the dashboard will attempt to re-synchronize all the charts so that they are refreshed concurrently. When set to <b>Best Effort</b>, each chart may be refreshed with a little time difference to the others. Normally, the dashboard starts refreshing them in parallel, but depending on the speed of your computer and the network latencies, charts start having a slight time difference. Setting this to <b>Resync</b> will attempt to re-synchronize the charts on every update. Setting it to <b>Best Effort</b> may lower the pressure on your browser and the network.</small>
977 <tr class="option-row">
978 <td class="option-control"><input id="sync_selection" type="checkbox" checked data-toggle="toggle" data-on="Sync" data-off="Don't Sync" data-onstyle="success" data-offstyle="danger" data-width="110px"></td>
979 <td class="option-info"><strong>Sync hover selection on all charts?</strong><br/>
980 <small>When enabled, a selection on one chart will automatically select the same time on all other visible charts and the legends of all visible charts will be updated to show the selected values. When disabled, only the chart getting the user's attention will be selected. Enable it to get better insights of the data. Disable it if you are on a very slow computer that cannot actually do it.</small>
983 <tr class="option-row">
984 <td class="option-control"><input id="sync_pan_and_zoom" type="checkbox" checked data-toggle="toggle" data-on="Sync" data-off="Don't Sync" data-onstyle="success" data-offstyle="danger" data-width="110px"></td>
985 <td class="option-info"><strong>Sync pan and zoom on all charts?</strong><br/>
986 <small>When enabled, pan and zoom operations on a chart will be replicated to all charts (even the ones that are not currently visible - of course only when they will become visible). When disabled, pan and zoom operations will not be propagated to other charts.</small>
993 <div role="tabpanel" class="tab-pane" id="settings_visual">
994 <form id="optionsForm3" method="get" class="form-horizontal">
995 <div class="form-group">
997 <tr class="option-row">
998 <td class="option-control"><input id="netdata_theme_control" type="checkbox" checked data-toggle="toggle" data-offstyle="danger" data-onstyle="success" data-on="Dark" data-off="White" data-width="110px"></td>
999 <td class="option-info"><strong>Which theme to use?</strong><br/>
1000 <small>Netdata comes with two themes: <b>Dark</b> (the default) and <b>White</b>.
1002 <b>Switching this will reload the dashboard</b>.
1006 <tr class="option-row">
1007 <td class="option-control"><input id="show_help" type="checkbox" checked data-toggle="toggle" data-on="Help Me" data-off="No Help" data-width="110px"></td>
1008 <td class="option-info"><strong>Do you need help?</strong><br/>
1009 <small>Netdata can show some help in some areas to help you use the dashboard. If all these balloons bother you, disable them using this switch.
1011 <b>Switching this will reload the dashboard</b>.
1015 <tr class="option-row">
1016 <td class="option-control"><input id="pan_and_zoom_data_padding" type="checkbox" checked data-toggle="toggle" data-on="Pad" data-off="Don't Pad" data-width="110px"></td>
1017 <td class="option-info"><strong>Enable data padding when panning and zooming?</strong><br/>
1018 <small>When set to <b>Pad</b> the charts will be padded with more data, both before and after the visible area, thus giving the impression the whole database is loaded. This padding will happen only after the first pan or zoom operation on the chart (initially all charts have only the visible data). When set to <b>Don't Pad</b> only the visible data will be transfered from the netdata server, even after the first pan and zoom operation.</small>
1021 <tr class="option-row">
1022 <td class="option-control"><input id="smooth_plot" type="checkbox" checked data-toggle="toggle" data-on="Smooth" data-off="Rough" data-width="110px"></td>
1023 <td class="option-info"><strong>Enable Bézier lines on charts?</strong><br/>
1024 <small>When set to <b>Smooth</b> the charts libraries that support it, will plot smooth curves instead of simple straight lines to connect the points.
1026 Keep in mind <a href="http://dygraphs.com" target="_blank">dygraphs</a>, the main charting library in netdata dashboards, can only smooth line charts. It cannot smooth area or stacked charts. When set to <b>Rough</b>, this setting can lower the CPU resources consumed by your browser.</small>
1035 <div class="modal-footer">
1036 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1043 <div class="modal fade" id="updateModal" tabindex="-1" role="dialog" aria-labelledby="updateModalLabel">
1044 <div class="modal-dialog" role="document">
1045 <div class="modal-content">
1046 <div class="modal-header">
1047 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
1048 <h4 class="modal-title" id="updateModalLabel">Update Check</h4>
1050 <div class="modal-body">
1051 Your netdata version: <b><code><span id="netdataVersion">Unknown</span></code></b>
1053 <div style="padding: 10px;"></div>
1054 <div id="versionCheckLog">Not checked yet. Please press the Check Now button.</div>
1056 <div class="modal-footer">
1057 <a href="#" onclick="notifyForUpdate(true); return false;" type="button" class="btn btn-default">Check Now</a>
1058 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1064 <div class="modal fade" id="deleteRegistryModal" tabindex="-1" role="dialog" aria-labelledby="deleteRegistryModalLabel">
1065 <div class="modal-dialog" role="document">
1066 <div class="modal-content">
1067 <div class="modal-header">
1068 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
1069 <h4 class="modal-title" id="deleteRegistryModalLabel">Delete <span id="deleteRegistryServerName"></span>?</h4>
1071 <div class="modal-body">
1072 You are about to delete, from your personal list of netdata servers, the following server:
1073 <p style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;">
1074 <b><span id="deleteRegistryServerName2"></span></b>
1076 <b><span id="deleteRegistryServerURL"></span></b>
1078 Are you sure you want to do this?
1080 <div style="padding: 10px;"></div>
1081 <small>Keep in mind, this server will be added back if and when you visit it again.</small>
1083 <div id="deleteRegistryResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px;"></div>
1085 <div class="modal-footer">
1086 <button type="button" class="btn btn-success" data-dismiss="modal">keep it</button>
1087 <a href="#" onclick="notifyForDeleteRegistry(true); return false;" type="button" class="btn btn-danger">delete it</a>
1093 <div class="modal fade" id="switchRegistryModal" tabindex="-1" role="dialog" aria-labelledby="switchRegistryModalLabel">
1094 <div class="modal-dialog" role="document">
1095 <div class="modal-content">
1096 <div class="modal-header">
1097 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
1098 <h4 class="modal-title" id="switchRegistryModalLabel">Switch Netdata Registry Identity</h4>
1100 <div class="modal-body">
1101 You can copy and paste the following ID to all your browsers (e.g. work and home).
1103 All the browsers with the same ID will identify <b>you</b>, so please don't share this with others.
1104 <p style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;">
1106 <input type="text" class="form-control" id="switchRegistryPersonGUID" placeholder="your personal ID" maxlength="36" autocomplete="off" style="text-align: center; font-size: 1.4em;">
1109 Either copy this ID and paste it to another browser, or paste here the ID you have taken from another browser.
1110 <p style="padding-top: 10px;"><small>
1113 <li>when you switch ID, your previous ID will be lost forever - this is irreversible.</li>
1114 <li>both IDs (your old and the new) must list this netdata at their personal lists.</li>
1115 <li>both IDs have to be known by the registry: <b><span id="switchRegistryURL"></span></b>.</li>
1116 <li>to get a new ID, just clear your browser cookies.</li>
1119 <div id="switchRegistryResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px;"></div>
1121 <div class="modal-footer">
1122 <button type="button" class="btn btn-success" data-dismiss="modal">cancel</button>
1123 <a href="#" onclick="notifyForSwitchRegistry(true); return false;" type="button" class="btn btn-danger">impersonate</a>
1129 <div class="modal fade" id="gotoServerModal" tabindex="-1" role="dialog" aria-labelledby="gotoServerModalLabel">
1130 <div class="modal-dialog" role="document">
1131 <div class="modal-content">
1132 <div class="modal-header">
1133 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
1134 <h4 class="modal-title" id="gotoServerModalLabel"><span id="gotoServerName"></span></h4>
1136 <div class="modal-body">
1137 Checking known URLs for this server...
1138 <div style="padding-top: 20px;">
1139 <table id="gotoServerList">
1142 <p style="padding-top: 10px;"><small>
1143 Checks may fail if you are viewing an HTTPS page and the server to be checked is HTTP only.
1145 <div id="gotoServerResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px;"></div>
1147 <div class="modal-footer">
1148 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1154 <script type="text/javascript">
1155 var this_is_demo = null;
1157 if(this_is_demo !== null) return this_is_demo;
1158 this_is_demo = false;
1161 if(typeof document.location.hostname === 'string') {
1162 if(document.location.hostname.endsWith('.my-netdata.io') ||
1163 document.location.hostname.endsWith('.mynetdata.io') ||
1164 document.location.hostname.endsWith('.netdata.rocks') ||
1165 document.location.hostname.endsWith('.firehol.org') ||
1166 document.location.hostname.endsWith('.netdata.online'))
1167 this_is_demo = true;
1174 return this_is_demo;
1178 document.getElementById('masthead').style.display = 'block';
1181 function netdataURL(url) {
1182 if(typeof url === 'undefined')
1183 url = document.location.toString();
1185 if(url.indexOf('#') !== -1)
1186 url = url.substring(0, url.indexOf('#'));
1188 var hash = netdataHash();
1190 // console.log('netdataURL: ' + url + hash);
1195 function netdataReload(url) {
1196 var t = netdataURL(url);
1197 // console.log('netdataReload: ' + t);
1198 document.location = t;
1200 // since we play with hash
1201 // this is needed to reload the page
1205 var gotoServerValidateRemaining = 0;
1206 var gotoServerMiddleClick = false;
1207 var gotoServerStop = false;
1208 function gotoServerValidateUrl(id, guid, url) {
1210 if(document.location.toString().startsWith('http://') && url.toString().startsWith('https://'))
1211 // we penalize https only if the current url is http
1212 // to allow the user walk through all its servers.
1215 var finalURL = netdataURL(url);
1217 setTimeout(function() {
1218 document.getElementById('gotoServerList').innerHTML += '<tr><td style="padding-left: 20px;"><a href="' + finalURL + '" target="_blank">' + url + '</a></td><td style="padding-left: 30px;"><code id="' + guid + '-' + id + '-status">checking...</code></td></tr>';
1220 NETDATA.registry.hello(url, function(data) {
1222 // console.log('OK ' + id + ' URL: ' + url);
1223 document.getElementById(guid + '-' + id + '-status').innerHTML = "OK";
1225 if(!gotoServerStop) {
1226 gotoServerStop = true;
1228 if(gotoServerMiddleClick) {
1229 window.open(finalURL, '_blank');
1230 gotoServerMiddleClick = false;
1231 document.getElementById('gotoServerResponse').innerHTML = '<b>Opening new window to ' + NETDATA.registry.machines[guid].name + '<br/><a href="' + finalURL + '">' + url + '</a></b><br/>(check your pop-up blocker if it fails)';
1234 document.location = finalURL;
1238 document.getElementById(guid + '-' + id + '-status').innerHTML = "failed!";
1239 gotoServerValidateRemaining--;
1240 if(gotoServerValidateRemaining <= 0) {
1241 gotoServerMiddleClick = false;
1242 document.getElementById('gotoServerResponse').innerHTML = '<b>Sorry! I cannot find any operational URL for this server</b>';
1246 }, (id * 50) + penaldy);
1249 function gotoServerModalHandler(guid) {
1250 // console.log('goto server: ' + guid);
1252 gotoServerStop = false;
1253 var len = NETDATA.registry.machines[guid].alternate_urls.length;
1255 document.getElementById('gotoServerResponse').innerHTML = '';
1256 document.getElementById('gotoServerList').innerHTML = '';
1257 document.getElementById('gotoServerName').innerHTML = NETDATA.registry.machines[guid].name;
1258 $('#gotoServerModal').modal('show');
1260 gotoServerValidateRemaining = len;
1262 gotoServerValidateUrl(len, guid, NETDATA.registry.machines[guid].alternate_urls[len]);
1267 function gotoServerInit() {
1268 $(".registry_link").on('click', function(e) {
1271 gotoServerMiddleClick = true;
1274 gotoServerMiddleClick = false;
1281 function switchRegistryModalHandler() {
1282 document.getElementById('switchRegistryPersonGUID').value = NETDATA.registry.person_guid;
1283 document.getElementById('switchRegistryURL').innerHTML = NETDATA.registry.server;
1284 document.getElementById('switchRegistryResponse').innerHTML = '';
1285 $('#switchRegistryModal').modal('show');
1288 function notifyForSwitchRegistry() {
1289 var n = document.getElementById('switchRegistryPersonGUID').value;
1291 if(n !== '' && n.length === 36) {
1292 NETDATA.registry.switch(n, function(result) {
1293 if(result !== null) {
1294 $('#switchRegistryModal').modal('hide');
1295 NETDATA.registry.init();
1298 document.getElementById('switchRegistryResponse').innerHTML = "<b>Sorry! The registry rejected your request.</b>";
1303 document.getElementById('switchRegistryResponse').innerHTML = "<b>The ID you have entered is not a GUID.</b>";
1306 var deleteRegistryUrl = null;
1307 function deleteRegistryModalHandler(guid, name, url) {
1308 deleteRegistryUrl = url;
1309 document.getElementById('deleteRegistryServerName').innerHTML = name;
1310 document.getElementById('deleteRegistryServerName2').innerHTML = name;
1311 document.getElementById('deleteRegistryServerURL').innerHTML = url;
1312 document.getElementById('deleteRegistryResponse').innerHTML = '';
1313 $('#deleteRegistryModal').modal('show');
1316 function notifyForDeleteRegistry() {
1317 if(deleteRegistryUrl) {
1318 NETDATA.registry.delete(deleteRegistryUrl, function(result) {
1319 if(result !== null) {
1320 deleteRegistryUrl = null;
1321 $('#deleteRegistryModal').modal('hide');
1322 NETDATA.registry.init();
1325 document.getElementById('deleteRegistryResponse').innerHTML = "<b>Sorry! this command was rejected by the registry server.</b>";
1332 sparklines_registry: {},
1336 hostname: 'netdata_server', // will be overwritten by the netdata server
1337 categories: new Array(),
1339 families: new Array(),
1343 chartsMinWidth: 1450,
1345 sparklinesHeight: 60,
1348 // generate a sparkline
1349 // used in the documentation
1350 function sparkline(chart, dimension, units) {
1351 var key = chart + '.' + dimension;
1353 if(typeof units === 'undefined')
1356 if(typeof options.sparklines_registry[key] === 'undefined')
1357 options.sparklines_registry[key] = { count: 1 };
1359 options.sparklines_registry[key].count++;
1361 key = key + '.' + options.sparklines_registry[key].count;
1363 var h = '<div data-netdata="' + chart + '" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-dimensions="' + dimension + '" data-show-value-of-' + dimension + '-at="' + key + '"></div> (<span id="' + key + '" style="display: inline-block; min-width: 50px; text-align: right;">X</span>' + units + ')';
1368 function chartsPerRow(total) {
1369 if(options.chartsPerRow === 0) {
1370 width = Math.floor(total / options.chartsMinWidth);
1371 if(width === 0) width = 1;
1374 else return options.chartsPerRow;
1377 function prioritySort(a, b) {
1378 if(a.priority < b.priority) return -1;
1379 if(a.priority > b.priority) return 1;
1380 if(a.name < b.name) return -1;
1384 function sortObjectByPriority(object) {
1386 var sorted = new Array();
1388 for(var i in object) {
1389 if(typeof idx[i] === 'undefined') {
1395 sorted.sort(function(a, b) {
1396 if(idx[a].priority < idx[b].priority) return -1;
1397 if(idx[a].priority > idx[b].priority) return 1;
1398 if(a < b) return -1;
1406 // ----------------------------------------------------------------------------
1407 // scroll to a section, without changing the browser history
1409 function scrollToId(hash) {
1410 if(hash && hash != '') {
1411 var offset = $('#' + hash).offset();
1412 if(typeof offset !== 'undefined')
1413 $('html, body').animate({ scrollTop: offset.top }, 0);
1416 // we must return false to prevent the default action
1420 // ----------------------------------------------------------------------------
1422 function gaugeChart(title, width, dimensions, colors) {
1423 if(typeof colors === 'undefined')
1426 if(typeof dimensions === 'undefined')
1429 return '<div data-netdata="CHART_UNIQUE_ID"'
1430 + ' data-dimensions="' + dimensions + '"'
1431 + ' data-chart-library="gauge"'
1432 + ' data-gauge-adjust="width"'
1433 + ' data-title="' + title + '"'
1434 + ' data-width="' + width + '"'
1435 + ' data-before="0"'
1436 + ' data-after="-CHART_DURATION"'
1437 + ' data-points="CHART_DURATION"'
1438 + ' data-colors="' + colors + '"'
1439 + ' role="application"></div>';
1442 // ----------------------------------------------------------------------------
1446 title: 'System Overview',
1447 icon: '<i class="fa fa-bookmark" aria-hidden="true"></i>',
1448 info: 'Overview of the key system metrics.'
1452 title: 'Access Points',
1453 icon: '<i class="fa fa-wifi" aria-hidden="true"></i>',
1458 title: 'Quality of Service',
1459 icon: '<i class="fa fa-globe" aria-hidden="true"></i>',
1460 info: 'Netdata collects and visualizes tc class utilization using its <a href="https://github.com/firehol/netdata/blob/master/plugins.d/tc-qos-helper.sh" target="_blank">tc-helper plugin</a>. If you also use <a href="http://firehol.org/#fireqos" target="_blank">FireQOS</a> for setting up QoS, netdata automatically collects interface and class names. If your QoS configuration includes overheads calculation, the values shown here will include these overheads (the total bandwidth for the same interface as reported in the Network Interfaces section, will be lower than the total bandwidth reported here). Also, data collection may have a slight time difference compared to the interface (QoS data collection is implemented with a BASH script, so a shift in data collection of a few milliseconds should be justified).'
1464 title: 'Network Interfaces',
1465 icon: '<i class="fa fa-share-alt" aria-hidden="true"></i>',
1466 info: 'Per network interface statistics collected from <code>/proc/net/dev</code>.'
1470 title: 'IPv4 Networking',
1471 icon: '<i class="fa fa-cloud" aria-hidden="true"></i>',
1476 title: 'IPv6 Networking',
1477 icon: '<i class="fa fa-cloud" aria-hidden="true"></i>',
1482 title: 'IP Virtual Server',
1483 icon: '<i class="fa fa-eye" aria-hidden="true"></i>',
1488 title: 'Firewall (netfilter)',
1489 icon: '<i class="fa fa-shield" aria-hidden="true"></i>',
1495 icon: '<i class="fa fa-bolt" aria-hidden="true"></i>',
1501 icon: '<i class="fa fa-bolt" aria-hidden="true"></i>',
1507 icon: '<i class="fa fa-folder" aria-hidden="true"></i>',
1508 info: 'Charts with performance information for all the system disks. Special care has been given to present disk performance metrics in a way compatible with <code>iostat -x</code>. netdata by default prevents rendering performance charts for individual partitions and unmounted virtual disks. Disabled charts can still be enabled by altering the relative settings in the netdata configuration file.'
1513 icon: '<i class="fa fa-leaf" aria-hidden="true"></i>',
1518 title: 'File Server (nfsd)',
1519 icon: '<i class="fa fa-folder-open" aria-hidden="true"></i>',
1524 title: 'Applications',
1525 icon: '<i class="fa fa-heartbeat" aria-hidden="true"></i>',
1526 info: 'Per application statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics for applications of interest, defined in <code>/etc/netdata/apps_groups.conf</code> (the default is <a href="https://github.com/firehol/netdata/blob/master/conf.d/apps_groups.conf" target="_blank">here</a>). The plugin internally builds a process tree (much like <code>ps fax</code> does), and groups processes together (evaluating both child and parent processes) so that the result is always a chart with a predefined set of dimensions (of course, only application groups found running are reported). The reported values are compatible with <code>top</code>, although the netdata plugin counts also the resources of exited children (unlike <code>top</code> which shows only the resources of the currently running processes). So for processes like shell scripts, the reported values include the resources used by the commands these scripts run within each timeframe.',
1532 icon: '<i class="fa fa-user" aria-hidden="true"></i>',
1533 info: 'Per user statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics per user. The reported values are compatible with <code>top</code>, although the netdata plugin counts also the resources of exited children (unlike <code>top</code> which shows only the resources of the currently running processes). So for processes like shell scripts, the reported values include the resources used by the commands these scripts run within each timeframe.',
1538 title: 'User Groups',
1539 icon: '<i class="fa fa-users" aria-hidden="true"></i>',
1540 info: 'Per user group statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics per user group. The reported values are compatible with <code>top</code>, although the netdata plugin counts also the resources of exited children (unlike <code>top</code> which shows only the resources of the currently running processes). So for processes like shell scripts, the reported values include the resources used by the commands these scripts run within each timeframe.',
1545 title: 'Netdata Monitoring',
1546 icon: '<i class="fa fa-bar-chart" aria-hidden="true"></i>',
1551 title: 'Example Charts',
1557 icon: '<i class="fa fa-th" aria-hidden="true"></i>',
1563 icon: '<i class="fa fa-th-large" aria-hidden="true"></i>',
1569 icon: '<i class="fa fa-database" aria-hidden="true"></i>',
1575 icon: '<i class="fa fa-database" aria-hidden="true"></i>',
1581 icon: '<i class="fa fa-database" aria-hidden="true"></i>',
1587 icon: '<i class="fa fa-folder-open" aria-hidden="true"></i>',
1593 icon: '<i class="fa fa-eye" aria-hidden="true"></i>',
1599 icon: '<i class="fa fa-envelope" aria-hidden="true"></i>',
1605 icon: '<i class="fa fa-eye" aria-hidden="true"></i>',
1611 icon: '<i class="fa fa-eye" aria-hidden="true"></i>',
1617 icon: '<i class="fa fa-tag" aria-hidden="true"></i>',
1623 icon: '<i class="fa fa-exchange" aria-hidden="true"></i>',
1629 icon: '<i class="fa fa-battery-half" aria-hidden="true"></i>',
1634 title: 'Solar Power',
1635 icon: '<i class="fa fa-sun-o" aria-hidden="true"></i>',
1641 icon: '<i class="fa fa-random" aria-hidden="true"></i>',
1648 title: 'Memory Deduper',
1649 info: 'Kernel Same-page Merging (KSM) performance monitoring, read from several files in <code>/sys/kernel/mm/ksm/</code>. KSM is a memory-saving de-duplication feature in the Linux kernel (since version 2.6.32). The KSM daemon ksmd periodically scans those areas of user memory which have been registered with it, looking for pages of identical content which can be replaced by a single write-protected page (which is automatically copied if a process later wants to update its content). KSM was originally developed for use with KVM (where it was known as Kernel Shared Memory), to fit more virtual machines into physical memory, by sharing the data common between them. But it can be useful to any application which generates many instances of the same data.'
1652 'netfilter.conntrack': {
1653 title: 'Connection Tracker',
1654 info: 'Netfilter Connection Tracker performance monitoring, read from <code>/proc/net/stat/nf_conntrack</code>. The connection tracker keeps track of all connections of the machine, inbound and outbound. It works by keeping a database with all open connections, tracking network and address translation and connection expectations.'
1657 'netfilter.nfacct': {
1658 title: 'Bandwidth Accounting',
1659 info: 'The following information is read using the <code>nfacct.plugin</code>.'
1662 'netfilter.synproxy': {
1663 title: 'DDoS Protection',
1664 info: 'DDoS Protection performance monitoring read from <code>/proc/net/stat/synproxy</code>. <a href="https://github.com/firehol/firehol/wiki/Working-with-SYNPROXY" target="_blank">SYNPROXY</a> is a TCP SYN packets proxy. It is used to protect any TCP server (like a web server) from SYN floods and similar DDoS attacks. It is a netfilter module, in the Linux kernel (since version 3.12). It is optimized to handle millions of packets per second utilizing all CPUs available without any concurrency locking between the connections. It can be used for any kind of TCP traffic (even encrypted), since it does not interfere with the content itself.'
1669 // chartData works on the context of a chart
1670 // Its purpose is to set:
1672 // info: the text above the charts
1673 // heads: the representation of the chart at the top the subsection (second level menu)
1674 // mainheads: the representation of the chart at the top of the section (first level menu)
1675 // colors: the dimension colors of the chart (the default colors are appended)
1676 // height: the ratio of the chart height relative to the default
1680 info: 'Total CPU utilization (all cores). 100% here means there is no CPU idle time at all. You can get per core usage at the <a href="#cpu">CPUs</a> section and per application usage at the <a href="#apps">Applications Monitoring</a> section.<br/>Keep an eye on <b>iowait</b> ' + sparkline('system.cpu', 'iowait', '%') + '. If it is constantly high, your disks are a bottleneck and they slow your system down.<br/>Another important metric worth monitoring, is <b>softirq</b> ' + sparkline('system.cpu', 'softirq', '%') + '. A constantly high percentage of softirq may indicate network drivers issues.'
1684 info: 'Current system load, i.e. the number of processes using CPU or waiting for system resources (usually CPU and disk). The 3 metrics refer to 1, 5 and 15 minute averages. Linux calculates this once every 5 seconds. Netdata reads them from <code>/proc/loadavg</code>. For more information check <a href="https://en.wikipedia.org/wiki/Load_(computing)" target="_blank">this wikipedia article</a>',
1689 info: 'Total Disk I/O, for all disks, read from <code>/proc/vmstat</code>. You can get detailed information about each disk at the <a href="#disk">Disks</a> section and per application Disk usage at the <a href="#apps">Applications Monitoring</a> section.'
1693 info: 'Total Swap I/O, read from <code>/proc/vmstat</code>. (netdata measures both <code>in</code> and <code>out</code>. If either of them is not shown in the chart, it is because it is zero - you can change the page settings to always render all the available dimensions on all charts).'
1696 'system.pgfaults': {
1697 info: 'Total page faults, read from <code>/proc/vmstat</code>. <b>Major page faults</b> indicates that the system is using its swap. You can find which applications use the swap at the <a href="#apps">Applications Monitoring</a> section.'
1702 info: '<a href="https://en.wikipedia.org/wiki/Entropy_(computing)" target="_blank">Entropy</a>, read from <code>/proc/sys/kernel/random/entropy_avail</code>, is like a pool of random numbers that are mainly used in cryptography. It is advised that the pool remains always <a href="https://blog.cloudflare.com/ensuring-randomness-with-linuxs-random-number-generator/" target="_blank">above 200</a>. If the pool of entropy gets empty, you risk your security to be predictable and you should install a user-space random numbers generating daemon, like <a href="http://www.issihosts.com/haveged/" target="_blank">haveged</a>, to keep the pool in healthy levels.'
1707 info: 'The number of new processes created per second, read from <code>/proc/stat</code>.'
1712 info: 'Total number of CPU interrupts, read from <code>/proc/stat</code>. Check <code>system.interrupts</code> that gives more detail about each interrupt and also the <a href="#cpu">CPUs</a> section where interrupts are analyzed per CPU core.'
1715 'system.interrupts': {
1716 info: 'CPU interrupts in detail, read from <code>/proc/interrupts</code>. At the <a href="#cpu">CPUs</a> section, interrupts are analyzed per CPU core.'
1719 'system.softirqs': {
1720 info: 'CPU softirqs in detail, read from <code>/proc/softirqs</code>. At the <a href="#cpu">CPUs</a> section, softirqs are analyzed per CPU core.'
1723 'system.processes': {
1724 info: 'System processes, read from <code>/proc/stat</code>. <b>Blocked</b> are processes that are willing to execute but they cannot, e.g. because they wait for disk activity.'
1727 'system.active_processes': {
1728 info: 'All system active processes, read from <code>/proc/loadavg</code>.'
1732 info: '<a href="https://en.wikipedia.org/wiki/Context_switch" target="_blank">Context Switches</a>, read from <code>/proc/stat</code>, is the switching of the CPU from one process, task or thread to another. If there are many processes or threads willing to execute and very few CPU cores available to handle them, the system is making more context switching to balance the CPU resources among them. The whole process is computationally intensive. The more the context switches, the slower the system gets.'
1735 'system.idlejitter': {
1737 info: 'Idle jitter is calculated by netdata. A thread is spawned that requests to sleep for a few microseconds. When the system wakes it up, it measures how many microseconds have passed. The difference between the requested and the actual duration of the sleep, is the <b>idle jitter</b>. This number is useful in real-time environments, where CPU jitter can affect the quality of the service (like VoIP media gateways).'
1741 info: 'Total IPv4 Traffic, read from <code>/proc/net/netstat</code>.'
1745 info: 'Total IPv6 Traffic, read from <code>/proc/net/snmp6</code>.'
1749 info: 'System memory, read from <code>/proc/meminfo</code>.'
1753 info: 'System swap memory, read from <code>/proc/meminfo</code>.'
1756 // ------------------------------------------------------------------------
1759 'mem.ksm_savings': {
1761 gaugeChart('Saved', '12%', 'savings', '#0099CC')
1768 return '<div data-netdata="' + id + '"'
1769 + ' data-gauge-max-value="100"'
1770 + ' data-chart-library="gauge"'
1771 + ' data-title="Savings"'
1772 + ' data-units="percentage %"'
1773 + ' data-gauge-adjust="width"'
1774 + ' data-width="12%"'
1775 + ' data-before="0"'
1776 + ' data-after="-CHART_DURATION"'
1777 + ' data-points="CHART_DURATION"'
1778 + ' role="application"></div>';
1784 colors: NETDATA.colors[3]
1787 // ------------------------------------------------------------------------
1802 // ------------------------------------------------------------------------
1817 // ------------------------------------------------------------------------
1832 // ------------------------------------------------------------------------
1838 if(id.match(/.*-ifb$/))
1839 return gaugeChart('Inbound', '12%', '', '#5555AA');
1841 return gaugeChart('Outbound', '12%', '', '#AA9900');
1846 // ------------------------------------------------------------------------
1847 // NETWORK INTERFACES
1851 gaugeChart('Received', '12%', 'received'),
1852 gaugeChart('Sent', '12%', 'sent')
1856 // ------------------------------------------------------------------------
1859 'netfilter.sockets': {
1862 gaugeChart('Active Connections', '12%', '', '#88AA00')
1868 gaugeChart('New Connections', '12%', 'new', '#5555AA')
1872 // ------------------------------------------------------------------------
1878 gaugeChart('Utilization', '12%', '', '#FF5588')
1880 info: 'Disk Utilization measures the amount of time the disk was busy with something. This is not related to its performance. 100% means that the Linux kernel always had an outstanding operation on the disk. Keep in mind that depending on the underlying technology of the disk, 100% here may or may not be an indication of congestion.'
1885 info: 'Backlog is an indication of the duration of pending disk operations. On every I/O event the Linux kernel is multiplying the time spent doing I/O since the last update of this field with the number of pending operations. While not accurate, this metric can provide an indication of the expected completion time of the operations in progress.'
1890 gaugeChart('Read', '12%', 'reads'),
1891 gaugeChart('Write', '12%', 'writes')
1893 info: 'Amount of data transferred to and from disk.'
1897 info: 'Completed disk I/O operations. Keep in mind the number of operations requested might be higher, since the Linux kernel is able to merge adjacent to each other (see merged operations chart).'
1901 info: 'I/O operations currently in progress. This metric is a snapshot - it is not an average over the last interval.'
1906 info: 'The sum of the duration of all completed I/O operations. This number can exceed the interval if the disk is able to execute I/O operations in parallel.'
1910 info: 'The number of merged disk operations. The Linux kernel is able to merge adjacent I/O operations, for example two 4KB reads can become one 8KB read before given to disk.'
1914 info: 'The average service time for completed I/O operations. This metric is calculated using the total busy time of the disk and the number of completed operations. If the disk is able to execute multiple parallel operations the reporting average service time will be misleading.'
1918 info: 'The average I/O operation size.'
1922 info: 'The average time for I/O requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them.'
1926 info: 'Disk space utilization. reserved for root is automatically reserved by the system to prevent the root user from getting out of space.'
1929 info: 'inodes (or index nodes) are filesystem objects (e.g. files and directories). On many types of file system implementations, the maximum number of inodes is fixed at filesystem creation, limiting the maximum number of files the filesystem can hold. It is possible for a device to run out of inodes. When this happens, new files cannot be created on the device, even though there may be free space available.'
1933 info: 'The amount of data sent to mysql clients (<strong>out</strong>) and received from mysql clients (<strong>in</strong>).'
1936 // ------------------------------------------------------------------------
1940 info: 'The number of statements executed by the server.<ul>' +
1941 '<li><strong>queries</strong> counts the statements executed within stored SQL programs.</li>' +
1942 '<li><strong>questions</strong> counts the statements sent to the mysql server by mysql clients.</li>' +
1943 '<li><strong>slow queries</strong> counts the number of statements that took more than <a href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_long_query_time" target="_blank">long_query_time</a> seconds to be executed.' +
1944 ' For more information about slow queries check the mysql <a href="http://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html" target="_blank">slow query log</a>.</li>' +
1949 info: 'Usage of the internal handlers of mysql. This chart provides very good insights of what the mysql server is actually doing.' +
1950 ' (if the chart is not showing all these dimensions it is because they are zero - set <strong>Which dimensions to show?</strong> to <strong>All</strong> from the dashboard settings, to render even the zero values)<ul>' +
1951 '<li><strong>commit</strong>, the number of internal <a href="http://dev.mysql.com/doc/refman/5.7/en/commit.html" target="_blank">COMMIT</a> statements.</li>' +
1952 '<li><strong>delete</strong>, the number of times that rows have been deleted from tables.</li>' +
1953 '<li><strong>prepare</strong>, a counter for the prepare phase of two-phase commit operations.</li>' +
1954 '<li><strong>read first</strong>, the number of times the first entry in an index was read. A high value suggests that the server is doing a lot of full index scans; e.g. <strong>SELECT col1 FROM foo</strong>, with col1 indexed.</li>' +
1955 '<li><strong>read key</strong>, the number of requests to read a row based on a key. If this value is high, it is a good indication that your tables are properly indexed for your queries.</li>' +
1956 '<li><strong>read next</strong>, the number of requests to read the next row in key order. This value is incremented if you are querying an index column with a range constraint or if you are doing an index scan.</li>' +
1957 '<li><strong>read prev</strong>, the number of requests to read the previous row in key order. This read method is mainly used to optimize <strong>ORDER BY ... DESC</strong>.</li>' +
1958 '<li><strong>read rnd</strong>, the number of requests to read a row based on a fixed position. A high value indicates you are doing a lot of queries that require sorting of the result. You probably have a lot of queries that require MySQL to scan entire tables or you have joins that do not use keys properly.</li>' +
1959 '<li><strong>read rnd next</strong>, the number of requests to read the next row in the data file. This value is high if you are doing a lot of table scans. Generally this suggests that your tables are not properly indexed or that your queries are not written to take advantage of the indexes you have.</li>' +
1960 '<li><strong>rollback</strong>, the number of requests for a storage engine to perform a rollback operation.</li>' +
1961 '<li><strong>savepoint</strong>, the number of requests for a storage engine to place a savepoint.</li>' +
1962 '<li><strong>savepoint rollback</strong>, the number of requests for a storage engine to roll back to a savepoint.</li>' +
1963 '<li><strong>update</strong>, the number of requests to update a row in a table.</li>' +
1964 '<li><strong>write</strong>, the number of requests to insert a row in a table.</li>' +
1968 'mysql.table_locks': {
1969 info: 'MySQL table locks counters: <ul>' +
1970 '<li><strong>immediate</strong>, the number of times that a request for a table lock could be granted immediately.</li>' +
1971 '<li><strong>waited</strong>, the number of times that a request for a table lock could not be granted immediately and a wait was needed. If this is high and you have performance problems, you should first optimize your queries, and then either split your table or tables or use replication.</li>' +
1975 // ------------------------------------------------------------------------
1978 'apache.connections': {
1979 colors: NETDATA.colors[4],
1981 gaugeChart('Connections', '12%', '', NETDATA.colors[4])
1985 'apache.requests': {
1986 colors: NETDATA.colors[0],
1988 gaugeChart('Requests', '12%', '', NETDATA.colors[0])
1993 colors: NETDATA.colors[3],
1995 gaugeChart('Bandwidth', '12%', '', NETDATA.colors[3])
2002 return '<div data-netdata="' + id + '"'
2003 + ' data-dimensions="busy"'
2004 + ' data-append-options="percentage"'
2005 + ' data-gauge-max-value="100"'
2006 + ' data-chart-library="gauge"'
2007 + ' data-title="Workers Utilization"'
2008 + ' data-units="percentage %"'
2009 + ' data-gauge-adjust="width"'
2010 + ' data-width="12%"'
2011 + ' data-before="0"'
2012 + ' data-after="-CHART_DURATION"'
2013 + ' data-points="CHART_DURATION"'
2014 + ' role="application"></div>';
2019 'apache.bytesperreq': {
2020 colors: NETDATA.colors[3],
2024 'apache.reqpersec': {
2025 colors: NETDATA.colors[4],
2029 'apache.bytespersec': {
2030 colors: NETDATA.colors[6],
2035 // ------------------------------------------------------------------------
2038 'nginx.connections': {
2039 colors: NETDATA.colors[4],
2041 gaugeChart('Connections', '12%', '', NETDATA.colors[4])
2046 colors: NETDATA.colors[0],
2048 gaugeChart('Requests', '12%', '', NETDATA.colors[0])
2052 // ------------------------------------------------------------------------
2055 'netdata.response_time': {
2056 info: 'The netdata API response time measures the time netdata needed to serve requests. This time includes everything, from the reception of the first byte of a request, to the dispatch of the last byte of its reply, therefore it includes all network latencies involved (i.e. a client over a slow network will influence these metrics).'
2060 function anyAttribute(obj, attr, key, def) {
2061 if(typeof obj[key] !== 'undefined') {
2062 if(typeof obj[key][attr] !== 'undefined')
2063 return obj[key][attr];
2068 function menuTitle(chart) {
2069 if(typeof chart.menu_pattern !== 'undefined') {
2070 return (anyAttribute(menuData, 'title', chart.menu_pattern, chart.menu_pattern).toString()
2071 + ' ' + chart.type.slice(-(chart.type.length - chart.menu_pattern.length - 1)).toString()).replace(/_/g, ' ');
2074 return (anyAttribute(menuData, 'title', chart.menu, chart.menu)).toString().replace(/_/g, ' ');
2077 function menuIcon(chart) {
2078 if(typeof chart.menu_pattern !== 'undefined')
2079 return anyAttribute(menuData, 'icon', chart.menu_pattern, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>').toString();
2081 return anyAttribute(menuData, 'icon', chart.menu, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>');
2084 function menuInfo(menu) {
2085 return anyAttribute(menuData, 'info', menu, null);
2088 function menuHeight(menu, relative) {
2089 return anyAttribute(menuData, 'height', menu, 1.0) * relative;
2092 function submenuTitle(menu, submenu) {
2093 var key = menu + '.' + submenu;
2094 var title = anyAttribute(submenuData, 'title', key, submenu).toString().replace(/_/g, ' ');;
2095 if(title.length > 28) {
2096 var a = title.substring(0, 13);
2097 var b = title.substring(title.length - 12, title.length);
2098 return a + '...' + b;
2103 function submenuInfo(menu, submenu) {
2104 var key = menu + '.' + submenu;
2105 return anyAttribute(submenuData, 'info', key, null);
2108 function submenuHeight(menu, submenu, relative) {
2109 var key = menu + '.' + submenu;
2110 return anyAttribute(submenuData, 'height', key, 1.0) * relative;
2114 function chartInfo(id) {
2115 if(typeof chartData[id] !== 'undefined' && typeof chartData[id].info !== 'undefined')
2116 return '<div class="chart-message netdata-chart-alignment" role="document">' + chartData[id].info + '</div>';
2121 function chartHeight(id, def) {
2122 if(typeof chartData[id] !== 'undefined' && typeof chartData[id].height !== 'undefined')
2123 return def * chartData[id].height;
2129 // ----------------------------------------------------------------------------
2131 // enrich the data structure returned by netdata
2132 // to reflect our menu system and content
2133 function enrichChartData(chart) {
2134 var tmp = chart.type.split('_')[0];
2144 chart.menu = chart.type;
2145 if(chart.id.match(/.*[\._\/-:]qemu[\._\/-:]*/) || chart.id.match(/.*[\._\/-:]kvm[\._\/-:]*/))
2146 chart.menu_pattern = 'cgqemu';
2148 chart.menu_pattern = 'cgroup';
2166 chart.menu = chart.type;
2167 chart.menu_pattern = tmp;
2173 // find a name for this device from fireqos info
2174 // we strip '_(in|out)' or '(in|out)_'
2175 if(typeof options.submenu_names[chart.family] === 'undefined' || options.submenu_names[chart.family] === chart.family) {
2176 var n = chart.name.split('.')[1];
2177 if(n.endsWith('_in'))
2178 options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_in'));
2179 else if(n.endsWith('_out'))
2180 options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_out'));
2181 else if(n.startsWith('in_'))
2182 options.submenu_names[chart.family] = n.slice(3, n.length);
2183 else if(n.startsWith('out_'))
2184 options.submenu_names[chart.family] = n.slice(4, n.length);
2187 // increase the priority of IFB devices
2188 // to have inbound appear before outbound
2189 if(chart.id.match(/.*-ifb$/))
2195 chart.menu = chart.type;
2199 chart.submenu = chart.family;
2202 // ----------------------------------------------------------------------------
2204 function name2id(s) {
2207 .replace(/\(/g, '_')
2208 .replace(/\)/g, '_')
2209 .replace(/\./g, '_')
2210 .replace(/\//g, '_');
2213 function headMain(charts, duration) {
2216 if(typeof charts['system.swap'] !== 'undefined')
2217 head += '<div style="margin-right: 10px;" data-netdata="system.swap"'
2218 + ' data-dimensions="free"'
2219 + ' data-append-options="percentage"'
2220 + ' data-chart-library="easypiechart"'
2221 + ' data-title="Free Swap"'
2223 + ' data-easypiechart-max-value="100"'
2224 + ' data-width="8%"'
2225 + ' data-before="0"'
2226 + ' data-after="-' + duration.toString() + '"'
2227 + ' data-points="' + duration.toString() + '"'
2228 + ' data-colors="#DD4400"'
2229 + ' role="application"></div>';
2231 if(typeof charts['system.io'] !== 'undefined') {
2232 head += '<div style="margin-right: 10px;" data-netdata="system.io"'
2233 + ' data-dimensions="in"'
2234 + ' data-chart-library="easypiechart"'
2235 + ' data-title="Disk Read"'
2236 + ' data-width="10%"'
2237 + ' data-before="0"'
2238 + ' data-after="-' + duration.toString() + '"'
2239 + ' data-points="' + duration.toString() + '"'
2240 + ' role="application"></div>';
2242 head += '<div style="margin-right: 10px;" data-netdata="system.io"'
2243 + ' data-dimensions="out"'
2244 + ' data-chart-library="easypiechart"'
2245 + ' data-title="Disk Write"'
2246 + ' data-width="10%"'
2247 + ' data-before="0"'
2248 + ' data-after="-' + duration.toString() + '"'
2249 + ' data-points="' + duration.toString() + '"'
2250 + ' role="application"></div>';
2253 if(typeof charts['system.cpu'] !== 'undefined')
2254 head += '<div data-netdata="system.cpu"'
2255 + ' data-chart-library="gauge"'
2256 + ' data-title="CPU"'
2258 + ' data-gauge-max-value="100"'
2259 + ' data-width="18%"'
2260 + ' data-after="-' + duration.toString() + '"'
2261 + ' data-points="' + duration.toString() + '"'
2262 + ' data-colors="' + NETDATA.colors[12] + '"'
2263 + ' role="application"></div>';
2265 if(typeof charts['system.ipv4'] !== 'undefined') {
2266 head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
2267 + ' data-dimensions="received"'
2268 + ' data-chart-library="easypiechart"'
2269 + ' data-title="IPv4 Inbound"'
2270 + ' data-width="10%"'
2271 + ' data-before="0"'
2272 + ' data-after="-' + duration.toString() + '"'
2273 + ' data-points="' + duration.toString() + '"'
2274 + ' role="application"></div>';
2276 head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
2277 + ' data-dimensions="sent"'
2278 + ' data-chart-library="easypiechart"'
2279 + ' data-title="IPv4 Outbound"'
2280 + ' data-width="10%"'
2281 + ' data-before="0"'
2282 + ' data-after="-' + duration.toString() + '"'
2283 + ' data-points="' + duration.toString() + '"'
2284 + ' role="application"></div>';
2286 else if(typeof charts['system.ipv6'] !== 'undefined') {
2287 head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
2288 + ' data-dimensions="received"'
2289 + ' data-chart-library="easypiechart"'
2290 + ' data-title="IPv6 Inbound"'
2291 + ' data-units="kbps"'
2292 + ' data-width="10%"'
2293 + ' data-before="0"'
2294 + ' data-after="-' + duration.toString() + '"'
2295 + ' data-points="' + duration.toString() + '"'
2296 + ' role="application"></div>';
2298 head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
2299 + ' data-dimensions="sent"'
2300 + ' data-chart-library="easypiechart"'
2301 + ' data-title="IPv6 Outbound"'
2302 + ' data-units="kbps"'
2303 + ' data-width="10%"'
2304 + ' data-before="0"'
2305 + ' data-after="-' + duration.toString() + '"'
2306 + ' data-points="' + duration.toString() + '"'
2307 + ' role="application"></div>';
2310 if(typeof charts['system.ram'] !== 'undefined')
2311 head += '<div style="margin-right: 10px;" data-netdata="system.ram"'
2312 + ' data-dimensions="cached|free"'
2313 + ' data-append-options="percentage"'
2314 + ' data-chart-library="easypiechart"'
2315 + ' data-title="Available RAM"'
2317 + ' data-easypiechart-max-value="100"'
2318 + ' data-width="8%"'
2319 + ' data-after="-' + duration.toString() + '"'
2320 + ' data-points="' + duration.toString() + '"'
2321 + ' data-colors="' + NETDATA.colors[7] + '"'
2322 + ' role="application"></div>';
2327 function generateHeadCharts(type, chart, duration) {
2329 var hcharts = anyAttribute(chartData, type, chart.context, []);
2330 if(hcharts.length > 0) {
2331 var hi = 0, hlen = hcharts.length;
2333 if(typeof hcharts[hi] === 'function')
2334 head += hcharts[hi](chart.id).replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
2336 head += hcharts[hi].replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
2343 function renderPage(menus, data) {
2344 var div = document.getElementById('charts_div');
2345 var pcent_width = Math.floor(100 / chartsPerRow($(div).width()));
2347 // find the proper duration for per-second updates
2348 var duration = Math.round(($(div).width() * pcent_width / 100 * data.update_every / 3) / 60) * 60;
2350 var sidebar = '<ul class="nav dashboard-sidenav" data-spy="affix" id="sidebar_ul">';
2351 var mainhead = headMain(data.charts, duration);
2354 var main = sortObjectByPriority(menus);
2355 var i = 0, len = main.length;
2357 var menu = main[i++];
2359 // generate an entry at the main menu
2361 var menuid = name2id(menu);
2362 sidebar += '<li class=""><a href="#' + menuid + '" onClick="return scrollToId(\'' + menuid + '\');">' + menus[menu].icon + ' ' + menus[menu].title + '</a><ul class="nav">';
2363 html += '<div role="section"><div role="sectionhead"><h1 id="' + menuid + '" role="heading">' + menus[menu].title + '</h1></div><div id="menu_' + menuid + '" role="document">';
2365 if(menus[menu].info !== null)
2366 html += menus[menu].info;
2368 // console.log(' >> ' + menu + ' (' + menus[menu].priority + '): ' + menus[menu].title);
2371 var mhead = '<div class="netdata-chart-row">' + mainhead;
2374 // sort the submenus of this menu
2375 var sub = sortObjectByPriority(menus[menu].submenus);
2376 var si = 0, slen = sub.length;
2378 var submenu = sub[si++];
2380 // generate an entry at the submenu
2381 var submenuid = name2id(menu + '_' + submenu);
2382 sidebar += '<li class><a href="#' + submenuid + '" onClick="return scrollToId(\'' + submenuid + '\');">' + menus[menu].submenus[submenu].title + '</a></li>';
2383 shtml += '<div class="netdata-group-container" id="submenu_' + submenuid + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 id="' + submenuid + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>';
2385 if(menus[menu].submenus[submenu].info !== null)
2386 shtml += '<div class="chart-message netdata-chart-alignment" role="document">' + menus[menu].submenus[submenu].info + '</div>';
2388 var head = '<div class="netdata-chart-row">';
2391 // console.log(' \------- ' + submenu + ' (' + menus[menu].submenus[submenu].priority + '): ' + menus[menu].submenus[submenu].title);
2393 // sort the charts in this submenu of this menu
2394 menus[menu].submenus[submenu].charts.sort(prioritySort);
2395 var ci = 0, clen = menus[menu].submenus[submenu].charts.length;
2397 var chart = menus[menu].submenus[submenu].charts[ci++];
2399 // generate the submenu heading charts
2400 mhead += generateHeadCharts('mainheads', chart, duration);
2401 head += generateHeadCharts('heads', chart, duration);
2403 // generate the chart
2404 chtml += chartInfo(chart.context) + '<div data-netdata="' + chart.id + '"'
2405 + ' data-width="' + pcent_width.toString() + '%"'
2406 + ' data-height="' + chartHeight(chart.context, options.chartsHeight).toString() + 'px"'
2407 + ' data-before="0"'
2408 + ' data-after="-' + duration.toString() + '"'
2409 + ' data-id="' + name2id(options.hostname + '/' + chart.id) + '"'
2410 + ' data-colors="' + anyAttribute(chartData, 'colors', chart.context, '') + '"'
2411 + ' role="application"></div>';
2413 // console.log(' \------- ' + chart.id + ' (' + chart.priority + '): ' + chart.context + ' height: ' + menus[menu].submenus[submenu].height);
2417 shtml += head + chtml + '</div>';
2421 sidebar += '</ul></li>';
2422 html += mhead + shtml + '</div></div><hr role="separator"/>';
2426 div.innerHTML = html;
2427 document.getElementById('sidebar').innerHTML = sidebar;
2431 function renderChartsAndMenu(data) {
2432 var menus = options.menus;
2433 var charts = data.charts;
2435 for(var c in charts) {
2436 enrichChartData(charts[c]);
2439 if(typeof menus[charts[c].menu] === 'undefined') {
2440 menus[charts[c].menu] = {
2441 priority: charts[c].priority,
2443 title: menuTitle(charts[c]),
2444 icon: menuIcon(charts[c]),
2445 info: menuInfo(charts[c].menu),
2446 height: menuHeight(charts[c].menu, options.chartsHeight)
2450 if(charts[c].priority < menus[charts[c].menu].priority)
2451 menus[charts[c].menu].priority = charts[c].priority;
2453 // create the submenu
2454 if(typeof menus[charts[c].menu].submenus[charts[c].submenu] === 'undefined') {
2455 menus[charts[c].menu].submenus[charts[c].submenu] = {
2456 priority: charts[c].priority,
2457 charts: new Array(),
2459 info: submenuInfo(charts[c].menu, charts[c].submenu),
2460 height: submenuHeight(charts[c].menu, charts[c].submenu, menus[charts[c].menu].height)
2464 if(charts[c].priority < menus[charts[c].menu].submenus[charts[c].submenu].priority)
2465 menus[charts[c].menu].submenus[charts[c].submenu].priority = charts[c].priority;
2467 // index the chart in the menu/submenu
2468 menus[charts[c].menu].submenus[charts[c].submenu].charts.push(charts[c]);
2471 // propagate the descriptive subname given to QoS
2472 // to all the other submenus with the same name
2473 for(var m in menus) {
2474 for(var s in menus[m].submenus) {
2475 // set the family using a name
2476 if(typeof options.submenu_names[s] !== 'undefined') {
2477 menus[m].submenus[s].title = s + ' (' + options.submenu_names[s] + ')';
2480 menus[m].submenus[s].title = submenuTitle(m, s);
2485 renderPage(menus, data);
2488 // ----------------------------------------------------------------------------
2490 function alarmsUpdateModal() {
2491 var active = '<h3>Raised Alarms</h3><table class="table">';
2492 var all = '<h3>All Running Alarms</h3><div class="panel-group" id="alarms_all_accordion" role="tablist" aria-multiselectable="true">';
2493 var log = '<h3>Alarm Log</h3><table class="table"><tr><th>When</th><th>Chart</th><th>Alarm</th><th>Status</th>';
2494 var footer = '<hr/><a href="https://github.com/firehol/netdata/wiki/Generating-Badges" target="_blank">netdata badges</a> refresh automatically. Their color indicates the state of the alarm: <span style="color: #e05d44"><b> red </b></span> is critical, <span style="color:#fe7d37"><b> orange </b></span> is warning, <span style="color: #4c1"><b> bright green </b></span> is ok, <span style="color: #9f9f9f"><b> light grey </b></span> is undefined (i.e. no data or no status), <span style="color: #000"><b> black </b></span> is not initialized. You can copy and paste their URLs to embed them in any web page.';
2496 NETDATA.alarms.get('all', function(data) {
2497 options.alarm_families = new Array();
2499 alarmsCallback(data);
2502 document.getElementById('alarms_active').innerHTML =
2503 document.getElementById('alarms_all').innerHTML =
2504 document.getElementById('alarms_log').innerHTML =
2505 'failed to load alarm data!';
2509 function frequency_text(seconds, sfx) {
2516 if(sfx) suffix = ' ago';
2519 var hours = Math.floor(seconds / 3600);
2520 seconds -= (hours * 3600);
2522 var minutes = Math.floor(seconds / 60);
2523 seconds -= (minutes * 60);
2527 if(hours > 1) txt += hours.toString() + ' hours';
2528 else if(hours === 1) txt += hours.toString() + ' hour';
2530 if(hours > 0 && minutes > 0 && seconds == 0)
2531 txt += ' and ';
2532 else if(hours > 0 && minutes > 0 && seconds > 0)
2535 if(minutes > 1) txt += minutes.toString() + ' minutes';
2536 else if(minutes === 1) txt += minutes.toString() + ' minute';
2538 if((minutes > 0 || minutes > 0) && seconds > 0)
2539 txt += ' and ';
2541 if(seconds > 1) txt += seconds.toString() + ' seconds';
2542 else if(seconds === 1) txt += seconds.toString() + ' second';
2544 return txt + suffix;
2547 function alarm_lookup_explain(alarm, chart) {
2548 var dimensions = ' of all values ';
2550 if(chart.dimensions.length > 1)
2551 dimensions = ' of the sum of all dimensions ';
2553 if(typeof alarm.lookup_dimensions !== 'undefined') {
2554 var d = alarm.lookup_dimensions.replace('|', ',');
2555 var x = d.split(',');
2557 dimensions = 'of the sum of dimensions <code>' + alarm.lookup_dimensions + '</code> ';
2559 dimensions = 'of all values of dimension <code>' + alarm.lookup_dimensions + '</code> ';
2562 return '<code>' + alarm.lookup_method + '</code> '
2563 + dimensions + ', of chart <code>' + alarm.chart + '</code>'
2564 + ', starting <code>' + frequency_text(alarm.lookup_after + alarm.lookup_before, true) + '</code> and up to <code>' + frequency_text(alarm.lookup_before, true) + '</code>'
2565 + ((alarm.lookup_options)?(', with options <code>' + alarm.lookup_options.replace(' ', ', ') + '</code>'):'')
2569 function alarm_to_html(alarm, full) {
2570 var chart = options.data.charts[alarm.chart];
2572 var html = '<tr><td class="text-center" style="vertical-align:middle" width="40%"><b>' + alarm.chart + '</b><br/> <br/><embed src="' + NETDATA.alarms.server + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto" type="image/svg+xml" height="20" /><br/> <br/><span style="font-size: 18px">' + alarm.info + '</span><br/> <br/>role: <b>' + alarm.recipient + '</b></td>'
2573 + '<td><table class="table">'
2574 + ((typeof alarm.warn !== 'undefined')?('<tr><td width="10%" style="text-align:right">warning when</td><td><span style="font-family: monospace; color:#fe7d37; font-weight: bold;">' + alarm.warn + '</span></td></tr>'):'')
2575 + ((typeof alarm.crit !== 'undefined')?('<tr><td width="10%" style="text-align:right">critical when</td><td><span style="font-family: monospace; color: #e05d44; font-weight: bold;">' + alarm.crit + '</span></td></tr>'):'');
2578 html += ((typeof alarm.lookup_after !== 'undefined')?('<tr><td width="10%" style="text-align:right">db lookup</td><td>' + alarm_lookup_explain(alarm, chart) + '</td></tr>'):'')
2579 + ((typeof alarm.calc !== 'undefined')?('<tr><td width="10%" style="text-align:right">calculation</td><td><span style="font-family: monospace;">' + alarm.calc + '</span></td></tr>'):'')
2580 + ((chart.green !== null)?('<tr><td width="10%" style="text-align:right">green threshold</td><td><code>' + chart.green + ' ' + chart.units + '</code></td></tr>'):'')
2581 + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red threshold</td><td><code>' + chart.red + ' ' + chart.units + '</code></td></tr>'):'');
2584 html += '<tr><td width="10%" style="text-align:right">check every</td><td>' + frequency_text(alarm.update_every) + '</td></tr>'
2585 + '<tr><td width="10%" style="text-align:right">execute</td><td><span style="font-family: monospace;">' + alarm.exec + '</span></td></tr>'
2586 + '<tr><td width="10%" style="text-align:right">source</td><td><span style="font-family: monospace;">' + alarm.source + '</span></td></tr>'
2587 + '</table></td></tr>';
2592 function alarm_family_show(id) {
2593 var html = '<table class="table">';
2594 var family = options.alarm_families[id];
2595 var len = family.arr.length;
2597 var alarm = family.arr[len];
2598 html += alarm_to_html(alarm, true);
2602 $('#alarm_all_' + id.toString()).html(html);
2605 // find the proper family of each alarm
2606 var now = new Date().getTime();
2608 var count_active = 0;
2611 var families_sort = new Array();
2612 for(x in data.alarms) {
2613 var alarm = data.alarms[x];
2614 var family = alarm.family;
2617 var chart = options.data.charts[alarm.chart];
2618 if(typeof chart === 'undefined')
2619 chart = options.data.charts_by_name[alarm.chart];
2621 // not found - this should never happen!
2622 if(typeof chart === 'undefined') {
2623 console.log('WARNING: alarm ' + x + ' is linked to chart ' + alarm.chart + ', which is not found in the list of chart got from the server.');
2624 chart = { priority: 9999999 };
2626 else if(typeof chart.menu !== 'undefined' && typeof chart.submenu !== 'undefined')
2627 // the family based on the chart
2628 family = chart.menu + ' - ' + chart.submenu;
2630 if(typeof families[family] === 'undefined') {
2631 families[family] = {
2634 priority: chart.priority
2637 families_sort.push(families[family]);
2640 if(chart.priority < families[family].priority)
2641 families[family].priority = chart.priority;
2643 families[family].arr.push(alarm);
2646 // sort the families, like the dashboard menu does
2647 var families_sorted = families_sort.sort(function (a, b) {
2648 if (a.priority > b.priority) return -1;
2649 if (a.priority < b.priority) return 1;
2650 if (a.name < b.name) return 1;
2651 if (a.name > b.name) return -1;
2656 var len = families_sorted.length;
2658 var family = families_sorted[len].name;
2659 var active_family_added = false;
2660 var expanded = 'true';
2665 all += "</table></div></div></div>";
2667 collapsed = 'class="collapsed"'
2671 all += '<div class="panel panel-default"><div class="panel-heading" role="tab" id="alarm_all_heading_' + fc.toString() + '"><h4 class="panel-title"><a ' + collapsed + ' role="button" data-toggle="collapse" data-parent="#alarms_all_accordion" href="#alarm_all_' + fc.toString() + '" aria-expanded="' + expanded + '" aria-controls="alarm_all_' + fc.toString() + '">' + family.toString() + '</a></h4></div><div id="alarm_all_' + fc.toString() + '" class="panel-collapse collapse ' + cin + '" role="tabpanel" aria-labelledby="alarm_all_heading_' + fc.toString() + '" data-alarm-id="' + fc.toString() + '"><div class="panel-body" id="alarm_all_body_' + fc.toString() + '">';
2673 options.alarm_families[fc] = families[family];
2677 var arr = families[family].arr;
2681 if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL') {
2682 if(!active_family_added) {
2683 active_family_added = true;
2684 active += '<tr><th class="text-center" colspan="2"><h4>' + family + '</h4></th></tr>';
2687 active += alarm_to_html(alarm, false);
2693 active += "</table>";
2694 if(families_sorted.length > 0) all += "</div></div></div>";
2698 active += "<h4>Everything is normal. No raised alarms.</h4>";
2703 all += "<h4>No alarms are running in this system.</h4>";
2707 document.getElementById('alarms_active').innerHTML = active;
2708 document.getElementById('alarms_all').innerHTML = all;
2710 if(families_sorted.length > 0) alarm_family_show(0);
2712 // register bootstrap events
2713 $('#alarms_all_accordion').on('show.bs.collapse', function (d) {
2714 var target = $(d.target);
2715 var id = $(target).data('alarm-id');
2716 alarm_family_show(id);
2718 $('#alarms_all_accordion').on('hidden.bs.collapse', function (d) {
2719 var target = $(d.target);
2720 var id = $(target).data('alarm-id');
2721 $('#alarm_all_' + id.toString()).html('');
2724 NETDATA.alarms.get_log(0, function(data) {
2726 document.getElementById('alarms_log').innerHTML =
2727 'failed to load alarm data!';
2732 var len = data.length;
2733 if(len > 50) len = 50;
2735 var time = new Date(data[i].when * 1000);
2736 log += '<tr><td>' + time.toLocaleDateString() + ' ' + time.toLocaleTimeString() + '</td><td>' + data[i].chart + '</td><td>' + data[i].name + '</td><td>' + data[i].status + '</td></tr>';
2742 log += "<h4>No alarms have been logged in this system.</h4>";
2744 document.getElementById('alarms_log').innerHTML = log;
2749 function alarmsCallback(data) {
2751 for(x in data.alarms) {
2752 var alarm = data.alarms[x];
2753 if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL')
2758 document.getElementById('alarms_count_badge').innerHTML = count.toString();
2760 document.getElementById('alarms_count_badge').innerHTML = '';
2763 function downloadAllCharts(netdata_url) {
2764 if(typeof netdata_url === 'undefined' || netdata_url === null)
2765 netdata_url = NETDATA.serverDefault;
2767 NETDATA.pause(function() {
2768 $("#loadOverlay").css("display","none");
2770 NETDATA.alarms.callback = alarmsCallback;
2772 // download all the charts the server knows
2773 NETDATA.chartRegistry.downloadAll(netdata_url, function(data) {
2776 options.hostname = data.hostname;
2777 options.data = data;
2779 // create a chart_by_name index
2780 data.charts_by_name = {};
2781 var charts = data.charts;
2784 var chart = charts[x];
2785 data.charts_by_name[chart.name] = chart;
2788 // update the dashboard hostname
2789 document.getElementById('hostname').innerHTML = options.hostname;
2790 document.getElementById('hostname').href = NETDATA.serverDefault;
2792 // update the dashboard title
2793 document.title = options.hostname + ' netdata dashboard';
2795 // render all charts
2796 renderChartsAndMenu(data);
2802 // ----------------------------------------------------------------------------
2804 function versionLog(msg) {
2805 document.getElementById('versionCheckLog').innerHTML = msg;
2808 function getNetdataVersion(callback) {
2809 versionLog('Downloading installed version info from netdata...');
2816 .done(function(data) {
2817 data = data.replace(/(\r\n|\n|\r| |\t)/gm,"");
2818 if(data.length !== 40) {
2819 versionLog('Received version string is invalid.');
2823 versionLog('Installed version of netdata is ' + data);
2824 document.getElementById('netdataVersion').innerHTML = data;
2829 versionLog('Failed to download installed version info from netdata!');
2834 function getGithubLatestCommit(callback) {
2835 versionLog('Downloading latest version info from github...');
2838 url: 'https://api.github.com/repos/firehol/netdata/commits',
2842 .done(function(data) {
2843 versionLog('Latest version info from github is ' + data[0].sha);
2844 callback(data[0].sha);
2847 versionLog('Failed to download installed version info from github!');
2852 function checkForUpdate(callback) {
2853 getNetdataVersion(function(sha1) {
2854 if(sha1 === null) callback(null, null);
2856 getGithubLatestCommit(function(sha2) {
2857 callback(sha1, sha2);
2864 function notifyForUpdate(force) {
2865 versionLog('<p>checking for updates...</p>');
2867 var now = new Date().getTime();
2869 if(typeof force === 'undefined' || force !== true) {
2870 var last = loadLocalStorage('last_update_check');
2872 if(typeof last === 'string')
2873 last = parseInt(last);
2877 if(now - last < 3600000 * 8) {
2878 // no need to check it - too soon
2883 checkForUpdate(function(sha1, sha2) {
2888 versionLog('<p><big>Failed to get your netdata version!</big></p><p>You can always get the latest version of netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
2890 else if(sha2 === null) {
2892 versionLog('<p><big>Failed to get the latest version from github.</big></p><p>You can always get the latest version of netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
2894 else if(sha1 === sha2) {
2896 versionLog('<p><big>You already have the latest version of netdata!</big></p><p>No update yet?<br/>Probably, we need some motivation to keep going on!</p><p>If you haven\'t already, <a href="https://github.com/firehol/netdata" target="_blank">give netdata a <b>Star</b> at its github page</a>.</p>');
2900 var compare = 'https://github.com/firehol/netdata/compare/' + sha1.toString() + '...' + sha2.toString();
2902 versionLog('<p><big><strong>New version of netdata available!</strong></big></p><p>Latest version: ' + sha2.toString() + '</p><p><a href="' + compare + '" target="_blank">Click here for the changes log</a> since your installed version, and<br/><a href="https://github.com/firehol/netdata/wiki/Updating-Netdata" target="_blank">click here for directions on updating</a> your netdata installation.</p><p>We suggest to review the changes log for new features you may be interested, or important bug fixes you may need.<br/>Keeping your netdata updated, is generally a good idea.</p>');
2904 document.getElementById('update_badge').innerHTML = '!';
2908 saveLocalStorage('last_update_check', now.toString());
2912 // ----------------------------------------------------------------------------
2914 function finalizePage() {
2915 // resize all charts - without starting the background thread
2916 // this has to be done while NETDATA is paused
2917 // if we ommit this, the affix menu will be wrong, since all
2918 // the Dom elements are initially zero-sized
2921 if(urlOptions.pan_and_zoom === true) {
2922 urlOptions.nowelcome = true;
2923 NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], urlOptions.after, urlOptions.before);
2926 // ------------------------------------------------------------------------
2927 // https://github.com/viralpatel/jquery.shorten/blob/master/src/jquery.shorten.js
2928 $.fn.shorten = function(settings) {
2934 ellipsesText: "...",
2935 moreText: '<i class="fa fa-expand" aria-hidden="true"></i> show more information',
2936 lessText: '<i class="fa fa-compress" aria-hidden="true"></i> show less information',
2937 onLess: function() { NETDATA.onscroll(); },
2938 onMore: function() { NETDATA.onscroll(); },
2944 $.extend(config, settings);
2947 if ($(this).data('jquery.shorten') && !config.force) {
2950 $(this).data('jquery.shorten', true);
2952 $(document).off("click", '.morelink');
2957 var $this = $(this);
2958 if ($this.hasClass('less')) {
2959 $this.removeClass('less');
2960 $this.html(config.moreText);
2961 $this.parent().prev().animate({'height':'0'+'%'}, 0, function () { $this.parent().prev().prev().show(); }).hide(0, function() {
2966 $this.addClass('less');
2967 $this.html(config.lessText);
2968 $this.parent().prev().animate({'height':'100'+'%'}, 0, function () { $this.parent().prev().prev().hide(); }).show(0, function() {
2976 return this.each(function() {
2977 var $this = $(this);
2979 var content = $this.html();
2980 var contentlen = $this.text().length;
2981 if (contentlen > config.showChars + config.minHideChars) {
2982 var c = content.substr(0, config.showChars);
2983 if (c.indexOf('<') >= 0) // If there's HTML don't want to cut it
2985 var inTag = false; // I'm in a tag?
2986 var bag = ''; // Put the characters to be shown here
2987 var countChars = 0; // Current bag size
2988 var openTags = []; // Stack for opened tags, so I can close them later
2991 for (var i = 0, r = 0; r <= config.showChars; i++) {
2992 if (content[i] == '<' && !inTag) {
2995 // This could be "tag" or "/tag"
2996 tagName = content.substring(i + 1, content.indexOf('>', i));
2998 // If its a closing tag
2999 if (tagName[0] == '/') {
3002 if (tagName != '/' + openTags[0]) {
3003 config.errMsg = 'ERROR en HTML: the top of the stack should be the tag that closes';
3005 openTags.shift(); // Pops the last tag from the open tag stack (the tag is closed in the retult HTML!)
3009 // There are some nasty tags that don't have a close tag like <br/>
3010 if (tagName.toLowerCase() != 'br') {
3011 openTags.unshift(tagName); // Add to start the name of the tag that opens
3015 if (inTag && content[i] == '>') {
3019 if (inTag) { bag += content.charAt(i); } // Add tag name chars to the result
3022 if (countChars <= config.showChars) {
3023 bag += content.charAt(i); // Fix to ie 7 not allowing you to reference string characters using the []
3025 } else // Now I have the characters needed
3027 if (openTags.length > 0) // I have unclosed tags
3029 //console.log('They were open tags');
3030 //console.log(openTags);
3031 for (j = 0; j < openTags.length; j++) {
3032 //console.log('Cierro tag ' + openTags[j]);
3033 bag += '</' + openTags[j] + '>'; // Close all tags that were opened
3035 // You could shift the tag from the stack to check if you end with an empty stack, that means you have closed all open tags
3042 c = $('<div/>').html(bag + '<span class="ellip">' + config.ellipsesText + '</span>').html();
3044 c+=config.ellipsesText;
3047 var html = '<div class="shortcontent">' + c +
3048 '</div><div class="allcontent">' + content +
3049 '</div><span><a href="javascript://nop/" class="morelink">' + config.moreText + '</a></span>';
3052 $this.find(".allcontent").hide(); // Hide all text
3053 $('.shortcontent p:last', $this).css('margin-bottom', 0); //Remove bottom margin on last paragraph as it's likely shortened
3058 $(".chart-message").shorten();
3059 // ------------------------------------------------------------------------
3061 // callback for us to track PanAndZoom operations
3062 NETDATA.globalPanAndZoom.callback = netdataPanAndZoomCallback;
3064 // let it run (update the charts)
3067 // check if we have to jump to a specific section
3068 scrollToId(urlOptions.hash.replace('#',''));
3070 /* activate bootstrap sidebar (affix) */
3071 $('#sidebar').affix({
3073 top: (isdemo())?150:0,
3078 /* fix scrolling of very long affix lists
3079 http://stackoverflow.com/questions/21691585/bootstrap-3-1-0-affix-too-long
3081 $('#sidebar').on('affixed.bs.affix', function() {
3082 $(this).removeAttr('style');
3085 /* activate bootstrap scrollspy (needed for sidebar) */
3086 $(document.body).scrollspy({
3088 offset: $(window).height() / 5 // controls the diff of the <hX> element to the top, to select it
3091 // change the URL based on the current position of the screen
3092 $('#sidebar').on('activate.bs.scrollspy', function (e) {
3093 var el = $(e.target);
3094 if(el.find('ul').size() == 0) {
3095 var hash = el.find('a').attr('href');
3096 if(typeof hash === 'string' && hash.substring(0, 1) == '#') {
3097 urlOptions.hash = hash;
3098 // console.log(urlOptions.hash);
3099 netdataHashUpdate();
3104 document.getElementById('footer').style.display = 'block';
3106 var update_options_modal = function() {
3107 // console.log('update_options_modal');
3109 var sync_option = function(option) {
3110 var self = $('#' + option);
3112 if(self.prop('checked') !== NETDATA.getOption(option)) {
3113 // console.log('switching ' + option.toString());
3114 self.bootstrapToggle(NETDATA.getOption(option)?'on':'off');
3118 var theme_sync_option = function(option) {
3119 var self = $('#' + option);
3121 self.bootstrapToggle(netdataTheme === 'slate'?'on':'off');
3124 sync_option('eliminate_zero_dimensions');
3125 sync_option('destroy_on_hide');
3126 sync_option('parallel_refresher');
3127 sync_option('concurrent_refreshes');
3128 sync_option('sync_selection');
3129 sync_option('sync_pan_and_zoom');
3130 sync_option('stop_updates_when_focus_is_lost');
3131 sync_option('smooth_plot');
3132 sync_option('pan_and_zoom_data_padding');
3133 sync_option('show_help');
3134 theme_sync_option('netdata_theme_control');
3136 if(NETDATA.getOption('parallel_refresher') === false) {
3137 $('#concurrent_refreshes_row').hide();
3140 $('#concurrent_refreshes_row').show();
3143 NETDATA.setOption('setOptionCallback', update_options_modal);
3145 // handle options changes
3146 $('#eliminate_zero_dimensions').change(function() { NETDATA.setOption('eliminate_zero_dimensions', $(this).prop('checked')); });
3147 $('#destroy_on_hide').change(function() { NETDATA.setOption('destroy_on_hide', $(this).prop('checked')); });
3148 $('#parallel_refresher').change(function() { NETDATA.setOption('parallel_refresher', $(this).prop('checked')); });
3149 $('#concurrent_refreshes').change(function() { NETDATA.setOption('concurrent_refreshes', $(this).prop('checked')); });
3150 $('#sync_selection').change(function() { NETDATA.setOption('sync_selection', $(this).prop('checked')); });
3151 $('#sync_pan_and_zoom').change(function() { NETDATA.setOption('sync_pan_and_zoom', $(this).prop('checked')); });
3152 $('#stop_updates_when_focus_is_lost').change(function() { NETDATA.setOption('stop_updates_when_focus_is_lost', $(this).prop('checked')); });
3153 $('#smooth_plot').change(function() { NETDATA.setOption('smooth_plot', $(this).prop('checked')); });
3154 $('#pan_and_zoom_data_padding').change(function() { NETDATA.setOption('pan_and_zoom_data_padding', $(this).prop('checked')); });
3155 $('#show_help').change(function() {
3156 urlOptions.help = $(this).prop('checked');
3157 NETDATA.setOption('show_help', urlOptions.help);
3161 // this has to be the last
3162 // it reloads the page
3163 $('#netdata_theme_control').change(function() {
3164 urlOptions.theme = $(this).prop('checked')?'slate':'white';
3165 if(setTheme(urlOptions.theme))
3169 $('#updateModal').on('shown.bs.modal', function() {
3170 notifyForUpdate(true);
3173 $('#alarmsModal').on('shown.bs.modal', function() {
3174 NETDATA.pause(alarmsUpdateModal);
3177 $('#alarmsModal').on('hidden.bs.modal', function() {
3179 document.getElementById('alarms_active').innerHTML =
3180 document.getElementById('alarms_all').innerHTML =
3181 document.getElementById('alarms_log').innerHTML =
3185 $('#deleteRegistryModal').on('hidden.bs.modal', function() {
3186 deleteRegistryGuid = null;
3190 if(!urlOptions.nowelcome) {
3191 setTimeout(function() {
3192 $('#welcomeModal').modal();
3196 // google analytics when this is used for the home page of the demo sites
3197 // this does not run on user's installations
3198 setTimeout(function() {
3199 (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
3200 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
3201 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
3202 })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
3204 ga('create', 'UA-64295674-3', 'auto');
3205 ga('send', 'pageview');
3208 else notifyForUpdate();
3211 function resetDashboardOptions() {
3212 var help = NETDATA.options.current.show_help;
3214 NETDATA.resetOptions();
3215 if(setTheme('slate'))
3218 if(help !== NETDATA.options.current.show_help)
3222 downloadAllCharts();