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, ¤tios, &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
<!--