]> arthur.barton.de Git - netdata.git/blob - web/index.html
Merge pull request #334 from simonnagl/bugfix/sh_arithmetic_expand
[netdata.git] / web / index.html
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4         <title>netdata dashboard</title>
5
6         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7         <meta charset="utf-8">
8         <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
9         <meta name="viewport" content="width=device-width, initial-scale=1">
10         <meta name="apple-mobile-web-app-capable" content="yes">
11         <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
12         <meta name="author" content="costa@tsaousis.gr">
13
14         <link rel="shortcut icon" href="images/seo-performance-multi-size.ico">
15
16         <link rel="apple-touch-icon" href="images/seo-performance-72.png">
17         <link rel="apple-touch-icon" sizes="72x72" href="images/seo-performance-72.png">
18         <link rel="apple-touch-icon" sizes="114x114" href="images/seo-performance-114.png">
19
20         <link rel="icon" type="image/png" sizes="512x512" href="images/seo-performance-512.png">
21         <link rel="icon" type="image/png" sizes="256x256" href="images/seo-performance-256.png">
22         <link rel="icon" type="image/png" sizes="128x128" href="images/seo-performance-128.png">
23         <link rel="icon" type="image/png" sizes="64x64" href="images/seo-performance-64.png">
24         <link rel="icon" type="image/png" sizes="48x48" href="images/seo-performance-48.png">
25         <link rel="icon" type="image/png" sizes="32x32" href="images/seo-performance-32.png">
26         <link rel="icon" type="image/png" sizes="24x24" href="images/seo-performance-24.png">
27         <link rel="icon" type="image/png" sizes="16x16" href="images/seo-performance-16.png">
28
29         <style>
30
31         /* prevent body from hiding under the navbar */
32         body {
33                 padding-top: 50px;
34         }
35
36         .modal-wide .modal-dialog {
37                 width: 80%;
38         }
39
40         /* fix # anchors scrolling under the navbar
41            https://github.com/twbs/bootstrap/issues/1768#issuecomment-46519033
42          */
43         h1 {
44                 position: relative;
45                 z-index: -1;
46         }
47         h2 {
48                 position: relative;
49                 z-index: -2;
50         }
51         h1:before, h2:before {
52                 display: block;
53                 content: " ";
54                 margin-top: -70px;
55                 height: 70px;
56                 visibility: hidden;
57         }
58
59         .p {
60                 display: block;
61                 margin-top: 15px;
62         }
63
64         .option-row,
65         .option-control {
66                 vertical-align: top;
67                 padding: 10px;
68                 padding-top: 30px;
69                 padding-left: 30px;
70         }
71
72         .option-info {
73                 padding: 10px;
74         }
75
76         .chart-message {
77                 display: block;
78                 margin-top: 10px;
79         }
80
81         .container {
82                 width: 90% !important;
83         }
84
85         #masthead h1 {
86                 /*font-size: 30px;*/
87                 line-height: 1;
88                 padding-top: 30px;
89         }
90
91         #masthead .well {
92                 margin-top:4%;
93         }
94
95         /* fix the navbar shifting when a modal is open */
96         /* https://github.com/twbs/bootstrap/issues/14040#issuecomment-159891033 */
97         body.modal-open{
98                 width: 100% !important;
99                 padding-right: 0 !important;
100 /*              overflow-y: scroll !important; */
101 /*              position: fixed !important;*/
102                 overflow: visible;
103         }
104
105         /*
106          * Side navigation
107          *
108          * Scrollspy and affixed enhanced navigation to highlight sections and secondary
109          * sections of docs content.
110          */
111
112         .affix {
113                 position: static;
114                 top: 70px !important;
115                 /*width: 220px;*/
116         }
117
118         .affix-top {
119                 /*width: 220px;*/
120         }
121
122         .dashboard-sidebar {
123                 max-height: calc(100% - 70px) !important;
124                 overflow-y: auto;
125                 /*width: 220px !important;*/
126         }
127
128         /* By default it's not affixed in mobile views, so undo that */
129         .dashboard-sidebar.affix {
130                 position: static;
131         }
132
133         @media (min-width: 768px) {
134                 .dashboard-sidebar {
135                         padding-left: 20px;
136                 }
137         }
138
139         /* First level of nav */
140         .dashboard-sidenav {
141                 margin-top: 20px;
142                 margin-bottom: 20px;
143         }
144
145         /* All levels of nav */
146         .dashboard-sidebar .nav > li > a {
147                 display: block;
148                 padding: 4px 20px;
149                 font-size: 13px;
150                 font-weight: 500;
151                 color: #767676;
152         }
153         .dashboard-sidebar .nav > li > a:hover,
154         .dashboard-sidebar .nav > li > a:focus {
155                 padding-left: 19px;
156                 color: #563d7c;
157                 text-decoration: none;
158                 background-color: transparent;
159                 border-left: 1px solid #563d7c;
160         }
161         .dashboard-sidebar .nav > .active > a,
162         .dashboard-sidebar .nav > .active:hover > a,
163         .dashboard-sidebar .nav > .active:focus > a {
164                 padding-left: 18px;
165                 font-weight: bold;
166                 color: #563d7c;
167                 background-color: transparent;
168                 border-left: 2px solid #563d7c;
169         }
170
171         /* Nav: second level (shown on .active) */
172         .dashboard-sidebar .nav .nav {
173                 display: none; /* Hide by default, but at >768px, show it */
174                 padding-bottom: 10px;
175         }
176         .dashboard-sidebar .nav .nav > li > a {
177                 padding-top: 1px;
178                 padding-bottom: 1px;
179                 padding-left: 30px;
180                 font-size: 12px;
181                 font-weight: normal;
182         }
183         .dashboard-sidebar .nav .nav > li > a:hover,
184         .dashboard-sidebar .nav .nav > li > a:focus {
185                 padding-left: 29px;
186         }
187         .dashboard-sidebar .nav .nav > .active > a,
188         .dashboard-sidebar .nav .nav > .active:hover > a,
189         .dashboard-sidebar .nav .nav > .active:focus > a {
190                 padding-left: 28px;
191                 font-weight: 500;
192         }
193
194         /* Back to top (hidden on mobile) */
195         .back-to-top,
196         .dashboard-theme-toggle {
197                 display: none;
198                 padding: 4px 10px;
199                 margin-top: 10px;
200                 margin-left: 10px;
201                 font-size: 12px;
202                 font-weight: 500;
203                 color: #999;
204         }
205         .back-to-top:hover,
206         .dashboard-theme-toggle:hover {
207                 color: #563d7c;
208                 text-decoration: none;
209         }
210         .dashboard-theme-toggle {
211                 margin-top: 0;
212         }
213
214         @media (min-width: 768px) {
215                 .back-to-top,
216                 .dashboard-theme-toggle {
217                         display: block;
218                 }
219
220                 /* Widen the fixed sidebar */
221                 .dashboard-sidebar.affix,
222                 .dashboard-sidebar.affix-top,
223                 .dashboard-sidebar.affix-bottom {
224                         width: 200px !important;
225                 }
226
227                 .dashboard-sidebar.affix {
228                         position: fixed; /* Undo the static from mobile first approach */
229                         top: 20px;
230                 }
231
232                 .dashboard-sidebar.affix-bottom {
233                         position: absolute; /* Undo the static from mobile first approach */
234                 }
235
236                 .dashboard-sidebar.affix-bottom .dashboard-sidenav,
237                 .dashboard-sidebar.affix .dashboard-sidenav {
238                         margin-top: 0;
239                         margin-bottom: 0;
240                 }
241         }
242
243         /* Show and affix the side nav when space allows it */
244         @media (min-width: 992px) {
245                 .dashboard-sidebar .nav > .active > ul {
246                         display: block;
247                 }
248
249                 /* Widen the fixed sidebar */
250                 .dashboard-sidebar.affix,
251                 .dashboard-sidebar.affix-top,
252                 .dashboard-sidebar.affix-bottom {
253                         width: 200px !important;
254                 }
255                 .dashboard-sidebar.affix {
256                         position: fixed; /* Undo the static from mobile first approach */
257                         top: 20px;
258                 }
259                 .dashboard-sidebar.affix-bottom {
260                         position: absolute; /* Undo the static from mobile first approach */
261                 }
262                 .dashboard-sidebar.affix-bottom .dashboard-sidenav,
263                 .dashboard-sidebar.affix .dashboard-sidenav {
264                         margin-top: 0;
265                         margin-bottom: 0;
266                 }
267         }
268
269         @media (min-width: 1200px) {
270                 /* Widen the fixed sidebar again */
271                 .dashboard-sidebar.affix-bottom,
272                 .dashboard-sidebar.affix-top,
273                 .dashboard-sidebar.affix {
274                         width: 263px;
275                 }
276         }
277         </style>
278
279         <!-- you can set your netdata server globally, by ucommenting this -->
280         <!-- you can also give a different server per chart, with the attribute: data-host="http://netdata.server:19999" -->
281         <!-- <script> netdataServer = "http://box:19999"; </script> -->
282
283         <!-- check which theme to use -->
284         <script>
285                 function loadLocalStorage(name) {
286                         var ret = null;
287
288                         try {
289                                 if(typeof Storage !== "undefined" && typeof localStorage === 'object')
290                                         ret = localStorage.getItem(name);
291                         }
292                         catch(error) {
293                                 ;
294                         }
295
296                         if(typeof ret === 'undefined' || ret === null)
297                                 return null;
298
299                         return ret;
300                 }
301
302                 function saveLocalStorage(name, value) {
303                         try {
304                                 if(typeof Storage !== "undefined" && typeof localStorage === 'object') {
305                                         localStorage.setItem(name, value.toString());
306                                         return true;
307                                 }
308                         }
309                         catch(error) {
310                                 ;
311                         }
312
313                         return false;
314                 }
315
316                 function getTheme(def) {
317                         var ret = loadLocalStorage('netdataTheme');
318                         if(typeof ret === 'undefined' || ret === null || ret === 'undefined')
319                                 return def;
320                         else
321                                 return ret;
322                 }
323                 var netdataTheme = getTheme('slate');
324
325                 function setTheme(theme) {
326                         if(theme === netdataTheme) return false;
327
328                         return saveLocalStorage('netdataTheme', theme);
329                 }
330         </script>
331
332         <!-- load the dashboard manager - it will do the rest -->
333         <script type="text/javascript" src="dashboard.js?v34"></script>
334 </head>
335
336 <body data-spy="scroll" data-target="#sidebar">
337         <nav class="navbar navbar-default navbar-fixed-top" role="banner">
338                 <div class="container">
339                         <div class="navbar-header">
340                                 <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-collapse">
341                                         <span class="sr-only">Toggle navigation</span>
342                                         <span class="icon-bar"></span>
343                                         <span class="icon-bar"></span>
344                                         <span class="icon-bar"></span>
345                                 </button>
346                                 <a href="/" class="navbar-brand" id="hostname">netdata</a>
347                         </div>
348                         <nav id="demosites_nav" class="collapse navbar-collapse navbar-left" role="navigation">
349                                 <ul class="nav navbar-nav">
350                                         <li class="dropdown">
351                                                 <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">demo sites <strong class="caret"></strong></a>
352                                                 <ul class="dropdown-menu scrollable-menu inpagemenu" role="menu">
353                                                         <li id="demo_eu"><a href="//netdata.firehol.org?nowelcome">EU - London (DigitalOcean.com)</a></li>
354                                                         <li id="demo_us"><a href="//netdata2.firehol.org?nowelcome">US - Atlanta (CDN77.com)</a></li>
355                                                         <li role="separator" class="divider"></li>
356                                                         <li id="demo_tv"><a href="tv.html">TV Dashboard for 2 servers</a></li>
357                                                         <li id="demosites"><a href="demosites.html">Dashboard for monitoring netdata demo sites</a></li>
358                                                 </ul>
359                                         </li>
360                                 </ul>
361                         </nav>
362                         <nav class="collapse navbar-collapse navbar-right" role="navigation">
363                                 <ul class="nav navbar-nav">
364                                         <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fa fa-cog"></i> settings</a></li>
365                                         <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fa fa-github"></i> community</a></li>
366                                         <li id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal"><i class="fa fa-cloud-download"></i> update</a></li>
367 <!--                                    <li><a href="old/" class="btn" target="_blank"><i class="fa fa-step-backward"></i> old dashboard</a></li> -->
368                                         <li><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fa fa-question-circle"></i> help</a></li>
369 <!--                                    <li><a href="#sec">Visualize</a></li>
370                                         <li><a href="#sec">Prototype</a></li>
371 -->                             </ul>
372                         </nav>
373                 </div>
374         </nav>
375
376         <div id="masthead" style="display: none;">
377                 <div class="container">
378                         <div class="row">
379                                 <div class="col-md-7">
380                                         <h1>Netdata
381                                                 <p class="lead">Real-time performance monitoring, in the greatest possible detail</p>
382                                         </h1>
383                                 </div>
384                                 <div class="col-md-5">
385                                         <div class="well well-lg">
386                                                 <div class="row">
387                                                 <div class="col-md-6">
388                                                         <b>Drag</b> charts to pan.
389                                                         <b>Shift + wheel</b> on them, to zoom in and out.
390                                                         <b>Double-click</b> on them, to reset.
391                                                         <b>Hover</b> on them too!
392                                                         </div>
393                                                 <div class="col-md-6">
394                                                         <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>
395                                                         </div>
396                                                 </div>
397                                         </div>
398                                 </div>
399                         </div>
400                 </div>
401         </div>
402
403         <div class="container">
404                 <div class="row">
405                         <div class="col-md-10" role="main">
406                                 <div id="charts_div"></div>
407                         </div>
408                         <div class="col-md-2" role="complementary">
409                                 <nav class="dashboard-sidebar hidden-print hidden-xs hidden-sm" id="sidebar" role="menu"></nav>
410                         </div>
411                 </div>
412         </div>
413
414         <div id="footer" class="container" style="display: none;">
415                 <div class="row">
416                         <div class="col-md-10" role="main">
417                                 <div class="p">
418                                         <big><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></big><br/>
419                                         <i class="fa fa-copyright"></i> Copyright 2016, Costa Tsaousis.<br/>
420                                         Released under <a href="http://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">GPL v3 or later</a>.<br/>
421                                 </div>
422                                 <div class="p">
423                                         <small>
424                                                 <a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a> re-distributes these software tools:
425
426                                                 <i class="fa fa-circle"></i> The excellent <a href="http://dygraphs.com/" target="_blank">Dygraphs.com</a> web chart library,
427                                                 <i class="fa fa-copyright"></i> Copyright 2009, Dan Vanderkam, <a href="http://dygraphs.com/legal.html" target="_blank">MIT License</a>
428
429                                                 <i class="fa fa-circle"></i> <a href="http://omnipotent.net/jquery.sparkline/" target="_blank">jQuery Sparklines</a> web chart library,
430                                                 <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>
431
432                                                 <i class="fa fa-circle"></i> <a href="http://benpickles.github.io/peity/" target="_blank">Peity</a> web chart library,
433                                                 <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>
434
435                                                 <i class="fa fa-circle"></i> <a href="https://rendro.github.io/easy-pie-chart/" target="_blank">Easy Pie Chart</a> web chart library,
436                                                 <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>
437
438                                                 <i class="fa fa-circle"></i> <a href="http://bernii.github.io/gauge.js/" target="_blank">Gauge.js</a> web chart library,
439                                                 <i class="fa fa-copyright"></i> Copyright, Bernard Kobos, <a href="http://bernii.github.io/gauge.js/" target="_blank">MIT License</a>
440
441                                                 <i class="fa fa-circle"></i> <a href="https://jquery.org/" target="_blank">jQuery</a>,
442                                                 <i class="fa fa-copyright"></i> Copyright 2015, jQuery Foundation, <a href="https://jquery.org/license/" target="_blank">MIT License</a>
443
444                                                 <i class="fa fa-circle"></i> <a href="http://getbootstrap.com/getting-started/" target="_blank">Bootstrap</a>,
445                                                 <i class="fa fa-copyright"></i> Copyright 2015, Twitter, <a href="http://getbootstrap.com/getting-started/#license-faqs" target="_blank">MIT License</a>
446
447                                                 <i class="fa fa-circle"></i> <a href="http://www.bootstraptoggle.com/" target="_blank">Bootstrap Toggle</a>,
448                                                 <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>
449
450                                                 <i class="fa fa-circle"></i> <a href="https://jamesflorentino.github.io/nanoScrollerJS/" target="_blank">NanoScroller</a>,
451                                                 <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>
452
453                                                 <i class="fa fa-circle"></i> <a href="https://github.com/marcj/css-element-queries" target="_blank">CSS Element Queries</a>,
454                                                 <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>
455
456                                                 <i class="fa fa-circle"></i> <a href="https://fortawesome.github.io/Font-Awesome/" target="_blank">FontAwesome</a>,
457                                                 <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>
458
459                                                 <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.
460
461                                                 <i class="fa fa-circle"></i> <a href="http://morrisjs.github.io/morris.js/" target="_blank">morris.js</a>,
462                                                 <i class="fa fa-copyright"></i> Copyright 2013, Olly Smith, <a href="http://morrisjs.github.io/morris.js/" target="_blank">Simplified BSD License</a>
463
464                                                 <i class="fa fa-circle"></i> <a href="http://raphaeljs.com/" target="_blank">Raphaël</a>,
465                                                 <i class="fa fa-copyright"></i> Copyright 2008, Dmitry Baranovskiy, <a href="http://raphaeljs.com/license.html" target="_blank">MIT License</a>
466
467                                                 <i class="fa fa-circle"></i> <a href="http://C3js.org/" target="_blank">C3</a>,
468                                                 <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>
469
470                                                 <i class="fa fa-circle"></i> <a href="http://D3js.org/" target="_blank">D3</a>,
471                                                 <i class="fa fa-copyright"></i> Copyright 2015, Mike Bostock, <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">BSD License</a>
472
473                                                 <i class="fa fa-circle"></i> <a href="https://github.com/broofa/node-int64" target="_blank">node-int64</a>,
474                                                 <i class="fa fa-copyright"></i> Copyright 2014, Robert Kieffer, <a href="https://github.com/broofa/node-int64/blob/master/LICENSE" target="_blank">MIT License</a>
475
476                                         </small>
477                                 </div>
478                         </div>
479                 </div>
480         </div>
481
482         <div class="modal fade" id="welcomeModal" tabindex="-1" role="dialog" aria-labelledby="welcomeModalLabel">
483                 <div class="modal-dialog modal-lg" role="document">
484                         <div class="modal-content">
485                                 <div class="modal-header">
486                                         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
487                                         <h4 class="modal-title" id="welcomeModalLabel">Welcome!</h4>
488                                 </div>
489                                 <div class="modal-body">
490                                                 <div class="p">
491                                                 <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.
492                                                 </div>
493                                                 <div class="p">
494                                                 <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.
495                                                 </div>
496                                                 <div class="p">
497                                                 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.
498                                                 </div>
499                                                 <div class="p">
500                                                 <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>%),
501                                                 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).
502                                                 </div>
503                                                 <div class="p">
504                                                 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>!).
505                                                 </div>
506                                                 <div class="p">
507                                                 For more information please refer to the <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata wiki</a></b>.
508                                                 </div>
509                                 </div>
510                                 <div class="modal-footer">
511                                         <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
512                                 </div>
513                         </div>
514                 </div>
515         </div>
516
517         <div class="modal fade" id="helpModal" tabindex="-1" role="dialog" aria-labelledby="helpModalLabel">
518                 <div class="modal-dialog modal-lg" role="document">
519                         <div class="modal-content">
520                                 <div class="modal-header">
521                                         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
522                                         <h4 class="modal-title" id="helpModalLabel">Dashboard Help</h4>
523                                 </div>
524                                 <div class="modal-body">
525
526                                         <h4>Dygraphs (line, area and stacked area charts)</h4>
527
528                                         <!-- Nav tabs -->
529                                         <ul class="nav nav-tabs" role="tablist">
530                                                 <li role="presentation" class="active"><a href="#help_mouse" aria-controls="help_mouse" role="tab" data-toggle="tab">Mouse Interface</a></li>
531                                                 <li role="presentation"><a href="#help_touch" aria-controls="help_touch" role="tab" data-toggle="tab">Touch Interface</a></li>
532                                         </ul>
533
534                                         <!-- Tab panes -->
535                                         <div class="tab-content">
536                                                 <div role="tabpanel" class="tab-pane active" id="help_mouse">
537                                                         <div class="p">
538                                                                 <h4>Mouse Over / Hover</h4>
539                                                                 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).
540                                                                 <br/>
541                                                                 All the other visible charts will also show and highlight their values for the same timestamp.
542                                                         </div>
543                                                         <hr/>
544                                                         <div class="p">
545                                                                 <h4>Drag Chart Contents</h4>
546                                                                 Drag the contents of a chart to pan it horizontally.
547                                                                 <br/>
548                                                                 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).
549                                                                 <br/>
550                                                                 Once a chart is panned, auto refreshing stops for all charts. To enable it again, <b>double click</b> a panned chart.
551                                                         </div>
552                                                         <hr/>
553                                                         <div class="p">
554                                                                 <h4>Double Click</h4>
555                                                                 Double Click a chart to reset all the charts to their default auto-refreshing state.
556                                                         </div>
557                                                         <hr/>
558                                                         <div class="p">
559                                                                 <h4>SHIFT + Drag</h4>
560                                                                 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:
561                                                                 <ul>
562                                                                         <li>The already loaded chart contents are zoomed (low resolution)</li>
563                                                                         <li>New data are transferred from the netdata server, to refresh the chart with possibly more detail.</li>
564                                                                 </ul>
565                                                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
566                                                         </div>
567                                                         <hr/>
568                                                         <div class="p">
569                                                                 <h4>SHIFT + Mouse Wheel <small>(does not work on firefox and IE/Edge)</small></h4>
570                                                                 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.
571                                                                 <br/>
572                                                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
573                                                         </div>
574                                                         <hr/>
575                                                         <div class="p">
576                                                                 <h4>Legend Operations</h4>
577                                                                 Click on the label or value of a dimension, will select / un-select this dimension.
578                                                                 <br/>
579                                                                 You can press any of the SHIFT or CONTROL keys and then click on legend labels or values, to select / un-select multiple dimensions.
580                                                         </div>
581                                                 </div>
582                                                 <div role="tabpanel" class="tab-pane" id="help_touch">
583                                                         <div class="p">
584                                                                 <h4>Single Tap</h4>
585                                                                 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).
586                                                                 <br/>
587                                                                 All the other visible charts will also show and highlight their values for the same timestamp.
588                                                         </div>
589                                                         <hr/>
590                                                         <div class="p">
591                                                                 <h4>Drag Chart Contents</h4>
592                                                                 Touch and Drag the contents of a chart to pan it horizontally.
593                                                                 <br/>
594                                                                 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).
595                                                                 <br/>
596                                                                 Once a chart is panned, auto refreshing stops for all charts. To enable it again, <b>double tap</b> a panned chart.
597                                                         </div>
598                                                         <hr/>
599                                                         <div class="p">
600                                                                 <h4>Double Tap</h4>
601                                                                 Double tap a chart to reset all the charts to their default auto-refreshing state.
602                                                         </div>
603                                                         <hr/>
604                                                         <div class="p">
605                                                                 <h4>Zoom <small>(does not work on firefox and IE/Edge)</small></h4>
606                                                                 With two fingers, zoom in or out.
607                                                                 <br/>
608                                                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
609                                                         </div>
610                                                         <hr/>
611                                                         <div class="p">
612                                                                 <h4>Legend Operations</h4>
613                                                                 Tap on the label or value of a dimension, will select / un-select this dimension.
614                                                         </div>
615                                                 </div>
616                                         </div>
617                                 </div>
618                                 <div class="modal-footer">
619                                         <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
620                                 </div>
621                         </div>
622                 </div>
623         </div>
624
625         <div class="modal fade" id="optionsModal" tabindex="-1" role="dialog" aria-labelledby="optionsModalLabel">
626                 <div class="modal-dialog modal-lg" role="document">
627                         <div class="modal-content">
628                                 <div class="modal-header">
629                                         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
630                                         <h4 class="modal-title" id="optionsModalLabel">netdata dashboard options</h4>
631                                 </div>
632                                 <div class="modal-body">
633                                         <center>
634                                                 <small style="color: #BBBBBB;">These are browser settings. Each viewer has its own. They do not affect the operation of your netdata server.
635                                                 <br/>
636                                                 Settings take effect immediately and are saved permanently to browser local storage (except the refresh on focus / always option).
637                                                 <br/>
638                                                 To reset all options (including charts sizes) to their defaults, click <a href="#" onclick="resetDashboardOptions(); return false;">here</a>.</small>
639                                         </center>
640                                         <div style="padding: 10px;"></div>
641
642                                         <!-- Nav tabs -->
643                                         <ul class="nav nav-tabs" role="tablist">
644                                                 <li role="presentation" class="active"><a href="#settings_performance" aria-controls="settings_performance" role="tab" data-toggle="tab">Performance</a></li>
645                                                 <li role="presentation"><a href="#settings_sync" aria-controls="settings_sync" role="tab" data-toggle="tab">Synchronization</a></li>
646                                                 <li role="presentation"><a href="#settings_visual" aria-controls="settings_visual" role="tab" data-toggle="tab">Visual</a></li>
647                                         </ul>
648
649                                         <!-- Tab panes -->
650                                         <div class="tab-content">
651                                                 <div role="tabpanel" class="tab-pane active" id="settings_performance">
652                                                         <form id="optionsForm1" method="get" class="form-horizontal">
653                                                                 <div class="form-group">
654                                                                         <table>
655                                                                         <tr class="option-row">
656                                                                                 <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>
657                                                                                 <td class="option-info"><strong>When to refresh the charts?</strong><br/>
658                                                                                         <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>
659                                                                                 </td>
660                                                                                 </tr>
661                                                                         <tr class="option-row">
662                                                                                 <td class="option-control">
663                                                                                 <input id="eliminate_zero_dimensions" type="checkbox" checked data-toggle="toggle" data-on="Non Zero" data-off="All" data-width="110px">
664                                                                                 </td>
665                                                                                 <td class="option-info"><strong>Which dimensions to show?</strong><br/>
666                                                                                         <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>
667                                                                                 </td>
668                                                                                 </tr>
669                                                                         <tr class="option-row">
670                                                                                 <td class="option-control"><input id="destroy_on_hide" type="checkbox" data-toggle="toggle" data-on="Destroy" data-off="Hide" data-width="110px"></td>
671                                                                                 <td class="option-info"><strong>How to handle hidden charts?</strong><br/>
672                                                                                         <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>
673                                                                                 </td>
674                                                                                 </tr>
675                                                                         </table>
676                                                                 </div>
677                                                         </form>
678                                                 </div>
679                                                 <div role="tabpanel" class="tab-pane" id="settings_sync">
680                                                         <form id="optionsForm2" method="get" class="form-horizontal">
681                                                                 <div class="form-group">
682                                                                         <table>
683                                                                         <tr class="option-row">
684                                                                                 <td class="option-control"><input id="parallel_refresher" type="checkbox" checked data-toggle="toggle" data-on="Parallel" data-off="Sequential" data-width="110px"></td>
685                                                                                 <td class="option-info"><strong>Which chart refresh policy to use?</strong><br/>
686                                                                                         <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>
687                                                                                 </td>
688                                                                                 </tr>
689                                                                         <tr class="option-row" id="concurrent_refreshes_row">
690                                                                                 <td class="option-control"></td>
691                                                                                 <td class="option-info">
692                                                                                         <table>
693                                                                                         <tr class="option-row">
694                                                                                         <td class="option-control">
695                                                                                         <input id="concurrent_refreshes" type="checkbox" checked data-toggle="toggle" data-on="Resync" data-off="Best Effort" data-width="110px">
696                                                                                         </td>
697                                                                                         <td class="option-info">
698                                                                                         <strong>Shall we re-sync chart refreshes?</strong><br/>
699                                                                                         <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>
700                                                                                         </td>
701                                                                                         </tr>
702                                                                                         </table>
703                                                                                 </td>
704                                                                                 </tr>
705                                                                         <tr class="option-row">
706                                                                                 <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>
707                                                                                 <td class="option-info"><strong>Sync hover selection on all charts?</strong><br/>
708                                                                                         <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>
709                                                                                 </td>
710                                                                                 </tr>
711                                                                         <tr class="option-row">
712                                                                                 <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>
713                                                                                 <td class="option-info"><strong>Sync pan and zoom on all charts?</strong><br/>
714                                                                                         <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>
715                                                                                 </td>
716                                                                                 </tr>
717                                                                         </table>
718                                                                 </div>
719                                                         </form>
720                                                 </div>
721                                                 <div role="tabpanel" class="tab-pane" id="settings_visual">
722                                                         <form id="optionsForm3" method="get" class="form-horizontal">
723                                                                 <div class="form-group">
724                                                                         <table>
725                                                                         <tr class="option-row">
726                                                                                 <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>
727                                                                                 <td class="option-info"><strong>Which theme to use?</strong><br/>
728                                                                                         <small>Netdata comes with two themes: <b>Dark</b> (the default) and <b>White</b>.
729                                                                                         <br/>
730                                                                                         <b>Switching this will reload the dashboard</b>.
731                                                                                         </small>
732                                                                                 </td>
733                                                                                 </tr>
734                                                                         <tr class="option-row">
735                                                                                 <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>
736                                                                                 <td class="option-info"><strong>Do you need help?</strong><br/>
737                                                                                         <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.
738                                                                                         <br/>
739                                                                                         <b>Switching this will reload the dashboard</b>.
740                                                                                         </small>
741                                                                                 </td>
742                                                                                 </tr>
743                                                                         <tr class="option-row">
744                                                                                 <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>
745                                                                                 <td class="option-info"><strong>Enable data padding when panning and zooming?</strong><br/>
746                                                                                         <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>
747                                                                                 </td>
748                                                                                 </tr>
749                                                                         <tr class="option-row">
750                                                                                 <td class="option-control"><input id="smooth_plot" type="checkbox" checked data-toggle="toggle"  data-on="Smooth" data-off="Rough" data-width="110px"></td>
751                                                                                 <td class="option-info"><strong>Enable Bézier lines on charts?</strong><br/>
752                                                                                         <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.
753                                                                                         <br/>
754                                                                                         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>
755                                                                                 </td>
756                                                                                 </tr>
757                                                                         </table>
758                                                                 </div>
759                                                         </form>
760                                                 </div>
761                                         </div>
762                                 </div>
763                                 <div class="modal-footer">
764                                         <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
765                                 </div>
766                         </div>
767                 </div>
768         </div>
769
770
771         <div class="modal fade" id="updateModal" tabindex="-1" role="dialog" aria-labelledby="updateModalLabel">
772                 <div class="modal-dialog" role="document">
773                         <div class="modal-content">
774                                 <div class="modal-header">
775                                         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
776                                         <h4 class="modal-title" id="updateModalLabel">Update Check</h4>
777                                 </div>
778                                 <div class="modal-body">
779                                         Your netdata version: <b><code><span id="netdataVersion">Unknown</span></code></b>
780                                         <br/>
781                                         <div style="padding: 10px;"></div>
782                                         <div id="versionCheckLog">Not checked yet. Please press the Check Now button.</div>
783                                 </div>
784                                 <div class="modal-footer">
785                                         <a href="#" onclick="notifyForUpdate(true);" type="button" class="btn btn-default">Check Now</a>
786                                         <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
787                                 </div>
788                         </div>
789                 </div>
790         </div>
791
792 <script>
793
794 var this_is_demo = null;
795 function isdemo() {
796         if(this_is_demo !== null) return this_is_demo;
797         this_is_demo = false;
798
799         try {
800                 if(typeof document.location.hostname === 'string') {
801                         if(document.location.hostname === 'netdata.firehol.org') {
802                                 document.getElementById("demo_eu").className = "active";
803                                 this_is_demo = true;
804                         }
805                         else if(document.location.hostname === 'netdata2.firehol.org') {
806                                 document.getElementById("demo_us").className = "active";
807                                 this_is_demo = true;
808                         }
809                 }
810
811                 if(!this_is_demo)
812                         document.getElementById("demosites_nav").style.visibility = "hidden";
813         }
814         catch(error) {
815                 ;
816         }
817
818         return this_is_demo;
819 }
820
821 if(isdemo()) {
822         document.getElementById('masthead').style.display = 'block';
823 }
824
825 var options = {
826         sparklines_registry: {},
827         submenu_names: {},
828         data: null,
829         hostname: 'netdata_server', // will be overwritten by the netdata server
830         categories: new Array(),
831         categories_idx: {},
832         families: new Array(),
833         families_idx: {},
834
835         chartsPerRow: 0,
836         chartsMinWidth: 1450,
837         chartsHeight: 180,
838         sparklinesHeight: 60
839 };
840
841 // generate a sparkline
842 // used in the documentation
843 function sparkline(chart, dimension, units) {
844         var key = chart + '.' + dimension;
845
846         if(typeof units === 'undefined')
847                 units = '';
848
849         if(typeof options.sparklines_registry[key] === 'undefined')
850                 options.sparklines_registry[key] = { count: 1 };
851         else
852                 options.sparklines_registry[key].count++;
853
854         key = key + '.' + options.sparklines_registry[key].count;
855
856         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 + ')';
857
858         return h;
859 }
860
861 function chartsPerRow(total) {
862         if(options.chartsPerRow === 0) {
863                 width = Math.floor(total / options.chartsMinWidth);
864                 if(width === 0) width = 1;
865                 return width;
866         }
867         else return options.chartsPerRow;
868 }
869
870 function prioritySort(a, b) {
871         if(a.priority < b.priority) return -1;
872         if(a.priority > b.priority) return 1;
873         if(a.name < b.name) return -1;
874         return 1;
875 }
876
877 function sortObjectByPriority(object) {
878         var idx = {};
879         var sorted = new Array();
880
881         for(var i in object) {
882                 if(typeof idx[i] === 'undefined') {
883                         idx[i] = object[i];
884                         sorted.push(i);
885                 }
886         }
887
888         sorted.sort(function(a, b) {
889                 if(idx[a].priority < idx[b].priority) return -1;
890                 if(idx[a].priority > idx[b].priority) return 1;
891                 if(a < b) return -1;
892                 return 1;
893         });
894
895         return sorted;
896 }
897
898 // ----------------------------------------------------------------------------
899
900 function gaugeChart(title, width, dimensions, colors) {
901         if(typeof colors === 'undefined')
902                 colors = '';
903
904         if(typeof dimensions === 'undefined')
905                 dimensions = '';
906
907         return '<div data-netdata="CHART_UNIQUE_ID"'
908                                                         + ' data-dimensions="' + dimensions + '"'
909                                                         + ' data-chart-library="gauge"'
910                                                         + ' data-gauge-adjust="width"'
911                                                         + ' data-title="' + title + '"'
912                                                         + ' data-width="' + width + '"'
913                                                         + ' data-before="0"'
914                                                         + ' data-after="-CHART_DURATION"'
915                                                         + ' data-points="CHART_DURATION"'
916                                                         + ' data-colors="' + colors + '"'
917                                                         + ' role="application"></div>';
918 }
919
920 // ----------------------------------------------------------------------------
921
922 var menuData = {
923         'system': {
924                 title: 'System Overview',
925                 info: 'Overview of the key system metrics.'
926         },
927
928         'ap': {
929                 title: 'Access Points',
930                 info: undefined
931         },
932
933         'tc': {
934                 title: 'Quality of Service',
935                 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).'
936         },
937
938         'net': {
939                 title: 'Network Interfaces',
940                 info: 'Per network interface statistics collected from <code>/proc/net/dev</code>.'
941         },
942
943         'ipv4': {
944                 title: 'IPv4 Networking',
945                 info: undefined
946         },
947
948         'ipv6': {
949                 title: 'IPv6 Networking',
950                 info: undefined
951         },
952
953         'ipvs': {
954                 title: 'IP Virtual Server',
955                 info: undefined
956         },
957
958         'netfilter': {
959                 title: 'Firewall (netfilter)',
960                 info: undefined
961         },
962
963         'cpu': {
964                 title: 'CPUs',
965                 info: undefined
966         },
967
968         'mem': {
969                 title: 'Memory',
970                 info: undefined
971         },
972
973         'disk': {
974                 title: 'Disks',
975                 info: undefined
976         },
977
978         'sensors': {
979                 title: 'Sensors',
980                 info: undefined
981         },
982
983         'nfsd': {
984                 title: 'File Server (nfsd)',
985                 info: undefined
986         },
987
988         'apps': {
989                 title: 'Applications',
990                 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).<br/><b>IMPORTANT</b>: The values shown here are not 100% accurate. They only include values for the processes running. If an application is spawning children continuously, which are terminated in just a few milliseconds (like shell scripts do), the values reported will be inaccurate. Linux does report the values for the exited children of a process. However, these values are reported to the parent process <b>only when the child exits</b>. If these values, of the exited child processes, were also aggregated in the charts below, the charts would have been full of spikes, presenting unrealistic utilization for each process group. So, we decided to ignore these values and present only the utilization of <b>the currently running processes</b>.',
991                 height: 1.5
992         },
993
994         'users': {
995                 title: 'Users',
996                 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.<br/><b>IMPORTANT</b>: The values shown here are not 100% accurate. They only include values for the processes running. If an application is spawning children continuously, which are terminated in just a few milliseconds (like shell scripts do), the values reported will be inaccurate. Linux does report the values for the exited children of a process. However, these values are reported to the parent process <b>only when the child exits</b>. If these values, of the exited child processes, were also aggregated in the charts below, the charts would have been full of spikes, presenting unrealistic utilization for each process group. So, we decided to ignore these values and present only the utilization of <b>the currently running processes</b>.',
997                 height: 1.5
998         },
999
1000         'groups': {
1001                 title: 'User Groups',
1002                 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.<br/><b>IMPORTANT</b>: The values shown here are not 100% accurate. They only include values for the processes running. If an application is spawning children continuously, which are terminated in just a few milliseconds (like shell scripts do), the values reported will be inaccurate. Linux does report the values for the exited children of a process. However, these values are reported to the parent process <b>only when the child exits</b>. If these values, of the exited child processes, were also aggregated in the charts below, the charts would have been full of spikes, presenting unrealistic utilization for each process group. So, we decided to ignore these values and present only the utilization of <b>the currently running processes</b>.',
1003                 height: 1.5
1004         },
1005
1006         'netdata': {
1007                 title: 'Netdata Monitoring',
1008                 info: undefined
1009         },
1010
1011         'example': {
1012                 title: 'Example Charts',
1013                 info: undefined
1014         },
1015
1016         'cgroup': {
1017                 title: 'Container',
1018                 info: undefined
1019         },
1020
1021         'mysql': {
1022                 title: 'MySQL',
1023                 info: undefined
1024         },
1025
1026         'named': {
1027                 title: 'named',
1028                 info: undefined
1029         },
1030 };
1031
1032 var submenuData = {
1033         'mem.ksm': {
1034                 title: 'Memory Deduper',
1035                 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.'
1036         },
1037
1038         'netfilter.conntrack': {
1039                 title: 'Connection Tracker',
1040                 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.'
1041         },
1042
1043         'netfilter.nfacct': {
1044                 title: 'Bandwidth Accounting',
1045                 info: 'The following information is read using the <code>nfacct.plugin</code>.'
1046         },
1047
1048         'netfilter.synproxy': {
1049                 title: 'DDoS Protection',
1050                 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.'
1051         }
1052 };
1053
1054 var chartData = {
1055         'system.cpu': {
1056                 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.'
1057         },
1058
1059         'system.load': {
1060                 info: 'Current system load read from <code>/proc/loadavg</code>.',
1061                 height: 0.7
1062         },
1063
1064         'system.io': {
1065                 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.'
1066         },
1067
1068         'system.swapio': {
1069                 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).'
1070         },
1071
1072         'system.pgfaults': {
1073                 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.'
1074         },
1075
1076         'system.entropy': {
1077                 colors: '#CC22AA',
1078                 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.'
1079         },
1080
1081         'system.forks': {
1082                 colors: '#5555DD',
1083                 info: 'The number of new processes created per second, read from <code>/proc/stat</code>.'
1084         },
1085
1086         'system.intr': {
1087                 colors: '#DD5555',
1088                 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.'
1089         },
1090
1091         'system.interrupts': {
1092                 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.'
1093         },
1094
1095         'system.softirqs': {
1096                 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.'
1097         },
1098
1099         'system.processes': {
1100                 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.'
1101         },
1102
1103         'system.active_processes': {
1104                 info: 'All system active processes, read from <code>/proc/loadavg</code>.'
1105         },
1106
1107         'system.ctxt': {
1108                 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.'
1109         },
1110
1111         'system.idlejitter': {
1112                 colors: '#5555AA',
1113                 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).'
1114         },
1115
1116         'system.ipv4': {
1117                 info: 'Total IPv4 Traffic, read from <code>/proc/net/netstat</code>.'
1118         },
1119
1120         'system.ipv6': {
1121                 info: 'Total IPv6 Traffic, read from <code>/proc/net/snmp6</code>.'
1122         },
1123
1124         'system.ram': {
1125                 info: 'System memory, read from <code>/proc/meminfo</code>.'
1126         },
1127
1128         'system.swap': {
1129                 info: 'System swap memory, read from <code>/proc/meminfo</code>.'
1130         },
1131
1132         'mem.ksm_savings': {
1133                 heads: [
1134                         gaugeChart('Saved', '12%', 'savings', '#0099CC')
1135                 ]
1136         },
1137
1138         'mem.ksm_ratios': {
1139                 heads: [
1140                         function(id) {
1141                                 return  '<div data-netdata="' + id + '"'
1142                                         + ' data-gauge-max-value="100"'
1143                                         + ' data-chart-library="gauge"'
1144                                         + ' data-title="Savings"'
1145                                         + ' data-units="percentage %"'
1146                                         + ' data-gauge-adjust="width"'
1147                                         + ' data-width="12%"'
1148                                         + ' data-before="0"'
1149                                         + ' data-after="-CHART_DURATION"'
1150                                         + ' data-points="CHART_DURATION"'
1151                                         + ' role="application"></div>';
1152                         }
1153                 ]
1154         },
1155
1156         'mem.committed': {
1157                 colors: NETDATA.colors[3]
1158         },
1159
1160         'apps.cpu': {
1161                 height: 2.0
1162         },
1163
1164         'apps.preads': {
1165                 height: 2.0
1166         },
1167
1168         'apps.pwrites': {
1169                 height: 2.0
1170         },
1171
1172         'users.cpu': {
1173                 height: 2.0
1174         },
1175
1176         'users.preads': {
1177                 height: 2.0
1178         },
1179
1180         'users.pwrites': {
1181                 height: 2.0
1182         },
1183
1184         'groups.cpu': {
1185                 height: 2.0
1186         },
1187
1188         'groups.preads': {
1189                 height: 2.0
1190         },
1191
1192         'groups.pwrites': {
1193                 height: 2.0
1194         },
1195
1196         'tc.qos': {
1197                 heads: [
1198                         function(id) {
1199                                 if(id.match(/.*-ifb$/))
1200                                         return gaugeChart('Inbound', '12%', '', '#5555AA');
1201                                 else
1202                                         return gaugeChart('Outbound', '12%', '', '#AA9900');
1203                         }
1204                 ]
1205         },
1206
1207         'net.net': {
1208                 heads: [
1209                         gaugeChart('Received', '12%', 'received'),
1210                         gaugeChart('Sent', '12%', 'sent')
1211                 ]
1212         },
1213
1214         'disk.util': {
1215                 colors: '#FF5588',
1216                 heads: [
1217                         gaugeChart('Utilization', '12%', '', '#FF5588')
1218                 ]
1219         },
1220
1221         'disk.backlog': {
1222                 colors: '#0099CC'
1223         },
1224
1225         'disk.io': {
1226                 heads: [
1227                         gaugeChart('Read', '12%', 'reads'),
1228                         gaugeChart('Write', '12%', 'writes')
1229                 ]
1230         },
1231
1232         'netfilter.sockets': {
1233                 colors: '#88AA00',
1234                 heads: [
1235                         gaugeChart('Active Connections', '12%', '', '#88AA00')
1236                 ]
1237         },
1238
1239         'netfilter.new': {
1240                 heads: [
1241                         gaugeChart('New Connections', '12%', 'new', '#5555AA')
1242                 ]
1243         },
1244
1245         'disk.iotime': {
1246                 height: 0.5
1247         },
1248         'disk.mops': {
1249                 height: 0.5
1250         },
1251         'disk.svctm': {
1252                 height: 0.5
1253         },
1254         'disk.avgsz': {
1255                 height: 0.5
1256         },
1257         'disk.await': {
1258                 height: 0.5
1259         },
1260
1261         'apache.connections': {
1262                 colors: NETDATA.colors[4],
1263                 mainheads: [
1264                         gaugeChart('Connections', '12%', '', NETDATA.colors[4])
1265                 ]
1266         },
1267
1268         'apache.requests': {
1269                 colors: NETDATA.colors[0],
1270                 mainheads: [
1271                         gaugeChart('Connections', '12%', '', NETDATA.colors[0])
1272                 ]
1273         },
1274
1275         'apache.net': {
1276                 colors: NETDATA.colors[3],
1277                 mainheads: [
1278                         gaugeChart('Bandwidth', '12%', '', NETDATA.colors[3])
1279                 ]
1280         },
1281
1282         'apache.workers': {
1283                 mainheads: [
1284                         function(id) {
1285                                 return  '<div data-netdata="' + id + '"'
1286                                         + ' data-dimensions="busy"'
1287                                         + ' data-append-options="percentage"'
1288                                         + ' data-gauge-max-value="100"'
1289                                         + ' data-chart-library="gauge"'
1290                                         + ' data-title="Workers Utilization"'
1291                                         + ' data-units="percentage %"'
1292                                         + ' data-gauge-adjust="width"'
1293                                         + ' data-width="12%"'
1294                                         + ' data-before="0"'
1295                                         + ' data-after="-CHART_DURATION"'
1296                                         + ' data-points="CHART_DURATION"'
1297                                         + ' role="application"></div>';
1298                         }
1299                 ]
1300         },
1301
1302         'apache.bytesperreq': {
1303                 colors: NETDATA.colors[3],
1304                 height: 0.5
1305         },
1306
1307         'apache.reqpersec': {
1308                 colors: NETDATA.colors[4],
1309                 height: 0.5
1310         },
1311
1312         'apache.bytespersec': {
1313                 colors: NETDATA.colors[6],
1314                 height: 0.5
1315         },
1316
1317         'nginx.connections': {
1318                 colors: NETDATA.colors[4],
1319                 mainheads: [
1320                         gaugeChart('Connections', '12%', '', NETDATA.colors[4])
1321                 ]
1322         },
1323
1324         'nginx.requests': {
1325                 colors: NETDATA.colors[0],
1326                 mainheads: [
1327                         gaugeChart('Requests', '12%', '', NETDATA.colors[0])
1328                 ]
1329         }
1330 };
1331
1332 function anyAttribute(obj, attr, key, def) {
1333         if(typeof obj[key] !== 'undefined') {
1334                 if(typeof obj[key][attr] !== 'undefined')
1335                         return obj[key][attr];
1336         }
1337         return def;
1338 }
1339
1340 function menuTitle(chart) {
1341         if(typeof chart.menu_pattern !== 'undefined') {
1342                 return anyAttribute(menuData, 'title', chart.menu_pattern, chart.menu_pattern).toString()
1343                                 + ': ' + chart.type.slice(-(chart.type.length - chart.menu_pattern.length - 1)).toString();
1344         }
1345
1346         return anyAttribute(menuData, 'title', chart.menu, chart.menu);
1347 }
1348
1349 function menuInfo(menu) {
1350         return anyAttribute(menuData, 'info', menu, null);
1351 }
1352
1353 function menuHeight(menu, relative) {
1354         return anyAttribute(menuData, 'height', menu, 1.0) * relative;
1355 }
1356
1357 function submenuTitle(menu, submenu) {
1358         var key = menu + '.' + submenu;
1359         return anyAttribute(submenuData, 'title', key, submenu);
1360 }
1361
1362 function submenuInfo(menu, submenu) {
1363         var key = menu + '.' + submenu;
1364         return anyAttribute(submenuData, 'info', key, null);
1365 }
1366
1367 function submenuHeight(menu, submenu, relative) {
1368         var key = menu + '.' + submenu;
1369         return anyAttribute(submenuData, 'height', key, 1.0) * relative;
1370 }
1371
1372
1373 function chartInfo(id) {
1374         if(typeof chartData[id] !== 'undefined' && typeof chartData[id].info !== 'undefined')
1375                 return '<div class="chart-message netdata-chart-alignment" role="document">' + chartData[id].info + '</div>';
1376         else
1377                 return '';
1378 }
1379
1380 function chartHeight(id, def) {
1381         if(typeof chartData[id] !== 'undefined' && typeof chartData[id].height !== 'undefined')
1382                 return def * chartData[id].height;
1383         else
1384                 return def;
1385 }
1386
1387
1388 // ----------------------------------------------------------------------------
1389
1390 // enrich the data structure returned by netdata
1391 // to reflect our menu system and content
1392 function enrichChartData(chart) {
1393         var tmp = chart.type.split('_')[0];
1394
1395         switch(tmp) {
1396                 case 'ap':
1397                 case 'net':
1398                 case 'disk':
1399                         chart.menu = tmp;
1400                         break;
1401
1402                 case 'mysql':
1403                 case 'named':
1404                 case 'cgroup':
1405                         chart.menu = chart.type;
1406                         chart.menu_pattern = tmp;
1407                         break;
1408
1409                 case 'tc':
1410                         chart.menu = tmp;
1411
1412                         // find a name for this device from fireqos info
1413                         // we strip '_(in|out)' or '(in|out)_'
1414                         if(typeof options.submenu_names[chart.family] === 'undefined' || options.submenu_names[chart.family] === chart.family) {
1415                                 var n = chart.name.split('.')[1];
1416                                 if(n.endsWith('_in'))
1417                                         options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_in'));
1418                                 else if(n.endsWith('_out'))
1419                                         options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_out'));
1420                                 else if(n.startsWith('in_'))
1421                                         options.submenu_names[chart.family] = n.slice(3, n.length);
1422                                 else if(n.startsWith('out_'))
1423                                         options.submenu_names[chart.family] = n.slice(4, n.length);
1424                         }
1425
1426                         // increase the priority of IFB devices
1427                         // to have inbound appear before outbound
1428                         if(chart.id.match(/.*-ifb$/))
1429                                 chart.priority--;
1430
1431                         break;
1432
1433                 default:
1434                         chart.menu = chart.type;
1435                         break;
1436         }
1437
1438         chart.submenu = chart.family;
1439 }
1440
1441 // ----------------------------------------------------------------------------
1442
1443 function name2id(s) {
1444         return s
1445                 .replace(/ /g, '_')
1446                 .replace(/\(/g, '_')
1447                 .replace(/\)/g, '_')
1448                 .replace(/\./g, '_')
1449                 .replace(/\//g, '_');
1450 }
1451
1452 function headMain(charts, duration) {
1453         var head = '';
1454
1455         if(typeof charts['system.swap'] !== 'undefined')
1456                 head += '<div style="margin-right: 10px;" data-netdata="system.swap"'
1457                 + ' data-dimensions="free"'
1458                 + ' data-append-options="percentage"'
1459                 + ' data-chart-library="easypiechart"'
1460                 + ' data-title="Free Swap"'
1461                 + ' data-units="%"'
1462                 + ' data-easypiechart-max-value="100"'
1463                 + ' data-width="8%"'
1464                 + ' data-before="0"'
1465                 + ' data-after="-' + duration.toString() + '"'
1466                 + ' data-points="' + duration.toString() + '"'
1467                 + ' data-colors="#DD4400"'
1468                 + ' role="application"></div>';
1469
1470         if(typeof charts['system.io'] !== 'undefined') {
1471                 head += '<div style="margin-right: 10px;" data-netdata="system.io"'
1472                 + ' data-dimensions="in"'
1473                 + ' data-chart-library="easypiechart"'
1474                 + ' data-title="Disk Read"'
1475                 + ' data-units="KB / s"'
1476                 + ' data-width="10%"'
1477                 + ' data-before="0"'
1478                 + ' data-after="-' + duration.toString() + '"'
1479                 + ' data-points="' + duration.toString() + '"'
1480                 + ' role="application"></div>';
1481
1482                 head += '<div style="margin-right: 10px;" data-netdata="system.io"'
1483                 + ' data-dimensions="out"'
1484                 + ' data-chart-library="easypiechart"'
1485                 + ' data-title="Disk Write"'
1486                 + ' data-units="KB / s"'
1487                 + ' data-width="10%"'
1488                 + ' data-before="0"'
1489                 + ' data-after="-' + duration.toString() + '"'
1490                 + ' data-points="' + duration.toString() + '"'
1491                 + ' role="application"></div>';
1492         }
1493
1494         if(typeof charts['system.cpu'] !== 'undefined')
1495                 head += '<div data-netdata="system.cpu"'
1496                 + ' data-chart-library="gauge"'
1497                 + ' data-title="CPU"'
1498                 + ' data-units="%"'
1499                 + ' data-gauge-max-value="100"'
1500                 + ' data-width="18%"'
1501                 + ' data-after="-' + duration.toString() + '"'
1502                 + ' data-points="' + duration.toString() + '"'
1503                 + ' data-colors="' + NETDATA.colors[12] + '"'
1504                 + ' role="application"></div>';
1505
1506         if(typeof charts['system.ipv4'] !== 'undefined') {
1507                 head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
1508                 + ' data-dimensions="received"'
1509                 + ' data-chart-library="easypiechart"'
1510                 + ' data-title="IPv4 Inbound"'
1511                 + ' data-units="kbps"'
1512                 + ' data-width="10%"'
1513                 + ' data-before="0"'
1514                 + ' data-after="-' + duration.toString() + '"'
1515                 + ' data-points="' + duration.toString() + '"'
1516                 + ' role="application"></div>';
1517
1518                 head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
1519                 + ' data-dimensions="sent"'
1520                 + ' data-chart-library="easypiechart"'
1521                 + ' data-title="IPv4 Outbound"'
1522                 + ' data-units="kbps"'
1523                 + ' data-width="10%"'
1524                 + ' data-before="0"'
1525                 + ' data-after="-' + duration.toString() + '"'
1526                 + ' data-points="' + duration.toString() + '"'
1527                 + ' role="application"></div>';
1528         }
1529         else if(typeof charts['system.ipv6'] !== 'undefined') {
1530                 head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
1531                 + ' data-dimensions="received"'
1532                 + ' data-chart-library="easypiechart"'
1533                 + ' data-title="IPv6 Inbound"'
1534                 + ' data-units="kbps"'
1535                 + ' data-width="10%"'
1536                 + ' data-before="0"'
1537                 + ' data-after="-' + duration.toString() + '"'
1538                 + ' data-points="' + duration.toString() + '"'
1539                 + ' role="application"></div>';
1540
1541                 head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
1542                 + ' data-dimensions="sent"'
1543                 + ' data-chart-library="easypiechart"'
1544                 + ' data-title="IPv6 Outbound"'
1545                 + ' data-units="kbps"'
1546                 + ' data-width="10%"'
1547                 + ' data-before="0"'
1548                 + ' data-after="-' + duration.toString() + '"'
1549                 + ' data-points="' + duration.toString() + '"'
1550                 + ' role="application"></div>';
1551         }
1552
1553         if(typeof charts['system.ram'] !== 'undefined')
1554                 head += '<div style="margin-right: 10px;" data-netdata="system.ram"'
1555                 + ' data-dimensions="cached|free"'
1556                 + ' data-append-options="percentage"'
1557                 + ' data-chart-library="easypiechart"'
1558                 + ' data-title="Available RAM"'
1559                 + ' data-units="%"'
1560                 + ' data-easypiechart-max-value="100"'
1561                 + ' data-width="8%"'
1562                 + ' data-after="-' + duration.toString() + '"'
1563                 + ' data-points="' + duration.toString() + '"'
1564                 + ' data-colors="' + NETDATA.colors[7] + '"'
1565                 + ' role="application"></div>';
1566
1567         return head;
1568 }
1569
1570 function generateHeadCharts(type, chart, duration) {
1571         var head = '';
1572         var hcharts = anyAttribute(chartData, type, chart.context, []);
1573         if(hcharts.length > 0) {
1574                 var hi = 0, hlen = hcharts.length;
1575                 while(hi < hlen) {
1576                         if(typeof hcharts[hi] === 'function')
1577                                 head += hcharts[hi](chart.id).replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
1578                         else
1579                                 head += hcharts[hi].replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
1580                         hi++;
1581                 }
1582         }
1583         return head;
1584 }
1585
1586 function renderPage(menus, data) {
1587         var div = document.getElementById('charts_div');
1588         var pcent_width = Math.floor(100 / chartsPerRow($(div).width()));
1589
1590         // find the proper duration for per-second updates
1591         var duration = Math.round(($(div).width() * pcent_width / 100 * data.update_every / 3) / 60) * 60;
1592         var html = '';
1593         var sidebar = '<ul class="nav dashboard-sidenav" data-spy="affix" id="sidebar_ul">';
1594         var mainhead = headMain(data.charts, duration);
1595
1596         // sort the menus
1597         var main = sortObjectByPriority(menus);
1598         var i = 0, len = main.length;
1599         while(i < len) {
1600                 var menu = main[i++];
1601
1602                 // generate an entry at the main menu
1603
1604                 sidebar += '<li class=""><a href="#' + name2id(menu) + '">' + menus[menu].title + '</a><ul class="nav">';
1605                 html += '<div role="section"><div role="sectionhead"><h1 id="' + menu + '" role="heading">' + menus[menu].title + '</h1></div><div id="' + menu + '" role="document">';
1606
1607                 if(menus[menu].info !== null)
1608                         html += menus[menu].info;
1609
1610                 // console.log(' >> ' + menu + ' (' + menus[menu].priority + '): ' + menus[menu].title);
1611
1612                 var shtml = '';
1613                 var mhead = '<div style="width: 100%; text-align: center;">' + mainhead;
1614                 mainhead = '';
1615
1616                 // sort the submenus of this menu
1617                 var sub = sortObjectByPriority(menus[menu].submenus);
1618                 var si = 0, slen = sub.length;
1619                 while(si < slen) {
1620                         var submenu = sub[si++];
1621
1622                         // generate an entry at the submenu
1623                         sidebar += '<li class><a href="#' + name2id(menu + '_' + submenu) + '">' + menus[menu].submenus[submenu].title + '</a></li>';
1624                         shtml += '<div class="netdata-group-container" id="submenu_' + name2id(menu + '_' + submenu) + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 id="' + name2id(menu + '_' + submenu) + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>';
1625
1626                         if(menus[menu].submenus[submenu].info !== null)
1627                                 shtml += '<div class="chart-message netdata-chart-alignment" role="document">' + menus[menu].submenus[submenu].info + '</div>';
1628
1629                         var head = '<div style="width: 100%; text-align: center;">';
1630                         var chtml = '';
1631
1632                         // console.log('    \------- ' + submenu + ' (' + menus[menu].submenus[submenu].priority + '): ' + menus[menu].submenus[submenu].title);
1633
1634                         // sort the charts in this submenu of this menu
1635                         menus[menu].submenus[submenu].charts.sort(prioritySort);
1636                         var ci = 0, clen = menus[menu].submenus[submenu].charts.length;
1637                         while(ci < clen) {
1638                                 var chart = menus[menu].submenus[submenu].charts[ci++];
1639
1640                                 // generate the submenu heading charts
1641                                 mhead += generateHeadCharts('mainheads', chart, duration);
1642                                 head += generateHeadCharts('heads', chart, duration);
1643
1644                                 // generate the chart
1645                                 chtml += chartInfo(chart.context) + '<div data-netdata="' + chart.id + '"'
1646                                         + ' data-width="' + pcent_width.toString() + '%"'
1647                                         + ' data-height="' + chartHeight(chart.context, options.chartsHeight).toString() + 'px"'
1648                                         + ' data-before="0"'
1649                                         + ' data-after="-' + duration.toString() + '"'
1650                                         + ' data-id="' + name2id(options.hostname + '/' + chart.id) + '"'
1651                                         + ' data-colors="' + anyAttribute(chartData, 'colors', chart.context, '') + '"'
1652                                         + ' role="application"></div>';
1653
1654                                 // console.log('         \------- ' + chart.id + ' (' + chart.priority + '): ' + chart.context  + ' height: ' + menus[menu].submenus[submenu].height);
1655                         }
1656
1657                         head += '</div>';
1658                         shtml += head + chtml + '</div>';
1659                 }
1660
1661                 mhead += '</div>';
1662                 sidebar += '</ul></li>';
1663                 html += mhead + shtml + '</div></div><hr role="separator"/>';
1664         }
1665
1666         sidebar += '</ul>';
1667         div.innerHTML = html;
1668         document.getElementById('sidebar').innerHTML = sidebar;
1669         finalizePage();
1670 }
1671
1672 function renderChartsAndMenu(data) {
1673         var menus = {};
1674         var charts = data.charts;
1675
1676         for(var c in charts) {
1677                 enrichChartData(charts[c]);
1678
1679                 // create the menu
1680                 if(typeof menus[charts[c].menu] === 'undefined') {
1681                         menus[charts[c].menu] = {
1682                                 priority: charts[c].priority,
1683                                 submenus: {},
1684                                 title: menuTitle(charts[c]),
1685                                 info: menuInfo(charts[c].menu),
1686                                 height: menuHeight(charts[c].menu, options.chartsHeight)
1687                         };
1688                 }
1689
1690                 if(charts[c].priority < menus[charts[c].menu].priority)
1691                         menus[charts[c].menu].priority = charts[c].priority;
1692
1693                 // create the submenu
1694                 if(typeof menus[charts[c].menu].submenus[charts[c].submenu] === 'undefined') {
1695                         menus[charts[c].menu].submenus[charts[c].submenu] = {
1696                                 priority: charts[c].priority,
1697                                 charts: new Array(),
1698                                 title: null,
1699                                 info: submenuInfo(charts[c].menu, charts[c].submenu),
1700                                 height: submenuHeight(charts[c].menu, charts[c].submenu, menus[charts[c].menu].height)
1701                         };
1702                 }
1703
1704                 if(charts[c].priority < menus[charts[c].menu].submenus[charts[c].submenu].priority)
1705                         menus[charts[c].menu].submenus[charts[c].submenu].priority = charts[c].priority;
1706
1707                 // index the chart in the menu/submenu
1708                 menus[charts[c].menu].submenus[charts[c].submenu].charts.push(charts[c]);
1709         }
1710
1711         // propagate the descriptive subname given to QoS
1712         // to all the other submenus with the same name
1713         for(var m in menus) {
1714                 for(var s in menus[m].submenus) {
1715                         // set the family using a name
1716                         if(typeof options.submenu_names[s] !== 'undefined') {
1717                                 menus[m].submenus[s].title = s + ' (' + options.submenu_names[s] + ')';
1718                         }
1719                         else {
1720                                 menus[m].submenus[s].title = submenuTitle(m, s);
1721                         }
1722                 }
1723         }
1724
1725         renderPage(menus, data);
1726 }
1727
1728 function downloadAllCharts(netdata_url) {
1729         if(typeof netdata_url === 'undefined' || netdata_url === null)
1730                 netdata_url = NETDATA.serverDefault;
1731
1732         NETDATA.pause(function() {
1733
1734                 // download all the charts the server knows
1735                 NETDATA.chartRegistry.downloadAll(netdata_url, function(data) {
1736
1737                         options.data = data;
1738                         options.hostname = data.hostname;
1739                         document.getElementById('hostname').innerHTML = options.hostname;
1740                         document.getElementById('hostname').href = NETDATA.serverDefault;
1741                         document.title = options.hostname + ' dashboard';
1742
1743                         renderChartsAndMenu(data);
1744
1745                         // prepare our DOM
1746 //                      prepareScreen(data);
1747
1748                         // due to affix issues, prepareScreen() will unpause
1749                         // netdata as needed
1750                 });
1751         });
1752 }
1753
1754 // ----------------------------------------------------------------------------
1755
1756 function versionLog(msg) {
1757         document.getElementById('versionCheckLog').innerHTML = msg;
1758 }
1759
1760 function getNetdataVersion(callback) {
1761         versionLog('Downloading installed version info from netdata...');
1762
1763         $.ajax({
1764                 url: 'version.txt',
1765                 async: true,
1766                 cache: false
1767         })
1768         .done(function(data) {
1769                 data = data.replace(/(\r\n|\n|\r| |\t)/gm,"");
1770                 if(data.length !== 40) {
1771                         versionLog('Received version string is invalid.');
1772                         callback(null);
1773                 }
1774                 else {
1775                         versionLog('Installed version of netdata is ' + data);
1776                         document.getElementById('netdataVersion').innerHTML = data;
1777                         callback(data);
1778                 }
1779         })
1780         .fail(function() {
1781                 versionLog('Failed to download installed version info from netdata!');
1782                 callback(null);
1783         });
1784 }
1785
1786 function getGithubLatestCommit(callback) {
1787         versionLog('Downloading latest version info from github...');
1788
1789         $.ajax({
1790                 url: 'https://api.github.com/repos/firehol/netdata/commits',
1791                 async: true,
1792                 cache: false
1793         })
1794         .done(function(data) {
1795                 versionLog('Latest version info from github is ' + data[0].sha);
1796                 callback(data[0].sha);
1797         })
1798         .fail(function() {
1799                 versionLog('Failed to download installed version info from github!');
1800                 callback(null);
1801         });
1802 }
1803
1804 function checkForUpdate(callback) {
1805         getNetdataVersion(function(sha1) {
1806                 if(sha1 === null) callback(null, null);
1807
1808                 getGithubLatestCommit(function(sha2) {
1809                         callback(sha1, sha2);
1810                 });
1811         });
1812
1813         return null;
1814 }
1815
1816 var updateBlinkCounter = 0;
1817 function notifyForUpdate(force) {
1818         versionLog('<p>checking for updates...</p>');
1819
1820         var now = new Date().getTime();
1821
1822         if(typeof force === 'undefined' || force !== true) {
1823                 var last = loadLocalStorage('last_update_check');
1824
1825                 if(typeof last === 'string')
1826                         last = parseInt(last);
1827                 else
1828                         last = 0;
1829
1830                 if(now - last < 3600000 * 8) {
1831                         // no need to check it - too soon
1832                         return;
1833                 }
1834         }
1835
1836         checkForUpdate(function(sha1, sha2) {
1837                 var save = false;
1838
1839                 if(sha1 === null) {
1840                         save = false;
1841                         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>');
1842                 }
1843                 else if(sha2 === null) {
1844                         save = false;
1845                         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>');
1846                 }
1847                 else if(sha1 === sha2) {
1848                         save = true;
1849                         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>');
1850                 }
1851                 else {
1852                         save = true;
1853                         var compare = 'https://github.com/firehol/netdata/compare/' + sha1.toString() + '...' + sha2.toString();
1854
1855                         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>');
1856
1857                         function updateButtonBlink() {
1858                                 updateBlinkCounter--;
1859                                 if(updateBlinkCounter > 0)
1860                                         $('#updateButton').fadeOut(500).fadeIn(500, updateButtonBlink);
1861                         }
1862
1863                         if(updateBlinkCounter === 0) {
1864                                 updateBlinkCounter = 300;
1865                                 updateButtonBlink();
1866                         }
1867                 }
1868
1869                 if(save)
1870                         saveLocalStorage('last_update_check', now.toString());
1871         });
1872 }
1873
1874 // ----------------------------------------------------------------------------
1875
1876 function getUrlParameter(sParam) {
1877     var sPageURL = decodeURIComponent(window.location.search.substring(1)),
1878         sURLVariables = sPageURL.split('&'),
1879         sParameterName,
1880         i;
1881
1882     for (i = 0; i < sURLVariables.length; i++) {
1883         sParameterName = sURLVariables[i].split('=');
1884
1885         if (sParameterName[0] === sParam) {
1886             return sParameterName[1] === undefined ? true : sParameterName[1];
1887         }
1888     }
1889 }
1890
1891 function finalizePage() {
1892         // resize all charts - without starting the background thread
1893         // this has to be done while NETDATA is paused
1894         // if we ommit this, the affix menu will be wrong, since all
1895         // the Dom elements are initially zero-sized
1896         NETDATA.parseDom();
1897
1898         var before = 0, after = 0, nowelcome = 0;
1899         after = getUrlParameter('force_after_ms');
1900         before = getUrlParameter('force_before_ms');
1901         nowelcome = (getUrlParameter('nowelcome') === true)?true:false;
1902
1903         if(before > 0 && after > 0) {
1904                 nowelcome = true;
1905                 NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], after, before);
1906         }
1907
1908         // let it run (update the charts)
1909         NETDATA.unpause();
1910
1911         // check if we have to jump to a specific section
1912         var hash = location.hash.replace('#','');
1913         if(hash != '') {
1914                 // Clear the hash in the URL
1915                 // location.hash = '';   // delete front "//" if you want to change the address bar
1916                 var offset = $(location.hash).offset();
1917                 if(typeof offset !== 'undefined')
1918                         $('html, body').animate({ scrollTop: offset.top }, 0);
1919         }
1920
1921         /* activate bootstrap sidebar (affix) */
1922         $('#sidebar').affix({
1923                 offset: {
1924                         top: (isdemo())?150:0,
1925                         bottom: 0
1926                 }
1927         });
1928
1929         /* fix scrolling of very long affix lists
1930            http://stackoverflow.com/questions/21691585/bootstrap-3-1-0-affix-too-long
1931          */
1932         $('#sidebar').on('affixed.bs.affix', function() {
1933                 $(this).removeAttr('style');
1934         });
1935
1936         /* activate bootstrap scrollspy (needed for sidebar) */
1937         $(document.body).scrollspy({
1938                 target: '#sidebar',
1939                 offset: $(window).height() / 3 // controls the diff of the <hX> element to the top, to select it
1940         });
1941
1942         document.getElementById('footer').style.display = 'block';
1943
1944
1945         var update_options_modal = function() {
1946                 // console.log('update_options_modal');
1947
1948                 var sync_option = function(option) {
1949                         var self = $('#' + option);
1950
1951                         if(self.prop('checked') !== NETDATA.getOption(option)) {
1952                                 // console.log('switching ' + option.toString());
1953                                 self.bootstrapToggle(NETDATA.getOption(option)?'on':'off');
1954                         }
1955                 }
1956
1957                 var theme_sync_option = function(option) {
1958                         var self = $('#' + option);
1959
1960                         self.bootstrapToggle(netdataTheme === 'slate'?'on':'off');
1961                 }
1962
1963                 sync_option('eliminate_zero_dimensions');
1964                 sync_option('destroy_on_hide');
1965                 sync_option('parallel_refresher');
1966                 sync_option('concurrent_refreshes');
1967                 sync_option('sync_selection');
1968                 sync_option('sync_pan_and_zoom');
1969                 sync_option('stop_updates_when_focus_is_lost');
1970                 sync_option('smooth_plot');
1971                 sync_option('pan_and_zoom_data_padding');
1972                 sync_option('show_help');
1973                 theme_sync_option('netdata_theme_control');
1974
1975                 if(NETDATA.getOption('parallel_refresher') === false) {
1976                         $('#concurrent_refreshes_row').hide();
1977                 }
1978                 else {
1979                         $('#concurrent_refreshes_row').show();
1980                 }
1981         };
1982         NETDATA.setOption('setOptionCallback', update_options_modal);
1983
1984         // handle options changes
1985         $('#eliminate_zero_dimensions').change(function()       { NETDATA.setOption('eliminate_zero_dimensions', $(this).prop('checked')); });
1986         $('#destroy_on_hide').change(function()                 { NETDATA.setOption('destroy_on_hide', $(this).prop('checked')); });
1987         $('#parallel_refresher').change(function()              { NETDATA.setOption('parallel_refresher', $(this).prop('checked')); });
1988         $('#concurrent_refreshes').change(function()            { NETDATA.setOption('concurrent_refreshes', $(this).prop('checked')); });
1989         $('#sync_selection').change(function()                  { NETDATA.setOption('sync_selection', $(this).prop('checked')); });
1990         $('#sync_pan_and_zoom').change(function()               { NETDATA.setOption('sync_pan_and_zoom', $(this).prop('checked')); });
1991         $('#stop_updates_when_focus_is_lost').change(function() { NETDATA.setOption('stop_updates_when_focus_is_lost', $(this).prop('checked')); });
1992         $('#smooth_plot').change(function()                     { NETDATA.setOption('smooth_plot', $(this).prop('checked')); });
1993         $('#pan_and_zoom_data_padding').change(function()       { NETDATA.setOption('pan_and_zoom_data_padding', $(this).prop('checked')); });
1994         $('#show_help').change(function()                       { NETDATA.setOption('show_help', $(this).prop('checked')); location.reload(); });
1995
1996         // this has to be the last
1997         // it reloads the page
1998         $('#netdata_theme_control').change(function() {
1999                 if(setTheme($(this).prop('checked')?'slate':'white'))
2000                         location.reload();
2001         });
2002
2003         if(!nowelcome && isdemo()) {
2004                 setTimeout(function() {
2005                         $('#welcomeModal').modal();
2006                 }, 1000);
2007         }
2008         else
2009                 notifyForUpdate();
2010
2011         $('#updateModal').on('shown.bs.modal', function() {
2012                 notifyForUpdate(true);
2013         });
2014 }
2015
2016 function resetDashboardOptions() {
2017         var help = NETDATA.options.current.show_help;
2018
2019         NETDATA.resetOptions();
2020         if(setTheme('slate'))
2021                 location.reload();
2022
2023         if(help !== NETDATA.options.current.show_help)
2024                 location.reload();
2025 }
2026
2027 downloadAllCharts();
2028
2029 </script>
2030
2031 </body>
2032 </html>