]> arthur.barton.de Git - netdata.git/blob - web/index.html
added /proc/vmstat support; added a lot of detailed charts for interfaces, disks...
[netdata.git] / web / index.html
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5     <meta charset="utf-8">
6     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
7     <meta name="viewport" content="width=device-width, initial-scale=1">
8     <meta name="apple-mobile-web-app-capable" content="yes">
9     <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
10     <meta name="description" content="">
11     <meta name="author" content="costa@tsaousis.gr">
12  
13         <title>NetData</title>
14
15         <!-- Google AJAX API -->
16         <script type="text/javascript" src="https://www.google.com/jsapi"></script>
17         <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
18
19         <!-- Bootstrap -->
20         <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
21         <!-- <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css"> -->
22         <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
23         <link href="/file/theme.css" rel="stylesheet">
24
25         <!-- NetData -->
26         <script type="text/javascript" src="/file/netdata.js"></script>
27         <script type="text/javascript" src="/file/jquery.visible.js"></script>
28         <script type="text/javascript">
29         
30         // Set a callback to run when the Google Visualization API is loaded.
31         google.setOnLoadCallback(initCharts);
32         
33         var TARGET_THUMB_GRAPH_WIDTH = 500; // chart width will range from 0.5 to 1.5 of that
34         var MINIMUM_THUMB_GRAPH_WIDTH = 400; // chart will generally try to be wider than that
35         var TARGET_THUMB_GRAPH_HEIGHT = 220;
36         var MAINCHART_MAX_TIME_TO_SHOW = 1200;
37         var THUMBS_MAX_TIME_TO_SHOW = 600;
38
39         var MODE_THUMBS = 1;
40         var MODE_MAIN = 2;
41         var mode; // one of the MODE_* values
42
43         var mycharts = new Array();
44         var mainchart;
45
46         function chartIsLoadingHTML(width, height) { return "<table><tr><td align=\"center\" width=\"" + width + "\" height=\"" + height + "\" style=\"vertical-align:middle\"><h4><span class=\"glyphicon glyphicon-refresh\"></span><br/><br/>loading chart<br/><br/><span class=\"label label-default\">Please wait...</span></h4></td></tr></table>"; }
47
48         function showChartIsLoading(id, width, height) { document.getElementById(id).innerHTML = chartIsLoadingHTML(width, height); }
49
50         // copy the chart c to mainchart
51         // switch to main graphs screen
52         function mainChart(c) {
53                 if(mainchart && mainchart.chart) mainchart.chart.clearChart();
54
55                 mainchart = $.extend(true, {}, c);
56
57                 mainchart.chart = null;
58                 mainchart.chartOptions.width = screenWidth();
59                 mainchart.chartOptions.height = $(window).height() - 200;
60                 if(mainchart.chartOptions.height < 300) mainchart.chartOptions.height = 300;
61                 
62                 mainchart.group = 2;
63                 mainchart.div = 'maingraph';
64                 mainchart.last_updated = 0;
65
66                 if(mainchart.chartOptions.isStacked) mainchart.group = 5;
67                 //mainchart.chartOptions.titlePosition = 'none';
68                 mainchart.chartOptions.explorer = null;
69
70                 // initialize the div
71                 showChartIsLoading(mainchart.div, mainchart.chartOptions.width, mainchart.chartOptions.height);
72
73                 document.getElementById('maingraph_title').innerHTML = " " + mainchart.title + " ";
74
75                 // set the radio buttons
76                 setMainChartGroupMethod(mainchart.group_method, 'no-refresh');
77                 setMainChartMax('normal');
78
79                 $('#group' + mainchart.group).trigger('click');
80
81                 showMainGraph();
82         }
83
84         function setMainChart(i) {
85                 mainChart(mycharts[i]);
86         }
87
88         var last_main_chart_max='normal';
89         function setMainChartMax(m) {
90                 if(!mainchart) return;
91
92                 if(m == 'toggle') {
93                         if(last_main_chart_max == 'maximized') m = 'normal';
94                         else m = 'maximized';
95                 }
96
97                 if(m == "maximized") {
98                         mainchart.chartOptions.theme = 'maximized';
99                         //mainchart.chartOptions.axisTitlesPosition = 'in';
100                         //mainchart.chartOptions.legend = {position: 'none'};
101                         //mainchart.chartOptions.hAxis.title = null;
102                         mainchart.chartOptions.hAxis.viewWindowMode = 'maximized';
103                         mainchart.chartOptions.vAxis.viewWindowMode = 'maximized';
104                 }
105                 else {
106                         mainchart.chartOptions.theme = null;
107                         mainchart.chartOptions.hAxis.viewWindowMode = null;
108                         mainchart.chartOptions.vAxis.viewWindowMode = null;
109                 }
110                 $('.mainchart_max_button').button(m);
111                 last_main_chart_max = m;
112                 mainchart.last_updated = 0;
113         }
114
115         function setMainChartGroup(g) {
116                 if(!mainchart) return;
117
118                 mainchart.group = g;
119                 mainchart.last_updated = 0;
120
121                 chartsRefresh();
122         }
123
124         var last_main_chart_avg = null;
125         function setMainChartGroupMethod(g, norefresh) {
126                 if(!mainchart) return;
127
128                 if(g == 'toggle') {
129                         if(last_main_chart_avg == 'max') g = 'average';
130                         else g = 'max';
131                 }
132
133                 mainchart.group_method = g;
134
135                 $('.mainchart_avg_button').button(g);
136
137                 if(!norefresh) {
138                         mainchart.last_updated = 0;
139                         chartsRefresh();
140                 }
141
142                 last_main_chart_avg = g;
143         }
144
145         var stop_refreshing = 0;
146         function playGraphs() {
147                 stop_refreshing = 0;
148                 $('.mainchart_play_button').button('play');
149                 chartsRefresh();
150         }
151         function pauseGraphs() {
152                 stop_refreshing = 1;
153                 $('.mainchart_play_button').button('pause');
154         }
155
156         function setMainChartPlay(p) {
157                 if(!mainchart) return;
158
159                 if(p == 'toggle') {
160                         if(stop_refreshing) p = 'play';
161                         else p = 'pause';
162                 }
163
164                 if(p == 'play') {
165                         mainchart.chartOptions.explorer = null;
166                         playGraphs();
167                 }
168                 else {
169                         mainchart.chartOptions.explorer = {
170                                 'axis': 'horizontal',
171                                 'maxZoomOut': 1,
172                         };
173                         mainchart.last_updated = 0;
174                         refreshChart(mainchart, pauseGraphs);
175                 }
176                 last_main_chart_play = p;
177         }
178
179         // refresh the main chart
180         // make sure it gets updated frequently
181         function mainChartRefresh() {
182                 if(!mainchart || mode != MODE_MAIN) {
183                         if(mainchart) mainchart.clearChart();
184                         showThumbGraphs();
185                         return;
186                 }
187
188                 mainchart.points_to_show = Math.round(mainchart.entries / mainchart.group) - 1;
189
190                 if(mainchart.points_to_show * mainchart.group > MAINCHART_MAX_TIME_TO_SHOW)
191                         mainchart.points_to_show = MAINCHART_MAX_TIME_TO_SHOW / mainchart.group;
192
193                 if(!refreshChart(mainchart, triggerRefresh)) triggerRefresh();
194
195                 // FIXME for controlled charts
196                 // showChartWithRange(mainchart);
197         }
198
199         function screenWidth() {
200                 return (($(window).width() * 0.95) - 40);
201         }
202
203         // calculate the proper width for the thumb charts
204         function thumbWidth() {
205                 var cwidth = screenWidth();
206                 var items = Math.round(cwidth / TARGET_THUMB_GRAPH_WIDTH);
207                 if(items < 1) items = 1;
208
209                 if(items > 1 && (cwidth / items) < MINIMUM_THUMB_GRAPH_WIDTH) items--;
210
211                 return Math.round(cwidth / items) - 1;
212         }
213
214         // resize all charts
215         // if the thumb charts need resize in their width, reset them
216         function resizeCharts() {
217                 var width = screenWidth();
218
219                 if(mainchart) {
220                         mainchart.chartOptions.width = width;
221                         mainchart.chartOptions.height = $(window).height() - 200;
222                         mainchart.last_updated = 0;
223                 }
224
225                 width = thumbWidth();
226                 $.each(mycharts, function(i, c) {
227                         if(c.enabled && c.chartOptions.width != width) {
228                                 if(c.chart) c.chart.clearChart();
229                                 c.chart = null;
230                                 c.chartOptions.width = width;
231                                 showChartIsLoading(c.div, c.chartOptions.width, c.chartOptions.height);
232                                 c.last_updated = 0;
233                         }
234                 });
235
236                 playGraphs();
237         }
238
239         // load the charts from the server
240         // generate html for the thumbgraphs to support them
241         function initCharts() {
242                 var width = thumbWidth();
243                 var height = TARGET_THUMB_GRAPH_HEIGHT;
244
245                 loadCharts(null, function(c) {
246                         mycharts = c;
247
248                         if(mycharts == null || mycharts.length == 0) {
249                                 alert("Cannot load data from server.");
250                                 return;
251                         }
252
253                         var thumbsContainer = document.getElementById("thumbgraphs");
254                         if(!thumbsContainer) {
255                                 alert("Cannot find the thumbsContainer");
256                                 return;
257                         }
258
259                         function chartssort(a, b) {
260                                 if(a.userpriority < b.userpriority) return -1;
261                                 return 1;
262                         }
263                         mycharts.sort(chartssort);
264
265                         document.getElementById('hostname_id').innerHTML = mycharts[0].hostname;
266                         document.title = mycharts[0].hostname;
267
268                         // create an array for grouping all same-type graphs together
269                         var categories = new Array();
270                         $.each(mycharts, function(i, c) {
271                                 c.chartOptions.width = width;
272                                 c.chartOptions.height = height;
273
274                                 // calculate how many point to show for each chart
275                                 c.points_to_show = Math.round(c.entries / c.group) - 1;
276
277                                 // show max 10 mins of data
278                                 if(c.points_to_show * c.group > THUMBS_MAX_TIME_TO_SHOW) c.points_to_show = THUMBS_MAX_TIME_TO_SHOW / c.group;
279
280                                 if(c.enabled) {
281                                         var j;
282                                         var h = "<div class=\"thumbgraph\"><table><tr><td><div class=\"thumbgraph\" id=\"" + c.div + "\">" + chartIsLoadingHTML(c.chartOptions.width, c.chartOptions.height) + "</div></td></tr><tr><td align=\"center\"><div class=\"btn-group-xs\"><button type=\"button\" class=\"btn btn-default\" onclick=\"setMainChart(" + i +");\">&nbsp;&nbsp;select " + c.name + " for zoom&nbsp;&nbsp;</button></div></td></tr></table></div>";
283
284                                         // find the categories object for this type
285                                         for(j = 0; j < categories.length ;j++) {
286                                                 if(categories[j].name == c.type) {
287                                                         categories[j].html += h;
288                                                         categories[j].count++;
289                                                         break;
290                                                 }
291                                         }
292
293                                         if(j == categories.length) {
294                                                 var t = "(as " + c.group_method + " every " + (c.group * c.update_every) + " seconds)";
295                                                 categories.push({name: c.type, title: c.category, description: t, priority: 0, count: 1, glyphicon: c.glyphicon, html: h});
296                                         }
297                                 }
298                         });
299
300                         $.each(categories, function(i, a) {
301                                      if(a.name == "system") a.priority = 1;
302                                 else if(a.name == "net") a.priority = 2;
303                                 else if(a.name == "tc") a.priority = 3;
304                                 else if(a.name == "conntrack") a.priority = 4;
305                                 else if(a.name == "ipvs") a.priority = 5;
306                                 else if(a.name == "ipv4") a.priority = 6;
307                                 else if(a.name == "cpu") a.priority = 7;
308                                 else if(a.name == "mem") a.priority = 8;
309                                 else if(a.name == "disk") a.priority = 9;
310                                 else a.priority = 99;
311
312                                 a.html = "<tr><td id=\"" + a.name + "\"><ol class=\"breadcrumb graphs\"><li class=\"active\"><span class=\"glyphicon " + a.glyphicon + "\"></span> &nbsp; <a id=\"" + a.name + "\" href=\"#" + a.name + "\"><b>" + a.title + "</b> " + a.description + " </a></li></ol></td></tr><tr><td><div class=\"thumbgraphs\">" + a.html + "</td></tr>";
313                         });
314
315                         function categoriessort(a, b) {
316                                 if(a.priority < b.priority) return -1;
317                                 return 1;
318                         }
319                         categories.sort(categoriessort);
320
321                         // combine all the htmls into one
322                         var allcategories = "<table width=\"100%\">";
323                         $.each(categories, function(i, a) {
324                                 allcategories += a.html;
325                         });
326                         allcategories += "</table>";
327
328                         thumbsContainer.innerHTML = allcategories;
329                         showThumbGraphs();
330                 });
331         }
332
333         var last_thumb_updated = 0;
334         function thumbChartsRefresh() {
335                 if(mycharts.length == 0 || mode != MODE_THUMBS) return;
336
337                 // find a chart to refresh
338                 var orig = last_thumb_updated;
339                 last_thumb_updated++;
340                 if(last_thumb_updated >= mycharts.length) last_thumb_updated = 0;
341
342                 while(last_thumb_updated != orig) {
343                         if(refreshChart(mycharts[last_thumb_updated], chartsRefresh)) break;
344
345                         last_thumb_updated++;
346                         if(last_thumb_updated >= mycharts.length) last_thumb_updated = 0;
347                 }
348
349                 // no chart refreshed
350                 if(last_thumb_updated == orig) triggerRefresh();
351         }
352
353         // refresh the proper chart
354         var timeout;
355         function chartsRefresh() {
356                 if(stop_refreshing) return;
357
358                 if(timeout) {
359                         clearTimeout(timeout);
360                         timeout = null;
361                 }
362
363                      if(mode == MODE_THUMBS) thumbChartsRefresh();
364                 else if(mode == MODE_MAIN)   mainChartRefresh();
365                 else                         timeout = setTimeout(triggerRefresh, 1000);
366         }
367
368         // callback for refreshing the charts later
369         function triggerRefresh() {
370                      if(mode == MODE_THUMBS) timeout = setTimeout(chartsRefresh, 200);
371                 else if(mode == MODE_MAIN)   timeout = setTimeout(chartsRefresh, 500);
372                 else                         timeout = setTimeout(triggerRefresh, 1000);
373         }
374
375         window.onresize = function(event) {
376                 resizeCharts();
377         };
378
379         var thumbsScrollPosition = null;
380         function showMainGraph() {
381                 if(!mainchart) return;
382
383                 thumbsScrollPosition = window.pageYOffset;
384
385                 mode = MODE_MAIN;
386
387                 document.getElementById('maingraph_container').style.display = 'block';
388                 document.getElementById('thumbgraphs_container').style.display = 'none';
389
390                 playGraphs();
391         }
392
393         function showThumbGraphs() {
394                 mode = MODE_THUMBS;
395
396                 document.getElementById('maingraph_container').style.display = 'none';
397                 document.getElementById('thumbgraphs_container').style.display = 'block';
398
399                 if(thumbsScrollPosition) window.scrollTo(0, thumbsScrollPosition);
400
401                 if(mainchart) {
402                         if(mainchart.chart) mainchart.chart.clearChart();
403                         mainchart = null;
404                 }
405
406                 playGraphs();
407         }
408
409         </script>
410 </head>
411
412 <body role="document">
413     <nav id="mynav" class="navbar navbar-inverse navbar-fixed-top" role="navigation">
414       <div class="container">
415         <div class="navbar-header">
416           <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
417             <span class="sr-only">Toggle navigation</span>
418             <span class="icon-bar"></span>
419             <span class="icon-bar"></span>
420             <span class="icon-bar"></span>
421           </button>
422           <a class="navbar-brand" href="#" id="hostname_id">NetData</a>
423         </div>
424         <div class="collapse navbar-collapse">
425           <ul class="nav navbar-nav">
426             <li class="active"><a href="#">Home</a></li>
427             <li><a href="#system">System</a></li>
428             <li><a href="#net">Network</a></li>
429             <li><a href="#tc">QoS</a></li>
430             <li><a href="#conntrack">Netfilter</a></li>
431             <li><a href="#ipv4">IPv4</a></li>
432             <li><a href="#ipvs">IPVS</a></li>
433             <li><a href="#cpu">CPU</a></li>
434             <li><a href="#disk">Disk</a></li>
435           </ul>
436         </div><!--/.nav-collapse -->
437       </div>
438     </nav>
439
440     <div class="container graphs" id="maingraph_container" style="display: none">
441                 <table>
442                         <tr><td><ol class="breadcrumb graphs"><li class="active"><div class="btn-group btn-group-sm"><button type="button" onclick="showThumbGraphs();" class="btn btn-default"> &larr; Back </button></div><a id="maingraph_title" href="#maingraph"><b> Maingraph </b></a></li></ol></td></tr>
443                         <tr><td>
444                         <div class="maingraph">
445                                         <table>
446                                                 <tr><td>
447                                                 <div class="maingraph" id="maingraph"></div>
448                                                 </td></tr>
449                                                 <tr><td align="center">
450                                                         <div class="btn-group">
451                                                                 <form id="mainchartform">
452                                                                         <div class="btn-group btn-group-xs" data-toggle="tooltip" title=" click <span class='glyphicon glyphicon-play'></span> to have the graph auto-refresh, or click <span class='glyphicon glyphicon-pause'></span> to pause the graph. When paused the graph can be zoomed and panned horizontally." >
453                                                                                 <button type="button" class="btn btn-primary mainchart_play_button" data-play-text="<span class='glyphicon glyphicon-pause'></span>" data-pause-text="<span class='glyphicon glyphicon-play'></span>" onClick="setMainChartPlay('toggle');">
454                                                                                         <span class="glyphicon glyphicon-pause"></span>
455                                                                                 </button>
456                                                                         </div>
457                                                                         <div class="btn-group btn-group-xs" data-toggle="tooltip" title="use the maximum ( <span class='glyphicon glyphicon-signal'></span> ) or the average ( <span class='glyphicon glyphicon-align-justify'></span> ) value of grouped points" >
458                                                                                 <button type="button" class="btn btn-primary mainchart_avg_button" data-max-text="<span class='glyphicon glyphicon-signal'></span>" data-average-text="<span class='glyphicon glyphicon-align-justify'></span>" onClick="setMainChartGroupMethod('toggle');">
459                                                                                         <span class="glyphicon glyphicon-signal"></span>
460                                                                                 </button>
461                                                                         </div>
462 <!--                                                                    <div class="btn-group btn-group-xs" data-toggle="buttons">
463                                                                                 <label class="btn btn-primary" data-toggle="tooltip" title="show the MAX point among all points grouped">
464                                                                                         <input type="radio" name="groupmethod" id="groupmax" onChange="setMainChartGroupMethod('max');">
465                                                                                         <span class="glyphicon glyphicon-signal"></span>
466                                                                                 </label>
467                                                                                 <label class="btn btn-primary" data-toggle="tooltip" title="show the AVERAGE of all points grouped">
468                                                                                         <input type="radio" name="groupmethod" id="groupaverage" onChange="setMainChartGroupMethod('average');">
469                                                                                         <span class="glyphicon glyphicon-align-justify"></span>
470                                                                                 </label>
471                                                                         </div>
472 -->                                                                     <div class="btn-group btn-group-xs" data-toggle="buttons" >
473                                                                                 <label class="btn btn-primary" data-toggle="tooltip" title="do not group points, show the raw data">
474                                                                                         <input type="radio" name="group" id="group1" onChange="setMainChartGroup(1);">1
475                                                                                 </label>
476                                                                                 
477                                                                                 <label class="btn btn-primary" data-toggle="tooltip" title="group in half, show 1 every 2 points of data">
478                                                                                         <input type="radio" name="group" id="group2" onChange="setMainChartGroup(2);">2
479                                                                                 </label>
480
481                                                                                 <label class="btn btn-primary" data-toggle="tooltip" title="group every 5 points of data">
482                                                                                         <input type="radio" name="group" id="group5" onChange="setMainChartGroup(5);">5
483                                                                                 </label>
484                                                                                 <label class="btn btn-primary" data-toggle="tooltip" title="group every 10 points of data">
485                                                                                         <input type="radio" name="group" id="group10" onChange="setMainChartGroup(10);">10
486                                                                                 </label>
487                                                                                 <label class="btn btn-primary" data-toggle="tooltip" title="group every 15 points of data">
488                                                                                         <input type="radio" name="group" id="group15" onChange="setMainChartGroup(15);">15
489                                                                                 </label>
490                                                                                 <label class="btn btn-primary" data-toggle="tooltip" title="group every 20 points of data">
491                                                                                         <input type="radio" name="group" id="group20" onChange="setMainChartGroup(20);">20
492                                                                                 </label>
493                                                                                 <label class="btn btn-primary" data-toggle="tooltip" title="group every 30 points of data">
494                                                                                         <input type="radio" name="group" id="group30" onChange="setMainChartGroup(30);">30
495                                                                                 </label>
496                                                                                 <label class="btn btn-primary" data-toggle="tooltip" title="group every 45 points of data">
497                                                                                         <input type="radio" name="group" id="group45" onChange="setMainChartGroup(45);">45
498                                                                                 </label>
499                                                                                 <label class="btn btn-primary" data-toggle="tooltip" title="group every 60 points of data">
500                                                                                         <input type="radio" name="group" id="group60" onChange="setMainChartGroup(60);">60
501                                                                                 </label>
502                                                                         </div>
503                                                                         <div class="btn-group btn-group-xs" data-toggle="tooltip" title="maximized ( <span class='glyphicon glyphicon-fullscreen'></span> ) or normal ( <span class='glyphicon glyphicon-resize-small'></span> ) view of the graph" >
504                                                                                 <button type="button" class="btn btn-primary mainchart_max_button" data-maximized-text="<span class='glyphicon glyphicon-resize-small'></span>" data-normal-text="<span class='glyphicon glyphicon-fullscreen'></span>" onClick="setMainChartMax('toggle');">
505                                                                                         <span class="glyphicon glyphicon-fullscreen"></span>
506                                                                                 </button>
507                                                                         </div>
508 <!--                                                                    <div class="btn-group btn-group-xs" data-toggle="buttons" >
509                                                                                 <label class="btn btn-primary" data-toggle="tooltip" title="NORMAL chart size">
510                                                                                         <input type="radio" name="chartmax" id="chartnormal" onChange="setMainChartMax('normal');">
511                                                                                         <span class="glyphicon glyphicon-resize-small"></span>
512                                                                                 </label>
513                                                                                 <label class="btn btn-primary" data-toggle="tooltip" title="MAXIMIZED chart size">
514                                                                                         <input type="radio" name="chartmax" id="chartmax" onChange="setMainChartMax('maximized');">
515                                                                                         <span class="glyphicon glyphicon-fullscreen"></span>
516                                                                                 </label>
517                                                                         </div>
518 -->                                                             </form>
519                                                         </div>
520                                                         </td></tr>
521                                         </table>
522                            </div><!-- /.maingraph -->
523                         </td></tr>
524                 </table>
525         </div>
526
527     <div class="container graphs" id="thumbgraphs_container">
528         <div class="allgraphs" id="thumbgraphs">
529                 <table width="100%">
530                         <tr><td id="splash" align="center" style="vertical-align:middle">
531                                 <h1>
532                                 Welcome to <b>NetData</b>!
533                                 <br/><br/>
534                                 <span class="glyphicon glyphicon-off"></span>
535                                 <br/><br/>
536                                 loading charts
537                                 <br/><br/>
538                                 <span class="label label-default">Please wait...</span>
539                                 </h1>
540                         </td></tr>
541                 </table>
542         </div>
543         </div>
544
545         <script type='text/javascript'>
546                 
547
548                 $(document).ready(function(){
549                         document.getElementById('splash').height = $(window).height();
550
551                         $('[data-toggle="tooltip"]').tooltip({'placement': 'top', 'container': 'body', 'html': true});
552                 });
553
554         </script>
555 </html>