@cryptotaxi247 / netdata-1 / commits / b49764590

added support for Disk I/O monitoring, added mutex locking to sync threads

Costa Tsaousis (ktsaou) committed Mar 23, 2014 at 18:03 UTC b497645902e0a1eb58b6f522ece0800a1c255e5a
4 files changed +264 -105
example.html
+42 -23
@@ -4,52 +4,71 @@
4 * {font-family:Arial}
5 div {float: left; margin: 0 0 0 0; }
6 </style>
7 -<title>netdata</title>
7 +<title>box.home.tsaousis.gr netdata</title>
8 <head>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
11 <!--Load the AJAX API-->
12 <script type="text/javascript" src="https://www.google.com/jsapi"></script>
13 - <script type="text/javascript" src="jquery-1.10.1.min.js"></script>
13 + <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
14 <script type="text/javascript" src="netdata.js"></script>
15 <script type="text/javascript">
16
17 // Set a callback to run when the Google Visualization API is loaded.
18 google.setOnLoadCallback(drawCharts);
19 -
19 +
20 function drawCharts() {
21 - var width = (window.innerWidth - 50) / 2;
22 - var height = 260;
23 -
24 - if(width < height) width = height; //>
21 + var width = 3; // if zero, auto-adjusts to 50% of screen, 1-10 goes 1/width of screen
22 + var height = 4;
23
24 // EDIT: add one line per interface you have
25 // EDIT:
28 - // EDIT: name div id json data graph title
29 - // EDIT: --------------------------------------------------------------------------------
30 - drawChart('eth0', 'eth0_div', width, height, "eth0.json", "Live Network Usage for eth0");
31 - drawChart('tun0', 'tun0_div', width, height, "tun0.json", "Live Network Usage for tun0");
32 - drawChart('ppp0', 'ppp0_div', width, height, "ppp0.json", "Live Network Usage for ppp0");
26 + // EDIT: name div id json data graph vertical axis title
27 + // EDIT: --------------------------------------------------------------------------------------------------
28 + drawChart('disk.sde', 'disk_sde_div', width, height, "data/disk.sde/120/2/average/", "Live Disk I/O for USB HD (disk.sde)", "I/O in kilobytes/s");
29 + drawChart('disk.md125', 'disk_md125_div', width, height, "data/disk.md125/120/2/average/", "Live Disk I/O for rootfs (disk.md125)", "I/O in kilobytes/s");
30 + drawChart('disk.md126', 'disk_md126_div', width, height, "data/disk.md126/120/2/average/", "Live Disk I/O for swap (disk.md126)", "I/O in kilobytes/s");
31 + drawChart('disk.md127', 'disk_md127_div', width, height, "data/disk.md127/120/2/average/", "Live Disk I/O for /data (disk.md127)", "I/O in kilobytes/s");
32 + drawChart('net.dsl0', 'net_dsl0_div', width, height, "data/net.dsl0/120/2/average/", "Live Network Usage for ADSL (net.dsl0)", "bandwidth in kilobits/s");
33 + drawChart('net.eth3', 'net_eth3_div', width, height, "data/net.eth3/120/2/average/", "Live Network Usage for AWMN (net.eth3)", "bandwidth in kilobits/s");
34 + drawChart('net.eth0', 'net_eth0_div', width, height, "data/net.eth0/120/2/average/", "Live Network Usage for LAN (net.eth0)", "bandwidth in kilobits/s");
35 + drawChart('net.exohiko', 'net_exohiko_div', width, height, "data/net.exohiko/120/2/average/", "Live Network Usage for Exohiko (net.exohiko)", "bandwidth in kilobits/s");
36 + drawChart('net.tun2', 'net_tun2_div', width, height, "data/net.tun2/120/2/average/", "Live Network Usage for Gregory (net.tun2)", "bandwidth in kilobits/s");
37 + drawChart('net.tun0', 'net_tun0_div', width, height, "data/net.tun0/120/2/average/", "Live Network Usage for Realize (net.tun0)", "bandwidth in kilobits/s");
38 }
39
35 - function myRefresh() {
36 - // refresh up to 4 charts every time
37 - refreshCharts(4);
38 - }
40 + var refreshCount = 0;
41 + function myChartsRefresh() {
42 + refreshCount++;
43 + if(refreshCount > 500) location.reload();
44 +
45 + // refresh up to 1 charts per second
46 + refreshCharts(1);
47 + }
48
40 - // EDIT: how often the charts are updated, in milliseconds
41 - setInterval(myRefresh, 1000);
49 + setInterval(myChartsRefresh, 400);
50 +
51 + window.onresize = function(event) {
52 + refreshCharts(999999);
53 + };
54 </script>
43 -</head>
55 +
56 + </head>
57
58 <body>
59 <!--
60 EDIT: add one div per interface you have
61 EDIT: use the same id above and bellow!
62 -->
50 -
51 - <div id="eth0_div"></div>
52 - <div id="tun0_div"></div>
53 - <div id="ppp0_div"></div>
63 + <div id="net_dsl0_div"></div>
64 + <div id="net_eth3_div"></div>
65 + <div id="net_eth0_div"></div>
66 + <div id="net_exohiko_div"></div>
67 + <div id="net_tun0_div"></div>
68 + <div id="net_tun2_div"></div>
69 + <div id="disk_md125_div"></div>
70 + <div id="disk_md126_div"></div>
71 + <div id="disk_md127_div"></div>
72 + <div id="disk_sde_div"></div>
73 </body>
74 </html>
netdata.c
+165 -38
@@ -76,6 +76,10 @@
76 #define MAX_PROC_NET_DEV_LINE 4096
77 #define MAX_PROC_NET_DEV_IFACE_NAME 1024
78
79 +#define MAX_PROC_DISKSTATS_LINE 4096
80 +#define MAX_PROC_DISKSTATS_DISK_NAME 1024
81 +
82 +
83 int silent = 0;
84 int save_history = HISTORY;
85 int update_every = UPDATE_EVERY;
@@ -293,6 +297,8 @@ struct rrd_dimension {
297 typedef struct rrd_dimension RRD_DIMENSION;
298
299 struct rrd_stats {
300 + pthread_mutex_t mutex;
301 +
302 char name[RRD_STATS_NAME_MAX + 1];
303
304 size_t entries;
@@ -305,6 +311,7 @@ struct rrd_stats {
311 typedef struct rrd_stats RRD_STATS;
312
313 RRD_STATS *root = NULL;
314 +pthread_mutex_t root_mutex = PTHREAD_MUTEX_INITIALIZER;
315
316 RRD_STATS *rrd_stats_create(const char *name, unsigned long entries)
317 {
@@ -327,11 +334,18 @@ RRD_STATS *rrd_stats_create(const char *name, unsigned long entries)
334
335 st->entries = entries;
336 st->last_entry = 0;
330 -
337 st->dimensions = NULL;
338 +
339 + pthread_mutex_init(&st->mutex, NULL);
340 + pthread_mutex_lock(&st->mutex);
341 + pthread_mutex_lock(&root_mutex);
342 +
343 st->next = root;
344 root = st;
345
346 + pthread_mutex_unlock(&root_mutex);
347 + // leave st->mutex locked
348 +
349 return(st);
350 }
351
@@ -366,12 +380,15 @@ RRD_DIMENSION *rrd_stats_dimension_add(RRD_STATS *st, const char *name, size_t b
380
381 RRD_STATS *rrd_stats_find(const char *name)
382 {
383 + pthread_mutex_lock(&root_mutex);
384 +
385 RRD_STATS *st = root;
386
387 for ( ; st ; st = st->next ) {
388 if(strcmp(st->name, name) == 0) break;
389 }
390
391 + pthread_mutex_unlock(&root_mutex);
392 return(st);
393 }
394
@@ -390,12 +407,21 @@ void rrd_stats_next(RRD_STATS *st)
407 {
408 struct timeval *now;
409
410 + pthread_mutex_lock(&st->mutex);
411 +
412 // st->last_entry should never be outside the array
413 // or, the parallel threads may end up crashing
414 st->last_entry = ((st->last_entry + 1) >= st->entries) ? 0 : st->last_entry + 1;
415
416 now = &st->times[st->last_entry];
417 gettimeofday(now, NULL);
418 +
419 + // leave mutex locked
420 +}
421 +
422 +void rrd_stats_done(RRD_STATS *st)
423 +{
424 + pthread_mutex_unlock(&st->mutex);
425 }
426
427 void rrd_stats_dimension_set(RRD_STATS *st, const char *dimension, void *data)
@@ -434,6 +460,8 @@ void rrd_stats_dimension_set(RRD_STATS *st, const char *dimension, void *data)
460
461 size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_show, size_t group_count, int group_method)
462 {
463 + pthread_mutex_lock(&st->mutex);
464 +
465 // check the options
466 if(entries_to_show <= 0) entries_to_show = 1;
467 if(group_count <= 0) group_count = 1;
@@ -459,8 +487,10 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
487 for( rd = st->dimensions ; rd ; rd = rd->next)
488 dimensions++;
489
462 - if(!dimensions)
490 + if(!dimensions) {
491 + pthread_mutex_unlock(&st->mutex);
492 return sprintf(b, "No dimensions yet.");
493 + }
494
495 // temporary storage to keep track of group values and counts
496 long long group_values[dimensions];
@@ -518,7 +548,8 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
548 struct tm *tm = localtime(&st->times[t].tv_sec);
549 if(!tm) { error("localtime() failed."); continue; }
550
521 - strftime(dtm, 200, "[%H, %M, %S, 0]", tm);
551 + // strftime(dtm, 200, "[%Y, %m, %d, %H, %M, %S, 0]", tm); // datetime
552 + strftime(dtm, 200, "[%H, %M, %S, 0]", tm); // timeofday
553 i += sprintf(&b[i], "%s {\"c\":[{\"v\":%s},", printed?"]},\n":"", dtm);
554
555 printed++;
@@ -567,6 +598,7 @@ size_t rrd_stats_json(RRD_STATS *st, char *b, size_t length, size_t entries_to_s
598 if(printed) i += sprintf(&b[i], "]}");
599 i += sprintf(&b[i], "\n ]\n}\n");
600
601 + pthread_mutex_unlock(&st->mutex);
602 return(i);
603 }
604
@@ -1307,35 +1339,9 @@ void *socket_listen_main(void *ptr)
1339 // ----------------------------------------------------------------------------
1340 // /proc/net/dev processor
1341
1310 -void update_iface_history(char *name, unsigned long long rbytes, unsigned long long tbytes) {
1311 -
1312 - RRD_STATS *st = rrd_stats_find(name);
1313 - if(!st) {
1314 - st = rrd_stats_create(name, save_history);
1315 - if(!st) {
1316 - error("Cannot create RRD_STATS for interface %s.", name);
1317 - return;
1318 - }
1319 -
1320 - if(!rrd_stats_dimension_add(st, "received", sizeof(unsigned long long), 8, 1024)) {
1321 - error("Cannot add RRD_STATS dimension %s.", "received");
1322 - return;
1323 - }
1324 -
1325 - if(!rrd_stats_dimension_add(st, "sent", sizeof(unsigned long long), 8, 1024)) {
1326 - error("Cannot add RRD_STATS dimension %s.", "sent");
1327 - return;
1328 - }
1329 - }
1330 -
1331 - rrd_stats_next(st);
1332 - rrd_stats_dimension_set(st, "received", &rbytes);
1333 - rrd_stats_dimension_set(st, "sent", &tbytes);
1334 -}
1335 -
1342 int do_proc_net_dev() {
1343 char buffer[MAX_PROC_NET_DEV_LINE+1] = "";
1338 - char iface[MAX_PROC_NET_DEV_IFACE_NAME + 1] = "net.";
1344 + char name[MAX_PROC_NET_DEV_IFACE_NAME + 1] = "net.";
1345 unsigned long long rbytes, rpackets, rerrors, rdrops, rfifo, rframe, rcompressed, rmulticast;
1346 unsigned long long tbytes, tpackets, terrors, tdrops, tfifo, tcollisions, tcarrier, tcompressed;
1347
@@ -1363,19 +1369,139 @@ int do_proc_net_dev() {
1369
1370 // if(DEBUG) printf("%s\n", buffer);
1371 r = sscanf(buffer, "%s\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\n",
1366 - &iface[4],
1372 + &name[4],
1373 &rbytes, &rpackets, &rerrors, &rdrops, &rfifo, &rframe, &rcompressed, &rmulticast,
1374 &tbytes, &tpackets, &terrors, &tdrops, &tfifo, &tcollisions, &tcarrier, &tcompressed);
1375 if(r == EOF) break;
1376 if(r != 17) error("Cannot read /proc/net/dev line. Expected 17 params, read %d.", r);
1371 - else update_iface_history(iface, rbytes, tbytes);
1377 + else {
1378 + RRD_STATS *st = rrd_stats_find(name);
1379 +
1380 + if(!st) {
1381 + st = rrd_stats_create(name, save_history);
1382 + if(!st) {
1383 + error("Cannot create RRD_STATS for interface %s.", name);
1384 + continue;
1385 + }
1386 +
1387 + if(!rrd_stats_dimension_add(st, "sent", sizeof(unsigned long long), 8, 1024))
1388 + error("Cannot add RRD_STATS dimension %s.", "sent");
1389 +
1390 + if(!rrd_stats_dimension_add(st, "received", sizeof(unsigned long long), 8, 1024))
1391 + error("Cannot add RRD_STATS dimension %s.", "received");
1392 +
1393 + }
1394 + else rrd_stats_next(st);
1395 +
1396 + rrd_stats_dimension_set(st, "received", &rbytes);
1397 + rrd_stats_dimension_set(st, "sent", &tbytes);
1398 + rrd_stats_done(st);
1399 + }
1400 + }
1401 +
1402 + fclose(fp);
1403 + return 0;
1404 +}
1405 +
1406 +int do_proc_diskstats() {
1407 + char buffer[MAX_PROC_DISKSTATS_LINE+1] = "";
1408 + char name[MAX_PROC_DISKSTATS_DISK_NAME + 1] = "disk.";
1409 + // 1 2 3 4 5 6 7 8 9 10 11
1410 + unsigned long long major, minor, reads, reads_merged, readsectors, readms, writes, writes_merged, writesectors, writems, currentios, iosms, wiosms;
1411 +
1412 + int r;
1413 + char *p;
1414 +
1415 + FILE *fp = fopen("/proc/diskstats", "r");
1416 + if(!fp) {
1417 + error("Cannot read /proc/diskstats.");
1418 + return 1;
1419 + }
1420 +
1421 + for(;1;) {
1422 + p = fgets(buffer, MAX_PROC_DISKSTATS_LINE, fp);
1423 + if(!p) break;
1424 +
1425 + // if(DEBUG) printf("%s\n", buffer);
1426 + r = sscanf(buffer, "%llu %llu %s %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
1427 + &major, &minor, &name[5],
1428 + &reads, &reads_merged, &readsectors, &readms, &writes, &writes_merged, &writesectors, &writems, &currentios, &iosms, &wiosms
1429 + );
1430 + if(r == EOF) break;
1431 + if(r != 14) error("Cannot read /proc/diskstats line. Expected 14 params, read %d.", r);
1432 + else {
1433 + switch(major) {
1434 + case 1: // ram drives
1435 + continue;
1436 +
1437 + case 7: // loops
1438 + continue;
1439 +
1440 + case 8: // disks
1441 + if(minor % 16) continue; // partitions
1442 + break;
1443 +
1444 + case 9: // MDs
1445 + break;
1446 +
1447 + case 11: // CDs
1448 + continue;
1449 +
1450 + default:
1451 + continue;
1452 + }
1453 +
1454 + RRD_STATS *st = rrd_stats_find(name);
1455 +
1456 + if(!st) {
1457 + char ssfilename[FILENAME_MAX + 1];
1458 + int sector_size = 512;
1459 +
1460 + sprintf(ssfilename, "/sys/block/%s/queue/hw_sector_size", &name[5]);
1461 + FILE *fpss = fopen(ssfilename, "r");
1462 + if(fpss) {
1463 + char ssbuffer[1025];
1464 + char *tmp = fgets(ssbuffer, 1024, fpss);
1465 +
1466 + if(tmp) {
1467 + sector_size = atoi(tmp);
1468 + if(sector_size <= 0) {
1469 + error("Invalid sector size %d for device %s in %s. Assuming 512.", sector_size, name, ssfilename);
1470 + sector_size = 512;
1471 + }
1472 + }
1473 + else error("Cannot read data for sector size for device %s from %s. Assuming 512.", name, ssfilename);
1474 +
1475 + fclose(fpss);
1476 + }
1477 + else error("Cannot read sector size for device %s from %s. Assuming 512.", name, ssfilename);
1478 +
1479 + st = rrd_stats_create(name, save_history);
1480 + if(!st) {
1481 + error("Cannot create RRD_STATS for disk %s.", name);
1482 + continue;
1483 + }
1484 +
1485 + if(!rrd_stats_dimension_add(st, "reads", sizeof(unsigned long long), sector_size, 1024))
1486 + error("Cannot add RRD_STATS dimension %s.", "reads");
1487 +
1488 + if(!rrd_stats_dimension_add(st, "writes", sizeof(unsigned long long), sector_size, 1024))
1489 + error("Cannot add RRD_STATS dimension %s.", "writes");
1490 +
1491 + }
1492 + else rrd_stats_next(st);
1493 +
1494 + rrd_stats_dimension_set(st, "reads", &readsectors);
1495 + rrd_stats_dimension_set(st, "writes", &writesectors);
1496 + rrd_stats_done(st);
1497 + }
1498 }
1499
1500 fclose(fp);
1501 return 0;
1502 }
1503
1378 -void *proc_net_dev_main(void *ptr)
1504 +void *proc_main(void *ptr)
1505 {
1506 struct timeval last, now, tmp;
1507
@@ -1391,6 +1517,7 @@ void *proc_net_dev_main(void *ptr)
1517 debug(D_PROCNETDEV_LOOP, "PROCNETDEV: Last loop took %llu usec.", usec);
1518
1519 do_proc_net_dev(usec);
1520 + do_proc_diskstats(usec);
1521
1522 // find the time to sleep in order to wait exactly update_every seconds
1523 gettimeofday(&tmp, NULL);
@@ -1481,20 +1608,20 @@ int main(int argc, char **argv)
1608 silent = 1;
1609 }
1610
1484 - pthread_t p_proc_net_dev;
1485 - int r_proc_net_dev;
1611 + pthread_t p_proc;
1612 + int r_proc;
1613
1614 // spawn a child to collect data
1488 - r_proc_net_dev = pthread_create(&p_proc_net_dev, NULL, proc_net_dev_main, NULL);
1615 + r_proc = pthread_create(&p_proc, NULL, proc_main, NULL);
1616
1617 // the main process - the web server listener
1618 //sleep(1);
1619 socket_listen_main(NULL);
1620
1621 // wait for the childs to finish
1495 - pthread_join(p_proc_net_dev, NULL);
1622 + pthread_join(p_proc, NULL);
1623
1497 - printf("PROC NET DEV thread returns: %d\n", r_proc_net_dev);
1624 + printf("PROC NET DEV thread returns: %d\n", r_proc);
1625
1626 exit(0);
1627 }
netdata.js
+24 -31
@@ -8,7 +8,7 @@
8 if(index >= charts.length) return;
9
10 var jsonData = $.ajax({
11 - url: charts_urls[index],
11 + url: charts[index].url,
12 dataType:"json",
13 async: false,
14 cache: false
@@ -17,21 +17,20 @@
17 if(!jsonData || jsonData.length == 0) return;
18
19 // Create our data table out of JSON data loaded from server.
20 - charts_data[index] = null;
21 - charts_data[index] = new google.visualization.DataTable(jsonData);
20 + charts[index].data = new google.visualization.DataTable(jsonData);
21
22 // Instantiate and draw our chart, passing in some options.
24 - if(!charts[index]) {
25 - console.log('Creating new chart for ' + charts_urls[index]);
26 - charts[index] = new google.visualization.AreaChart(document.getElementById(charts_divs[index]));
23 + if(!charts[index].chart) {
24 + console.log('Creating new chart for ' + charts[index].url);
25 + charts[index].chart = new google.visualization.AreaChart(document.getElementById(charts[index].div));
26 }
27
29 - var width = charts_widths[index];
28 + var width = charts[index].width;
29 if(width == 0) width = (window.innerWidth - 40) / 2;
30 if(width <= 10) width = (window.innerWidth - 40) / width;
31 if(width < 200) width = 200;
32
34 - var height = charts_heights[index];
33 + var height = charts[index].height;
34 if(height == 0) height = (window.innerHeight - 20) / 2;
35 if(height <= 10) height = (window.innerHeight - 20) / height;
36 if(height < 100) height = 100;
@@ -39,37 +38,31 @@
38 var hAxisTitle = null;
39 var vAxisTitle = null;
40 if(height >= 200) hAxisTitle = "Time of Day";
42 - if(width >= 400) vAxisTitle = "Bandwidth in kbps";
41 + if(width >= 400) vAxisTitle = charts[index].vtitle;
42
44 - if(charts[index]) charts[index].draw(charts_data[index], {width: width, height: height, title: charts_titles[index], hAxis: {title: hAxisTitle}, vAxis: {title: vAxisTitle, minValue: 10}});
45 - else console.log('Cannot create chart for ' + charts_urls[index]);
43 + if(charts[index].chart) charts[index].chart.draw(charts[index].data, {width: width, height: height, title: charts[index].title, hAxis: {title: hAxisTitle}, vAxis: {title: vAxisTitle, minValue: 10}});
44 + else console.log('Cannot create chart for ' + charts[index].url);
45 }
46
47 var charts = new Array();
49 - var charts_data = new Array();
50 - var charts_names = new Array();
51 - var charts_divs = new Array();
52 - var charts_widths = new Array();
53 - var charts_heights = new Array();
54 - var charts_urls = new Array();
55 - var charts_titles = new Array();
56 -
57 - function drawChart(name, div, width, height, jsonurl, title) {
48 + function drawChart(name, div, width, height, jsonurl, title, vtitle) {
49 var i;
50
60 - for(i = 0; i < charts_names.length; i++) //>
61 - if(charts_names[i] == name) break;
51 + for(i = 0; i < charts.length; i++) //>
52 + if(charts[i].name == name) break;
53
63 - if(i >= charts_names.length) { //>
54 + if(i >= charts.length) { //>
55 console.log('Creating new objects for chart ' + name);
65 - charts[i] = null;
66 - charts_data[i] = null;
67 - charts_names[i] = name;
68 - charts_divs[i] = div;
69 - charts_widths[i] = width;
70 - charts_heights[i] = height;
71 - charts_urls[i] = jsonurl;
72 - charts_titles[i] = title;
56 + charts[i] = [];
57 + charts[i].chart = null;
58 + charts[i].data = null;
59 + charts[i].name = name;
60 + charts[i].div = div;
61 + charts[i].width = width;
62 + charts[i].height = height;
63 + charts[i].url = jsonurl;
64 + charts[i].title = title;
65 + charts[i].vtitle = vtitle;
66 }
67
68 try {
netdata.start
+33 -13
@@ -167,21 +167,37 @@ cat >${data}/index.html <<EOF
167
168 // EDIT: add one line per interface you have
169 // EDIT:
170 - // EDIT: name div id json data graph title
171 - // EDIT: --------------------------------------------------------------------------------
170 + // EDIT: name div id json data graph vertical axis title
171 + // EDIT: --------------------------------------------------------------------------------------------------
172 EOF
173
174 for x in $all
175 do
176 y=`echo "$x" | tr ".-" "__"`
177 - eval "NETDATA_TITLE_${y}=\${NETDATA_TITLE_${y}:-Live Network Usage for ${x}}"
177 +
178 + title=
179 + vtitle=
180 + case "$x" in
181 + net.*)
182 + title="Live Network Usage for "
183 + vtitle="bandwidth in kilobits/s"
184 + ;;
185 +
186 + disk.*)
187 + title="Live Disk I/O for "
188 + vtitle="I/O in kilobytes/s"
189 + ;;
190 +
191 + esac
192 +
193 + eval "NETDATA_TITLE_${y}=\${NETDATA_TITLE_${y}:-${x}}"
194 eval "t=\${NETDATA_TITLE_${y}}"
195
196 eval "p=\${NETDATA_PRIORITY_${y}}"
197 if [ ! "$p" = "IGNORE" ]
198 then
199 cat >>${data}/index.html <<EOF2
184 - drawChart('${x}', '${y}_div', width, height, "data/${x}/${NETDATA_CONFIG_HISTORY_POINTS}/${NETDATA_CONFIG_UPDATE_EVERY}/average/", "${t}");
200 + drawChart('${x}', '${y}_div', width, height, "data/${x}/${NETDATA_CONFIG_HISTORY_POINTS}/${NETDATA_CONFIG_UPDATE_EVERY}/average/", "${title}${t} (${x})", "${vtitle}");
201 EOF2
202 fi
203 done
@@ -192,9 +208,9 @@ if [ $count -gt 4 ]
208 then
209 ref=1
210 tim=$[1000 * NETDATA_CONFIG_UPDATE_EVERY / count]
195 - if [ $tim -lt $[333 * NETDATA_CONFIG_UPDATE_EVERY] ]
211 + if [ $tim -lt $[200 * NETDATA_CONFIG_UPDATE_EVERY] ]
212 then
197 - tim=$[333 * NETDATA_CONFIG_UPDATE_EVERY]
213 + tim=$[200 * NETDATA_CONFIG_UPDATE_EVERY]
214 fi
215 fi
216
@@ -202,18 +218,22 @@ cat >>${data}/index.html <<EOF3
218 }
219
220 var refreshCount = 0;
205 - function myChartsRefresh() {
221 + function myChartsRefresh() {
222 refreshCount++;
223 if(refreshCount > $NETDATA_CONFIG_RELOAD_EVERY) location.reload();
208 -
224 +
225 // refresh up to $ref charts per second
210 - refreshCharts($ref);
211 - }
226 + refreshCharts($ref);
227 + }
228
213 - // EDIT: how often the charts are updated, in milliseconds
214 - setInterval(myChartsRefresh, $tim);
229 + setInterval(myChartsRefresh, $tim);
230 +
231 + window.onresize = function(event) {
232 + refreshCharts(999999);
233 + };
234 </script>
216 -</head>
235 +
236 + </head>
237
238 <body>
239 <!--