@cryptotaxi247 / netdata-1 / commits / 8c724f935

added /proc/vmstat support; added a lot of detailed charts for interfaces, disks and ipv4

Costa Tsaousis (ktsaou) committed Apr 12, 2014 at 23:21 UTC 8c724f9353870fe07dc49436c2056803f3d395a4
3 files changed +700 -227
netdata.c
+650 -198
@@ -31,6 +31,7 @@
31
32 #include <pthread.h>
33 #include <zlib.h>
34 +#include <malloc.h>
35
36 #define RRD_DIMENSION_ABSOLUTE 0
37 #define RRD_DIMENSION_INCREMENTAL 1
@@ -388,6 +389,9 @@ struct rrd_stats {
389
390 time_t last_updated; // when this data set was last updated
391
392 + int isdetail; // if set, the data set should be considered as a detail of another
393 + // (the master data set should be the one that has the same group and is not detail)
394 +
395 struct timeval *times; // the time in microseconds each data entry was collected
396 RRD_DIMENSION *dimensions; // the actual data for every dimension
397
@@ -533,8 +537,14 @@ RRD_DIMENSION *rrd_stats_dimension_add(RRD_STATS *st, const char *id, const char
537 if(name) strncpy(rd->name, name, RRD_STATS_NAME_MAX);
538 else strncpy(rd->name, id, RRD_STATS_NAME_MAX);
539
536 - rd->next = st->dimensions;
537 - st->dimensions = rd;
540 + // append this dimension
541 + if(!st->dimensions)
542 + st->dimensions = rd;
543 + else {
544 + RRD_DIMENSION *td = st->dimensions;
545 + for(; td->next; td = td->next) ;
546 + td->next = rd;
547 + }
548
549 //rd->annotator = annotator;
550
@@ -932,9 +942,14 @@ void rrd_stats_one_json(RRD_STATS *st, char *options, struct web_buffer *wb)
942 wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"id\" : \"%s\",\n", st->id);
943 wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"name\" : \"%s\",\n", st->name);
944 wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"type\" : \"%s\",\n", st->type);
935 - wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"group_name\" : \"%s\",\n", st->group);
936 - wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"title\" : \"%s %s\",\n", st->title, st->name);
937 - wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"usertitle\" : \"%s %s (%s)\",\n", st->title, st->usertitle, st->id);
945 + wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"group_tag\" : \"%s\",\n", st->group);
946 + wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"title\" : \"%s\",\n", st->title);
947 +
948 + if(strcmp(st->id, st->usertitle) == 0 || strcmp(st->name, st->usertitle) == 0)
949 + wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"usertitle\" : \"%s (%s)\",\n", st->title, st->name);
950 + else
951 + wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"usertitle\" : \"%s %s (%s)\",\n", st->title, st->usertitle, st->name);
952 +
953 wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"userpriority\" : \"%s\",\n", st->userpriority);
954 wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"envtitle\" : \"%s\",\n", st->envtitle);
955 wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"envpriority\" : \"%s\",\n", st->envpriority);
@@ -945,7 +960,8 @@ void rrd_stats_one_json(RRD_STATS *st, char *options, struct web_buffer *wb)
960 wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"current\" : %ld,\n", st->current_entry);
961 wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"update_every\" : %d,\n", update_every);
962 wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"last_updated\" : %lu,\n", st->last_updated);
948 - wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"last_updated_secs_ago\" : %lu\n", time(NULL) - st->last_updated);
963 + wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"last_updated_secs_ago\" : %lu,\n", time(NULL) - st->last_updated);
964 + wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t\t\"isdetail\" : %d\n", st->isdetail);
965 wb->bytes += sprintf(&wb->buffer[wb->bytes], "\t\t}");
966 }
967
@@ -1475,16 +1491,17 @@ void web_client_process(struct web_client *w)
1491 char *buf = w->data->buffer;
1492 char *tok = strsep(&buf, " \r\n");
1493 char *url = NULL;
1494 + char *pointer_to_free = NULL; // keep url_decode() allocated buffer
1495
1496 if(buf && strcmp(tok, "GET") == 0) {
1497 tok = strsep(&buf, " \r\n");
1481 - url = url_decode(tok);
1498 + pointer_to_free = url = url_decode(tok);
1499 debug(D_WEB_CLIENT, "%llu: Processing HTTP GET on url '%s'.", w->id, url);
1500 }
1501 else if (buf && strcmp(tok, "POST") == 0) {
1502 w->keepalive = 0;
1503 tok = strsep(&buf, " \r\n");
1487 - url = url_decode(tok);
1504 + pointer_to_free = url = url_decode(tok);
1505
1506 debug(D_WEB_CLIENT, "%llu: I don't know how to handle POST with form data. Assuming it is a GET on url '%s'.", w->id, url);
1507 }
@@ -1635,6 +1652,7 @@ void web_client_process(struct web_client *w)
1652 w->data->bytes = 0;
1653 code = mysendfile(w, tok);
1654 }
1655 +
1656 }
1657 else {
1658 if(buf) debug(D_WEB_CLIENT_ACCESS, "%llu: Cannot understand '%s'.", w->id, buf);
@@ -1644,6 +1662,9 @@ void web_client_process(struct web_client *w)
1662 strcpy(w->data->buffer, "I don't understand you...\r\n");
1663 w->data->bytes = strlen(w->data->buffer);
1664 }
1665 +
1666 + // free url_decode() buffer
1667 + if(pointer_to_free) free(pointer_to_free);
1668 }
1669 else if(w->data->bytes > 8192) {
1670 debug(D_WEB_CLIENT_ACCESS, "%llu: Received request is too big.", w->id);
@@ -2186,6 +2207,31 @@ void *new_client(void *ptr)
2207 // 3. spawns a new pthread to serve the client (this is optimal for keep-alive clients)
2208 // 4. cleans up old web_clients that their pthreads have been exited
2209
2210 +void syslog_allocations(void)
2211 +{
2212 + static int mem = 0;
2213 +
2214 + struct mallinfo mi;
2215 +
2216 + mi = mallinfo();
2217 + if(mi.uordblks > mem) {
2218 + syslog(LOG_NOTICE, "Allocated memory increased from %d to %d (increased by %d bytes).", mem, mi.uordblks, mi.uordblks - mem );
2219 + mem = mi.uordblks;
2220 + }
2221 + /*
2222 + syslog(LOG_NOTICE, "Total non-mmapped bytes (arena): %d\n", mi.arena);
2223 + syslog(LOG_NOTICE, "# of free chunks (ordblks): %d\n", mi.ordblks);
2224 + syslog(LOG_NOTICE, "# of free fastbin blocks (smblks): %d\n", mi.smblks);
2225 + syslog(LOG_NOTICE, "# of mapped regions (hblks): %d\n", mi.hblks);
2226 + syslog(LOG_NOTICE, "Bytes in mapped regions (hblkhd): %d\n", mi.hblkhd);
2227 + syslog(LOG_NOTICE, "Max. total allocated space (usmblks): %d\n", mi.usmblks);
2228 + syslog(LOG_NOTICE, "Free bytes held in fastbins (fsmblks): %d\n", mi.fsmblks);
2229 + syslog(LOG_NOTICE, "Total allocated space (uordblks): %d\n", mi.uordblks);
2230 + syslog(LOG_NOTICE, "Total free space (fordblks): %d\n", mi.fordblks);
2231 + syslog(LOG_NOTICE, "Topmost releasable block (keepcost): %d\n", mi.keepcost);
2232 + */
2233 +}
2234 +
2235 void *socket_listen_main(void *ptr)
2236 {
2237 struct web_client *w;
@@ -2236,6 +2282,7 @@ void *socket_listen_main(void *ptr)
2282 if(w->obsolete) {
2283 debug(D_WEB_CLIENT, "%llu: Removing client.", w->id);
2284 w = web_client_free(w);
2285 + syslog_allocations();
2286 }
2287 }
2288 }
@@ -2283,27 +2330,94 @@ int do_proc_net_dev() {
2330 if(c) *c = '\t';
2331
2332 // if(DEBUG) printf("%s\n", buffer);
2286 - 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",
2333 + r = sscanf(buffer, "%s %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
2334 iface,
2335 &rbytes, &rpackets, &rerrors, &rdrops, &rfifo, &rframe, &rcompressed, &rmulticast,
2336 &tbytes, &tpackets, &terrors, &tdrops, &tfifo, &tcollisions, &tcarrier, &tcompressed);
2337 if(r == EOF) break;
2291 - if(r != 17) error("Cannot read /proc/net/dev line. Expected 17 params, read %d.", r);
2292 - else {
2293 - RRD_STATS *st = rrd_stats_find_bytype(RRD_TYPE_NET, iface);
2338 + if(r != 17) {
2339 + error("Cannot read /proc/net/dev line. Expected 17 params, read %d.", r);
2340 + continue;
2341 + }
2342
2295 - if(!st) {
2296 - st = rrd_stats_create(RRD_TYPE_NET, iface, NULL, iface, "Bandwidth", "kilobits/s", save_history);
2343 + // --------------------------------------------------------------------
2344
2298 - rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2299 - rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2300 - }
2301 - else rrd_stats_next(st);
2345 + RRD_STATS *st = rrd_stats_find_bytype(RRD_TYPE_NET, iface);
2346 + if(!st) {
2347 + st = rrd_stats_create(RRD_TYPE_NET, iface, NULL, iface, "Bandwidth", "kilobits/s", save_history);
2348
2303 - rrd_stats_dimension_set(st, "received", &rbytes, NULL);
2304 - rrd_stats_dimension_set(st, "sent", &tbytes, NULL);
2305 - rrd_stats_done(st);
2349 + rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2350 + rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2351 + }
2352 + else rrd_stats_next(st);
2353 +
2354 + rrd_stats_dimension_set(st, "received", &rbytes, NULL);
2355 + rrd_stats_dimension_set(st, "sent", &tbytes, NULL);
2356 + rrd_stats_done(st);
2357 +
2358 + // --------------------------------------------------------------------
2359 +
2360 + st = rrd_stats_find_bytype(iface, "packets");
2361 + if(!st) {
2362 + st = rrd_stats_create(iface, "packets", NULL, iface, "Packets", "packets/s", save_history);
2363 + st->isdetail = 1;
2364 +
2365 + rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2366 + rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2367 }
2368 + else rrd_stats_next(st);
2369 +
2370 + rrd_stats_dimension_set(st, "received", &rpackets, NULL);
2371 + rrd_stats_dimension_set(st, "sent", &tpackets, NULL);
2372 + rrd_stats_done(st);
2373 +
2374 + // --------------------------------------------------------------------
2375 +
2376 + st = rrd_stats_find_bytype(iface, "errors");
2377 + if(!st) {
2378 + st = rrd_stats_create(iface, "errors", NULL, iface, "Interface Errors", "errors/s", save_history);
2379 + st->isdetail = 1;
2380 +
2381 + rrd_stats_dimension_add(st, "receive", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2382 + rrd_stats_dimension_add(st, "transmit", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2383 + }
2384 + else rrd_stats_next(st);
2385 +
2386 + rrd_stats_dimension_set(st, "receive", &rerrors, NULL);
2387 + rrd_stats_dimension_set(st, "transmit", &terrors, NULL);
2388 + rrd_stats_done(st);
2389 +
2390 + // --------------------------------------------------------------------
2391 +
2392 + st = rrd_stats_find_bytype(iface, "fifo");
2393 + if(!st) {
2394 + st = rrd_stats_create(iface, "fifo", NULL, iface, "Interface Queue", "packets", save_history);
2395 + st->isdetail = 1;
2396 +
2397 + rrd_stats_dimension_add(st, "receive", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_ABSOLUTE, NULL);
2398 + rrd_stats_dimension_add(st, "transmit", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_ABSOLUTE, NULL);
2399 + }
2400 + else rrd_stats_next(st);
2401 +
2402 + rrd_stats_dimension_set(st, "receive", &rfifo, NULL);
2403 + rrd_stats_dimension_set(st, "transmit", &tfifo, NULL);
2404 + rrd_stats_done(st);
2405 +
2406 + // --------------------------------------------------------------------
2407 +
2408 + st = rrd_stats_find_bytype(iface, "compressed");
2409 + if(!st) {
2410 + st = rrd_stats_create(iface, "compressed", NULL, iface, "Compressed Packets", "packets/s", save_history);
2411 + st->isdetail = 1;
2412 +
2413 + rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2414 + rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2415 + }
2416 + else rrd_stats_next(st);
2417 +
2418 + rrd_stats_dimension_set(st, "received", &rcompressed, NULL);
2419 + rrd_stats_dimension_set(st, "sent", &tcompressed, NULL);
2420 + rrd_stats_done(st);
2421 }
2422
2423 fclose(fp);
@@ -2319,8 +2433,6 @@ int do_proc_net_dev() {
2433 int do_proc_diskstats() {
2434 char buffer[MAX_PROC_DISKSTATS_LINE+1] = "";
2435 char disk[MAX_PROC_DISKSTATS_DISK_NAME + 1] = "";
2322 - // 1 2 3 4 5 6 7 8 9 10 11
2323 - unsigned long long major, minor, reads, reads_merged, readsectors, readms, writes, writes_merged, writesectors, writems, currentios, iosms, wiosms;
2436
2437 int r;
2438 char *p;
@@ -2332,6 +2444,11 @@ int do_proc_diskstats() {
2444 }
2445
2446 for(;1;) {
2447 + unsigned long long major = 0, minor = 0,
2448 + reads = 0, reads_merged = 0, readsectors = 0, readms = 0,
2449 + writes = 0, writes_merged = 0, writesectors = 0, writems = 0,
2450 + currentios = 0, iosms = 0, wiosms = 0;
2451 +
2452 p = fgets(buffer, MAX_PROC_DISKSTATS_LINE, fp);
2453 if(!p) break;
2454
@@ -2341,150 +2458,220 @@ int do_proc_diskstats() {
2458 &reads, &reads_merged, &readsectors, &readms, &writes, &writes_merged, &writesectors, &writems, &currentios, &iosms, &wiosms
2459 );
2460 if(r == EOF) break;
2344 - if(r != 14) error("Cannot read /proc/diskstats line. Expected 14 params, read %d.", r);
2345 - else {
2346 - switch(major) {
2347 - case 9: // MDs
2348 - case 43: // network block
2349 - case 144: // nfs
2350 - case 145: // nfs
2351 - case 146: // nfs
2352 - case 199: // veritas
2353 - case 201: // veritas
2354 - case 251: // dm
2355 - break;
2461 + if(r != 14) {
2462 + error("Cannot read /proc/diskstats line. Expected 14 params, read %d.", r);
2463 + continue;
2464 + }
2465
2357 - case 48: // RAID
2358 - case 49: // RAID
2359 - case 50: // RAID
2360 - case 51: // RAID
2361 - case 52: // RAID
2362 - case 53: // RAID
2363 - case 54: // RAID
2364 - case 55: // RAID
2365 - case 112: // RAID
2366 - case 136: // RAID
2367 - case 137: // RAID
2368 - case 138: // RAID
2369 - case 139: // RAID
2370 - case 140: // RAID
2371 - case 141: // RAID
2372 - case 142: // RAID
2373 - case 143: // RAID
2374 - case 179: // MMC
2375 - case 180: // USB
2376 - if(minor % 8) continue; // partitions
2377 - break;
2466 + switch(major) {
2467 + case 9: // MDs
2468 + case 43: // network block
2469 + case 144: // nfs
2470 + case 145: // nfs
2471 + case 146: // nfs
2472 + case 199: // veritas
2473 + case 201: // veritas
2474 + case 251: // dm
2475 + break;
2476
2379 - case 8: // scsi disks
2380 - case 65: // scsi disks
2381 - case 66: // scsi disks
2382 - case 67: // scsi disks
2383 - case 68: // scsi disks
2384 - case 69: // scsi disks
2385 - case 70: // scsi disks
2386 - case 71: // scsi disks
2387 - case 72: // scsi disks
2388 - case 73: // scsi disks
2389 - case 74: // scsi disks
2390 - case 75: // scsi disks
2391 - case 76: // scsi disks
2392 - case 77: // scsi disks
2393 - case 78: // scsi disks
2394 - case 79: // scsi disks
2395 - case 80: // i2o
2396 - case 81: // i2o
2397 - case 82: // i2o
2398 - case 83: // i2o
2399 - case 84: // i2o
2400 - case 85: // i2o
2401 - case 86: // i2o
2402 - case 87: // i2o
2403 - case 101: // hyperdisk
2404 - case 102: // compressed
2405 - case 104: // scsi
2406 - case 105: // scsi
2407 - case 106: // scsi
2408 - case 107: // scsi
2409 - case 108: // scsi
2410 - case 109: // scsi
2411 - case 110: // scsi
2412 - case 111: // scsi
2413 - case 114: // bios raid
2414 - case 116: // ram board
2415 - case 128: // scsi
2416 - case 129: // scsi
2417 - case 130: // scsi
2418 - case 131: // scsi
2419 - case 132: // scsi
2420 - case 133: // scsi
2421 - case 134: // scsi
2422 - case 135: // scsi
2423 - case 153: // raid
2424 - case 202: // xen
2425 - case 256: // flash
2426 - case 257: // flash
2427 - if(minor % 16) continue; // partitions
2428 - break;
2477 + case 48: // RAID
2478 + case 49: // RAID
2479 + case 50: // RAID
2480 + case 51: // RAID
2481 + case 52: // RAID
2482 + case 53: // RAID
2483 + case 54: // RAID
2484 + case 55: // RAID
2485 + case 112: // RAID
2486 + case 136: // RAID
2487 + case 137: // RAID
2488 + case 138: // RAID
2489 + case 139: // RAID
2490 + case 140: // RAID
2491 + case 141: // RAID
2492 + case 142: // RAID
2493 + case 143: // RAID
2494 + case 179: // MMC
2495 + case 180: // USB
2496 + if(minor % 8) continue; // partitions
2497 + break;
2498
2430 - case 160: // raid
2431 - case 161: // raid
2432 - if(minor % 32) continue; // partitions
2433 - break;
2499 + case 8: // scsi disks
2500 + case 65: // scsi disks
2501 + case 66: // scsi disks
2502 + case 67: // scsi disks
2503 + case 68: // scsi disks
2504 + case 69: // scsi disks
2505 + case 70: // scsi disks
2506 + case 71: // scsi disks
2507 + case 72: // scsi disks
2508 + case 73: // scsi disks
2509 + case 74: // scsi disks
2510 + case 75: // scsi disks
2511 + case 76: // scsi disks
2512 + case 77: // scsi disks
2513 + case 78: // scsi disks
2514 + case 79: // scsi disks
2515 + case 80: // i2o
2516 + case 81: // i2o
2517 + case 82: // i2o
2518 + case 83: // i2o
2519 + case 84: // i2o
2520 + case 85: // i2o
2521 + case 86: // i2o
2522 + case 87: // i2o
2523 + case 101: // hyperdisk
2524 + case 102: // compressed
2525 + case 104: // scsi
2526 + case 105: // scsi
2527 + case 106: // scsi
2528 + case 107: // scsi
2529 + case 108: // scsi
2530 + case 109: // scsi
2531 + case 110: // scsi
2532 + case 111: // scsi
2533 + case 114: // bios raid
2534 + case 116: // ram board
2535 + case 128: // scsi
2536 + case 129: // scsi
2537 + case 130: // scsi
2538 + case 131: // scsi
2539 + case 132: // scsi
2540 + case 133: // scsi
2541 + case 134: // scsi
2542 + case 135: // scsi
2543 + case 153: // raid
2544 + case 202: // xen
2545 + case 256: // flash
2546 + case 257: // flash
2547 + if(minor % 16) continue; // partitions
2548 + break;
2549
2435 - case 3: // ide
2436 - case 13: // 8bit ide
2437 - case 22: // ide
2438 - case 33: // ide
2439 - case 34: // ide
2440 - case 56: // ide
2441 - case 57: // ide
2442 - case 88: // ide
2443 - case 89: // ide
2444 - case 90: // ide
2445 - case 91: // ide
2446 - if(minor % 64) continue; // partitions
2447 - break;
2550 + case 160: // raid
2551 + case 161: // raid
2552 + if(minor % 32) continue; // partitions
2553 + break;
2554
2449 - default:
2450 - continue;
2451 - }
2555 + case 3: // ide
2556 + case 13: // 8bit ide
2557 + case 22: // ide
2558 + case 33: // ide
2559 + case 34: // ide
2560 + case 56: // ide
2561 + case 57: // ide
2562 + case 88: // ide
2563 + case 89: // ide
2564 + case 90: // ide
2565 + case 91: // ide
2566 + if(minor % 64) continue; // partitions
2567 + break;
2568
2453 - RRD_STATS *st = rrd_stats_find_bytype(RRD_TYPE_DISK, disk);
2454 - if(!st) {
2455 - char ssfilename[FILENAME_MAX + 1];
2456 - int sector_size = 512;
2457 -
2458 - sprintf(ssfilename, "/sys/block/%s/queue/hw_sector_size", disk);
2459 - FILE *fpss = fopen(ssfilename, "r");
2460 - if(fpss) {
2461 - char ssbuffer[1025];
2462 - char *tmp = fgets(ssbuffer, 1024, fpss);
2463 -
2464 - if(tmp) {
2465 - sector_size = atoi(tmp);
2466 - if(sector_size <= 0) {
2467 - error("Invalid sector size %d for device %s in %s. Assuming 512.", sector_size, disk, ssfilename);
2468 - sector_size = 512;
2469 - }
2470 - }
2471 - else error("Cannot read data for sector size for device %s from %s. Assuming 512.", disk, ssfilename);
2569 + default:
2570 + continue;
2571 + }
2572
2473 - fclose(fpss);
2474 - }
2475 - else error("Cannot read sector size for device %s from %s. Assuming 512.", disk, ssfilename);
2573 + // --------------------------------------------------------------------
2574
2477 - st = rrd_stats_create(RRD_TYPE_DISK, disk, NULL, disk, "Disk I/O", "kilobytes/s", save_history);
2575 + RRD_STATS *st = rrd_stats_find_bytype(RRD_TYPE_DISK, disk);
2576 + if(!st) {
2577 + char ssfilename[FILENAME_MAX + 1];
2578 + int sector_size = 512;
2579 +
2580 + sprintf(ssfilename, "/sys/block/%s/queue/hw_sector_size", disk);
2581 + FILE *fpss = fopen(ssfilename, "r");
2582 + if(fpss) {
2583 + char ssbuffer[1025];
2584 + char *tmp = fgets(ssbuffer, 1024, fpss);
2585 +
2586 + if(tmp) {
2587 + sector_size = atoi(tmp);
2588 + if(sector_size <= 0) {
2589 + error("Invalid sector size %d for device %s in %s. Assuming 512.", sector_size, disk, ssfilename);
2590 + sector_size = 512;
2591 + }
2592 + }
2593 + else error("Cannot read data for sector size for device %s from %s. Assuming 512.", disk, ssfilename);
2594
2479 - rrd_stats_dimension_add(st, "writes", NULL, sizeof(unsigned long long), 0, sector_size * -1, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2480 - rrd_stats_dimension_add(st, "reads", NULL, sizeof(unsigned long long), 0, sector_size, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2595 + fclose(fpss);
2596 }
2482 - else rrd_stats_next(st);
2597 + else error("Cannot read sector size for device %s from %s. Assuming 512.", disk, ssfilename);
2598
2484 - rrd_stats_dimension_set(st, "reads", &readsectors, NULL);
2485 - rrd_stats_dimension_set(st, "writes", &writesectors, NULL);
2486 - rrd_stats_done(st);
2599 + st = rrd_stats_create(RRD_TYPE_DISK, disk, NULL, disk, "Disk I/O", "kilobytes/s", save_history);
2600 +
2601 + rrd_stats_dimension_add(st, "reads", NULL, sizeof(unsigned long long), 0, sector_size, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2602 + rrd_stats_dimension_add(st, "writes", NULL, sizeof(unsigned long long), 0, sector_size * -1, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2603 + }
2604 + else rrd_stats_next(st);
2605 +
2606 + rrd_stats_dimension_set(st, "reads", &readsectors, NULL);
2607 + rrd_stats_dimension_set(st, "writes", &writesectors, NULL);
2608 + rrd_stats_done(st);
2609 +
2610 + // --------------------------------------------------------------------
2611 +
2612 + st = rrd_stats_find_bytype(disk, "ops");
2613 + if(!st) {
2614 + st = rrd_stats_create(disk, "ops", NULL, disk, "Disk Operations", "operations/s", save_history);
2615 + st->isdetail = 1;
2616 +
2617 + rrd_stats_dimension_add(st, "reads", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2618 + rrd_stats_dimension_add(st, "writes", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2619 + }
2620 + else rrd_stats_next(st);
2621 +
2622 + rrd_stats_dimension_set(st, "reads", &reads, NULL);
2623 + rrd_stats_dimension_set(st, "writes", &writes, NULL);
2624 + rrd_stats_done(st);
2625 +
2626 + // --------------------------------------------------------------------
2627 +
2628 + st = rrd_stats_find_bytype(disk, "merged_ops");
2629 + if(!st) {
2630 + st = rrd_stats_create(disk, "merged_ops", NULL, disk, "Merged Disk Operations", "operations/s", save_history);
2631 + st->isdetail = 1;
2632 +
2633 + rrd_stats_dimension_add(st, "reads", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2634 + rrd_stats_dimension_add(st, "writes", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2635 }
2636 + else rrd_stats_next(st);
2637 +
2638 + rrd_stats_dimension_set(st, "reads", &reads_merged, NULL);
2639 + rrd_stats_dimension_set(st, "writes", &writes_merged, NULL);
2640 + rrd_stats_done(st);
2641 +
2642 + // --------------------------------------------------------------------
2643 +
2644 + st = rrd_stats_find_bytype(disk, "iotime");
2645 + if(!st) {
2646 + st = rrd_stats_create(disk, "iotime", NULL, disk, "Disk I/O Time", "milliseconds/s", save_history);
2647 + st->isdetail = 1;
2648 +
2649 + rrd_stats_dimension_add(st, "reads", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2650 + rrd_stats_dimension_add(st, "writes", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2651 + rrd_stats_dimension_add(st, "latency", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2652 + rrd_stats_dimension_add(st, "weighted", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2653 + }
2654 + else rrd_stats_next(st);
2655 +
2656 + rrd_stats_dimension_set(st, "reads", &readms, NULL);
2657 + rrd_stats_dimension_set(st, "writes", &writems, NULL);
2658 + rrd_stats_dimension_set(st, "latency", &iosms, NULL);
2659 + rrd_stats_dimension_set(st, "weighted", &wiosms, NULL);
2660 + rrd_stats_done(st);
2661 +
2662 + // --------------------------------------------------------------------
2663 +
2664 + st = rrd_stats_find_bytype(disk, "current_ops");
2665 + if(!st) {
2666 + st = rrd_stats_create(disk, "current_ops", NULL, disk, "Current Disk I/O operations", "operations", save_history);
2667 + st->isdetail = 1;
2668 +
2669 + rrd_stats_dimension_add(st, "operations", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_ABSOLUTE, NULL);
2670 + }
2671 + else rrd_stats_next(st);
2672 +
2673 + rrd_stats_dimension_set(st, "operations", &currentios, NULL);
2674 + rrd_stats_done(st);
2675 }
2676
2677 fclose(fp);
@@ -2528,13 +2715,15 @@ int do_proc_net_snmp() {
2715 if(r == EOF) break;
2716 if(r != 19) error("Cannot read /proc/net/snmp IP line. Expected 19 params, read %d.", r);
2717
2718 + // --------------------------------------------------------------------
2719 +
2720 RRD_STATS *st = rrd_stats_find(RRD_TYPE_NET_SNMP ".packets");
2721 if(!st) {
2722 st = rrd_stats_create(RRD_TYPE_NET_SNMP, "packets", NULL, RRD_TYPE_NET_SNMP, "IPv4 Packets", "packets/s", save_history);
2723
2535 - rrd_stats_dimension_add(st, "forwarded", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2536 - rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2724 rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2725 + rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2726 + rrd_stats_dimension_add(st, "forwarded", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2727 }
2728 else rrd_stats_next(st);
2729
@@ -2561,6 +2750,8 @@ int do_proc_net_snmp() {
2750 if(r == EOF) break;
2751 if(r != 14) error("Cannot read /proc/net/snmp TCP line. Expected 14 params, read %d.", r);
2752
2753 + // --------------------------------------------------------------------
2754 +
2755 // see http://net-snmp.sourceforge.net/docs/mibs/tcp.html
2756 RRD_STATS *st = rrd_stats_find(RRD_TYPE_NET_SNMP ".tcpsock");
2757 if(!st) {
@@ -2573,12 +2764,14 @@ int do_proc_net_snmp() {
2764 rrd_stats_dimension_set(st, "connections", &CurrEstab, NULL);
2765 rrd_stats_done(st);
2766
2767 + // --------------------------------------------------------------------
2768 +
2769 st = rrd_stats_find(RRD_TYPE_NET_SNMP ".tcppackets");
2770 if(!st) {
2771 st = rrd_stats_create(RRD_TYPE_NET_SNMP, "tcppackets", NULL, RRD_TYPE_NET_SNMP, "IPv4 TCP Packets", "packets/s", save_history);
2772
2580 - rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2773 rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2774 + rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2775 }
2776 else rrd_stats_next(st);
2777
@@ -2604,13 +2797,15 @@ int do_proc_net_snmp() {
2797 if(r == EOF) break;
2798 if(r != 6) error("Cannot read /proc/net/snmp UDP line. Expected 6 params, read %d.", r);
2799
2800 + // --------------------------------------------------------------------
2801 +
2802 // see http://net-snmp.sourceforge.net/docs/mibs/udp.html
2803 RRD_STATS *st = rrd_stats_find(RRD_TYPE_NET_SNMP ".udppackets");
2804 if(!st) {
2805 st = rrd_stats_create(RRD_TYPE_NET_SNMP, "udppackets", NULL, RRD_TYPE_NET_SNMP, "IPv4 UDP Packets", "packets/s", save_history);
2806
2612 - rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2807 rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2808 + rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2809 }
2810 else rrd_stats_next(st);
2811
@@ -2650,26 +2845,110 @@ int do_proc_net_netstat() {
2845 break;
2846 }
2847
2653 - unsigned long long InNoRoutes, InTruncatedPkts, InMcastPkts, OutMcastPkts, InBcastPkts, OutBcastPkts, InOctets, OutOctets, InMcastOctets, OutMcastOctets, InBcastOctets, OutBcastOctets;
2848 + unsigned long long
2849 + InNoRoutes = 0, InTruncatedPkts = 0,
2850 + InOctets = 0, InMcastPkts = 0, InBcastPkts = 0, InMcastOctets = 0, InBcastOctets = 0,
2851 + OutOctets = 0, OutMcastPkts = 0, OutBcastPkts = 0, OutMcastOctets = 0, OutBcastOctets = 0;
2852
2853 int r = sscanf(&buffer[7], "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
2656 - &InNoRoutes, &InTruncatedPkts, &InMcastPkts, &OutMcastPkts, &InBcastPkts, &OutBcastPkts, &InOctets, &OutOctets, &InMcastOctets, &OutMcastOctets, &InBcastOctets, &OutBcastOctets);
2854 + &InNoRoutes, &InTruncatedPkts, &InMcastPkts, &OutMcastPkts, &InBcastPkts, &OutBcastPkts,
2855 + &InOctets, &OutOctets, &InMcastOctets, &OutMcastOctets, &InBcastOctets, &OutBcastOctets);
2856
2857 if(r == EOF) break;
2659 - if(r != 12) error("Cannot read /proc/net/netstat IpExt line. Expected 12 params, read %d.", r);
2858 + if(r != 12) {
2859 + error("Cannot read /proc/net/netstat IpExt line. Expected 12 params, read %d.", r);
2860 + continue;
2861 + }
2862 +
2863 + // --------------------------------------------------------------------
2864
2661 - RRD_STATS *st = rrd_stats_find(RRD_TYPE_NET_SNMP ".net");
2865 + RRD_STATS *st = rrd_stats_find("system.ipv4");
2866 if(!st) {
2663 - st = rrd_stats_create(RRD_TYPE_NET_SNMP, "net", NULL, RRD_TYPE_NET_SNMP, "All IPv4 Bandwidth", "kilobits/s", save_history);
2867 + st = rrd_stats_create("system", "ipv4", NULL, "system", "IPv4 Bandwidth", "kilobits/s", save_history);
2868
2665 - rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2869 rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2870 + rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2871 }
2872 else rrd_stats_next(st);
2873
2874 rrd_stats_dimension_set(st, "sent", &OutOctets, NULL);
2875 rrd_stats_dimension_set(st, "received", &InOctets, NULL);
2876 rrd_stats_done(st);
2877 +
2878 + // --------------------------------------------------------------------
2879 +
2880 + st = rrd_stats_find("ipv4.inerrors");
2881 + if(!st) {
2882 + st = rrd_stats_create("ipv4", "inerrors", NULL, "ipv4", "IPv4 Input Errors", "packets/s", save_history);
2883 +
2884 + rrd_stats_dimension_add(st, "noroutes", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2885 + rrd_stats_dimension_add(st, "trunkated", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2886 + }
2887 + else rrd_stats_next(st);
2888 +
2889 + rrd_stats_dimension_set(st, "noroutes", &InNoRoutes, NULL);
2890 + rrd_stats_dimension_set(st, "trunkated", &InTruncatedPkts, NULL);
2891 + rrd_stats_done(st);
2892 +
2893 + // --------------------------------------------------------------------
2894 +
2895 + st = rrd_stats_find("ipv4.mcast");
2896 + if(!st) {
2897 + st = rrd_stats_create("ipv4", "mcast", NULL, "ipv4", "IPv4 Multicast Bandwidth", "kilobits/s", save_history);
2898 +
2899 + rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2900 + rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2901 + }
2902 + else rrd_stats_next(st);
2903 +
2904 + rrd_stats_dimension_set(st, "sent", &OutMcastOctets, NULL);
2905 + rrd_stats_dimension_set(st, "received", &InMcastOctets, NULL);
2906 + rrd_stats_done(st);
2907 +
2908 + // --------------------------------------------------------------------
2909 +
2910 + st = rrd_stats_find("ipv4.bcast");
2911 + if(!st) {
2912 + st = rrd_stats_create("ipv4", "bcast", NULL, "ipv4", "IPv4 Broadcast Bandwidth", "kilobits/s", save_history);
2913 +
2914 + rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2915 + rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
2916 + }
2917 + else rrd_stats_next(st);
2918 +
2919 + rrd_stats_dimension_set(st, "sent", &OutBcastOctets, NULL);
2920 + rrd_stats_dimension_set(st, "received", &InBcastOctets, NULL);
2921 + rrd_stats_done(st);
2922 +
2923 + // --------------------------------------------------------------------
2924 +
2925 + st = rrd_stats_find("ipv4.mcastpkts");
2926 + if(!st) {
2927 + st = rrd_stats_create("ipv4", "mcastpkts", NULL, "ipv4", "IPv4 Multicast Packets", "packets/s", save_history);
2928 +
2929 + rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2930 + rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2931 + }
2932 + else rrd_stats_next(st);
2933 +
2934 + rrd_stats_dimension_set(st, "sent", &OutMcastPkts, NULL);
2935 + rrd_stats_dimension_set(st, "received", &InMcastPkts, NULL);
2936 + rrd_stats_done(st);
2937 +
2938 + // --------------------------------------------------------------------
2939 +
2940 + st = rrd_stats_find("ipv4.bcastpkts");
2941 + if(!st) {
2942 + st = rrd_stats_create("ipv4", "bcastpkts", NULL, "ipv4", "IPv4 Broadcast Packets", "packets/s", save_history);
2943 +
2944 + rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2945 + rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
2946 + }
2947 + else rrd_stats_next(st);
2948 +
2949 + rrd_stats_dimension_set(st, "sent", &OutBcastPkts, NULL);
2950 + rrd_stats_dimension_set(st, "received", &InBcastPkts, NULL);
2951 + rrd_stats_done(st);
2952 }
2953 }
2954
@@ -2744,8 +3023,8 @@ int do_proc_net_stat_conntrack() {
3023 if(!st) {
3024 st = rrd_stats_create(RRD_TYPE_NET_STAT_CONNTRACK, "new", NULL, RRD_TYPE_NET_STAT_CONNTRACK, "Netfilter New Connections", "connections/s", save_history);
3025
2747 - rrd_stats_dimension_add(st, "dropped", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3026 rrd_stats_dimension_add(st, "new", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3027 + rrd_stats_dimension_add(st, "dropped", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3028 }
3029 else rrd_stats_next(st);
3030
@@ -2757,8 +3036,8 @@ int do_proc_net_stat_conntrack() {
3036 if(!st) {
3037 st = rrd_stats_create(RRD_TYPE_NET_STAT_CONNTRACK, "changes", NULL, RRD_TYPE_NET_STAT_CONNTRACK, "Netfilter Connection Changes", "connections/s", save_history);
3038
2760 - rrd_stats_dimension_add(st, "deleted", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3039 rrd_stats_dimension_add(st, "inserted", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3040 + rrd_stats_dimension_add(st, "deleted", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3041 }
3042 else rrd_stats_next(st);
3043
@@ -2827,8 +3106,8 @@ int do_proc_net_ip_vs_stats() {
3106 if(!st) {
3107 st = rrd_stats_create(RRD_TYPE_NET_IPVS, "packets", NULL, RRD_TYPE_NET_IPVS, "IPVS Packets", "packets/s", save_history);
3108
2830 - rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3109 rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3110 + rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3111 }
3112 else rrd_stats_next(st);
3113
@@ -2840,8 +3119,8 @@ int do_proc_net_ip_vs_stats() {
3119 if(!st) {
3120 st = rrd_stats_create(RRD_TYPE_NET_IPVS, "net", NULL, RRD_TYPE_NET_IPVS, "IPVS Bandwidth", "kilobits/s", save_history);
3121
2843 - rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
3122 rrd_stats_dimension_add(st, "received", NULL, sizeof(unsigned long long), 0, 8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
3123 + rrd_stats_dimension_add(st, "sent", NULL, sizeof(unsigned long long), 0, -8, 1024, RRD_DIMENSION_INCREMENTAL, NULL);
3124 }
3125 else rrd_stats_next(st);
3126
@@ -2875,28 +3154,32 @@ int do_proc_stat() {
3154 if(r == EOF) break;
3155 if(r < 10) error("Cannot read /proc/stat cpu line. Expected 11 params, read %d.", r);
3156
2878 - RRD_STATS *st = rrd_stats_find_bytype(RRD_TYPE_STAT, id);
2879 - if(!st) {
2880 - char *title = "Core utilization";
2881 - if(strcmp(id, "cpu") == 0) title = "Total CPU utilization";
3157 + char *title = "Core utilization";
3158 + char *type = RRD_TYPE_STAT;
3159 + if(strcmp(id, "cpu") == 0) {
3160 + title = "Total CPU utilization";
3161 + type = "system";
3162 + }
3163
2883 - st = rrd_stats_create(RRD_TYPE_STAT, id, NULL, RRD_TYPE_STAT, title, "percentage", save_history);
3164 + RRD_STATS *st = rrd_stats_find_bytype(type, id);
3165 + if(!st) {
3166 + st = rrd_stats_create(type, id, NULL, type, title, "percentage", save_history);
3167
3168 long multiplier = 1;
3169 long divisor = 1; // sysconf(_SC_CLK_TCK);
3170
2888 - rrd_stats_dimension_add(st, "iowait", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
2889 - rrd_stats_dimension_add(st, "nice", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
2890 - rrd_stats_dimension_add(st, "system", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
3171 + rrd_stats_dimension_add(st, "guest_nice", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
3172 + rrd_stats_dimension_add(st, "guest", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
3173 + rrd_stats_dimension_add(st, "steal", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
3174 + rrd_stats_dimension_add(st, "softirq", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
3175 + rrd_stats_dimension_add(st, "irq", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
3176 rrd_stats_dimension_add(st, "user", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
3177 + rrd_stats_dimension_add(st, "system", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
3178 + rrd_stats_dimension_add(st, "nice", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
3179 + rrd_stats_dimension_add(st, "iowait", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
3180 +
3181 rrd_stats_dimension_add(st, "idle", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
3182 rrd_stats_dimension_hide(st, "idle");
2894 -
2895 - rrd_stats_dimension_add(st, "irq", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
2896 - rrd_stats_dimension_add(st, "softirq", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
2897 - rrd_stats_dimension_add(st, "steal", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
2898 - rrd_stats_dimension_add(st, "guest", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
2899 - rrd_stats_dimension_add(st, "guest_nice", NULL, sizeof(unsigned long long), 0, multiplier, divisor, RRD_DIMENSION_PCENT_OVER_DIFF_TOTAL, NULL);
3183 }
3184 else rrd_stats_next(st);
3185
@@ -2921,9 +3204,9 @@ int do_proc_stat() {
3204 if(r == EOF) break;
3205 if(r != 2) error("Cannot read /proc/stat intr line. Expected 2 params, read %d.", r);
3206
2924 - RRD_STATS *st = rrd_stats_find_bytype(RRD_TYPE_STAT, id);
3207 + RRD_STATS *st = rrd_stats_find_bytype("system", id);
3208 if(!st) {
2926 - st = rrd_stats_create(RRD_TYPE_STAT, id, NULL, RRD_TYPE_STAT, "CPU Interrupts", "interrupts/s", save_history);
3209 + st = rrd_stats_create("system", id, NULL, "system", "CPU Interrupts", "interrupts/s", save_history);
3210
3211 rrd_stats_dimension_add(st, "interrupts", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3212 }
@@ -2941,9 +3224,9 @@ int do_proc_stat() {
3224 if(r == EOF) break;
3225 if(r != 2) error("Cannot read /proc/stat ctxt line. Expected 2 params, read %d.", r);
3226
2944 - RRD_STATS *st = rrd_stats_find_bytype(RRD_TYPE_STAT, id);
3227 + RRD_STATS *st = rrd_stats_find_bytype("system", id);
3228 if(!st) {
2946 - st = rrd_stats_create(RRD_TYPE_STAT, id, NULL, RRD_TYPE_STAT, "CPU Context Switches", "context switches/s", save_history);
3229 + st = rrd_stats_create("system", id, NULL, "system", "CPU Context Switches", "context switches/s", save_history);
3230
3231 rrd_stats_dimension_add(st, "switches", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3232 }
@@ -2961,9 +3244,9 @@ int do_proc_stat() {
3244 if(r == EOF) break;
3245 if(r != 2) error("Cannot read /proc/stat processes line. Expected 2 params, read %d.", r);
3246
2964 - RRD_STATS *st = rrd_stats_find_bytype(RRD_TYPE_STAT, id);
3247 + RRD_STATS *st = rrd_stats_find_bytype("system", id);
3248 if(!st) {
2966 - st = rrd_stats_create(RRD_TYPE_STAT, id, NULL, RRD_TYPE_STAT, "Started Processes", "processes/s", save_history);
3249 + st = rrd_stats_create("system", id, NULL, "system", "New Processes", "new processes/s", save_history);
3250
3251 rrd_stats_dimension_add(st, "started", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3252 }
@@ -2981,9 +3264,9 @@ int do_proc_stat() {
3264 if(r == EOF) break;
3265 if(r != 2) error("Cannot read /proc/stat processes line. Expected 2 params, read %d.", r);
3266
2984 - RRD_STATS *st = rrd_stats_find_bytype(RRD_TYPE_STAT, id);
3267 + RRD_STATS *st = rrd_stats_find_bytype("system", id);
3268 if(!st) {
2986 - st = rrd_stats_create(RRD_TYPE_STAT, id, NULL, RRD_TYPE_STAT, "CPU Running Processes", "processes running", save_history);
3269 + st = rrd_stats_create("system", id, NULL, "system", "CPU Running Processes", "processes running", save_history);
3270
3271 rrd_stats_dimension_add(st, "running", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_ABSOLUTE, NULL);
3272 }
@@ -3085,14 +3368,14 @@ int do_proc_meminfo() {
3368 // http://stackoverflow.com/questions/3019748/how-to-reliably-measure-available-memory-in-linux
3369 MemUsed = MemTotal - MemFree - Cached - Buffers;
3370
3088 - RRD_STATS *st = rrd_stats_find("mem.ram");
3371 + RRD_STATS *st = rrd_stats_find("system.ram");
3372 if(!st) {
3090 - st = rrd_stats_create("mem", "ram", NULL, "mem", "System RAM", "percentage", save_history);
3373 + st = rrd_stats_create("system", "ram", NULL, "system", "System RAM", "percentage", save_history);
3374
3092 - rrd_stats_dimension_add(st, "free", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_PCENT_OVER_ROW_TOTAL, NULL);
3093 - rrd_stats_dimension_add(st, "cached", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_PCENT_OVER_ROW_TOTAL, NULL);
3094 - rrd_stats_dimension_add(st, "used", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_PCENT_OVER_ROW_TOTAL, NULL);
3375 rrd_stats_dimension_add(st, "buffers", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_PCENT_OVER_ROW_TOTAL, NULL);
3376 + rrd_stats_dimension_add(st, "used", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_PCENT_OVER_ROW_TOTAL, NULL);
3377 + rrd_stats_dimension_add(st, "cached", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_PCENT_OVER_ROW_TOTAL, NULL);
3378 + rrd_stats_dimension_add(st, "free", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_PCENT_OVER_ROW_TOTAL, NULL);
3379 }
3380 else rrd_stats_next(st);
3381
@@ -3105,6 +3388,173 @@ int do_proc_meminfo() {
3388 return 0;
3389 }
3390
3391 +// ----------------------------------------------------------------------------
3392 +// /proc/vmstat processor
3393 +
3394 +#define MAX_PROC_VMSTAT_LINE 4096
3395 +#define MAX_PROC_VMSTAT_NAME 1024
3396 +
3397 +int do_proc_vmstat() {
3398 + char buffer[MAX_PROC_VMSTAT_LINE+1] = "";
3399 +
3400 + FILE *fp = fopen("/proc/vmstat", "r");
3401 + if(!fp) {
3402 + error("Cannot read /proc/vmstat.");
3403 + return 1;
3404 + }
3405 +
3406 + unsigned long long nr_free_pages = 0, nr_inactive_anon = 0, nr_active_anon = 0, nr_inactive_file = 0, nr_active_file = 0, nr_unevictable = 0, nr_mlock = 0,
3407 + nr_anon_pages = 0, nr_mapped = 0, nr_file_pages = 0, nr_dirty = 0, nr_writeback = 0, nr_slab_reclaimable = 0, nr_slab_unreclaimable = 0, nr_page_table_pages = 0,
3408 + nr_kernel_stack = 0, nr_unstable = 0, nr_bounce = 0, nr_vmscan_write = 0, nr_vmscan_immediate_reclaim = 0, nr_writeback_temp = 0, nr_isolated_anon = 0, nr_isolated_file = 0,
3409 + nr_shmem = 0, nr_dirtied = 0, nr_written = 0, nr_anon_transparent_hugepages = 0, nr_dirty_threshold = 0, nr_dirty_background_threshold = 0,
3410 + pgpgin = 0, pgpgout = 0, pswpin = 0, pswpout = 0, pgalloc_dma = 0, pgalloc_dma32 = 0, pgalloc_normal = 0, pgalloc_movable = 0, pgfree = 0, pgactivate = 0, pgdeactivate = 0,
3411 + pgfault = 0, pgmajfault = 0, pgrefill_dma = 0, pgrefill_dma32 = 0, pgrefill_normal = 0, pgrefill_movable = 0, pgsteal_kswapd_dma = 0, pgsteal_kswapd_dma32 = 0,
3412 + pgsteal_kswapd_normal = 0, pgsteal_kswapd_movable = 0, pgsteal_direct_dma = 0, pgsteal_direct_dma32 = 0, pgsteal_direct_normal = 0, pgsteal_direct_movable = 0,
3413 + pgscan_kswapd_dma = 0, pgscan_kswapd_dma32 = 0, pgscan_kswapd_normal = 0, pgscan_kswapd_movable = 0, pgscan_direct_dma = 0, pgscan_direct_dma32 = 0, pgscan_direct_normal = 0,
3414 + pgscan_direct_movable = 0, pginodesteal = 0, slabs_scanned = 0, kswapd_inodesteal = 0, kswapd_low_wmark_hit_quickly = 0, kswapd_high_wmark_hit_quickly = 0,
3415 + kswapd_skip_congestion_wait = 0, pageoutrun = 0, allocstall = 0, pgrotated = 0, compact_blocks_moved = 0, compact_pages_moved = 0, compact_pagemigrate_failed = 0,
3416 + compact_stall = 0, compact_fail = 0, compact_success = 0, htlb_buddy_alloc_success = 0, htlb_buddy_alloc_fail = 0, unevictable_pgs_culled = 0, unevictable_pgs_scanned = 0,
3417 + unevictable_pgs_rescued = 0, unevictable_pgs_mlocked = 0, unevictable_pgs_munlocked = 0, unevictable_pgs_cleared = 0, unevictable_pgs_stranded = 0, unevictable_pgs_mlockfreed = 0,
3418 + thp_fault_alloc = 0, thp_fault_fallback = 0, thp_collapse_alloc = 0, thp_collapse_alloc_failed = 0, thp_split = 0;
3419 +
3420 + for(;1;) {
3421 + char *p = fgets(buffer, MAX_PROC_VMSTAT_NAME, fp);
3422 + if(!p) break;
3423 +
3424 + // remove ':'
3425 + while((p = strchr(buffer, ':'))) *p = ' ';
3426 +
3427 + char name[MAX_PROC_MEMINFO_NAME + 1] = "";
3428 + unsigned long long value = 0;
3429 +
3430 + int r = sscanf(buffer, "%s %llu\n", name, &value);
3431 +
3432 + if(r == EOF) break;
3433 + if(r != 2) error("Cannot read /proc/meminfo line. Expected 2 params, read %d.", r);
3434 +
3435 + if(!nr_free_pages && strcmp(name, "nr_free_pages") == 0) nr_free_pages = value;
3436 + else if(!nr_inactive_anon && strcmp(name, "nr_inactive_anon") == 0) nr_inactive_anon = value;
3437 + else if(!nr_active_anon && strcmp(name, "nr_active_anon") == 0) nr_active_anon = value;
3438 + else if(!nr_inactive_file && strcmp(name, "nr_inactive_file") == 0) nr_inactive_file = value;
3439 + else if(!nr_active_file && strcmp(name, "nr_active_file") == 0) nr_active_file = value;
3440 + else if(!nr_unevictable && strcmp(name, "nr_unevictable") == 0) nr_unevictable = value;
3441 + else if(!nr_mlock && strcmp(name, "nr_mlock") == 0) nr_mlock = value;
3442 + else if(!nr_anon_pages && strcmp(name, "nr_anon_pages") == 0) nr_anon_pages = value;
3443 + else if(!nr_mapped && strcmp(name, "nr_mapped") == 0) nr_mapped = value;
3444 + else if(!nr_file_pages && strcmp(name, "nr_file_pages") == 0) nr_file_pages = value;
3445 + else if(!nr_dirty && strcmp(name, "nr_dirty") == 0) nr_dirty = value;
3446 + else if(!nr_writeback && strcmp(name, "nr_writeback") == 0) nr_writeback = value;
3447 + else if(!nr_slab_reclaimable && strcmp(name, "nr_slab_reclaimable") == 0) nr_slab_reclaimable = value;
3448 + else if(!nr_slab_unreclaimable && strcmp(name, "nr_slab_unreclaimable") == 0) nr_slab_unreclaimable = value;
3449 + else if(!nr_page_table_pages && strcmp(name, "nr_page_table_pages") == 0) nr_page_table_pages = value;
3450 + else if(!nr_kernel_stack && strcmp(name, "nr_kernel_stack") == 0) nr_kernel_stack = value;
3451 + else if(!nr_unstable && strcmp(name, "nr_unstable") == 0) nr_unstable = value;
3452 + else if(!nr_bounce && strcmp(name, "nr_bounce") == 0) nr_bounce = value;
3453 + else if(!nr_vmscan_write && strcmp(name, "nr_vmscan_write") == 0) nr_vmscan_write = value;
3454 + else if(!nr_vmscan_immediate_reclaim && strcmp(name, "nr_vmscan_immediate_reclaim") == 0) nr_vmscan_immediate_reclaim = value;
3455 + else if(!nr_writeback_temp && strcmp(name, "nr_writeback_temp") == 0) nr_writeback_temp = value;
3456 + else if(!nr_isolated_anon && strcmp(name, "nr_isolated_anon") == 0) nr_isolated_anon = value;
3457 + else if(!nr_isolated_file && strcmp(name, "nr_isolated_file") == 0) nr_isolated_file = value;
3458 + else if(!nr_shmem && strcmp(name, "nr_shmem") == 0) nr_shmem = value;
3459 + else if(!nr_dirtied && strcmp(name, "nr_dirtied") == 0) nr_dirtied = value;
3460 + else if(!nr_written && strcmp(name, "nr_written") == 0) nr_written = value;
3461 + else if(!nr_anon_transparent_hugepages && strcmp(name, "nr_anon_transparent_hugepages") == 0) nr_anon_transparent_hugepages = value;
3462 + else if(!nr_dirty_threshold && strcmp(name, "nr_dirty_threshold") == 0) nr_dirty_threshold = value;
3463 + else if(!nr_dirty_background_threshold && strcmp(name, "nr_dirty_background_threshold") == 0) nr_dirty_background_threshold = value;
3464 + else if(!pgpgin && strcmp(name, "pgpgin") == 0) pgpgin = value;
3465 + else if(!pgpgout && strcmp(name, "pgpgout") == 0) pgpgout = value;
3466 + else if(!pswpin && strcmp(name, "pswpin") == 0) pswpin = value;
3467 + else if(!pswpout && strcmp(name, "pswpout") == 0) pswpout = value;
3468 + else if(!pgalloc_dma && strcmp(name, "pgalloc_dma") == 0) pgalloc_dma = value;
3469 + else if(!pgalloc_dma32 && strcmp(name, "pgalloc_dma32") == 0) pgalloc_dma32 = value;
3470 + else if(!pgalloc_normal && strcmp(name, "pgalloc_normal") == 0) pgalloc_normal = value;
3471 + else if(!pgalloc_movable && strcmp(name, "pgalloc_movable") == 0) pgalloc_movable = value;
3472 + else if(!pgfree && strcmp(name, "pgfree") == 0) pgfree = value;
3473 + else if(!pgactivate && strcmp(name, "pgactivate") == 0) pgactivate = value;
3474 + else if(!pgdeactivate && strcmp(name, "pgdeactivate") == 0) pgdeactivate = value;
3475 + else if(!pgfault && strcmp(name, "pgfault") == 0) pgfault = value;
3476 + else if(!pgmajfault && strcmp(name, "pgmajfault") == 0) pgmajfault = value;
3477 + else if(!pgrefill_dma && strcmp(name, "pgrefill_dma") == 0) pgrefill_dma = value;
3478 + else if(!pgrefill_dma32 && strcmp(name, "pgrefill_dma32") == 0) pgrefill_dma32 = value;
3479 + else if(!pgrefill_normal && strcmp(name, "pgrefill_normal") == 0) pgrefill_normal = value;
3480 + else if(!pgrefill_movable && strcmp(name, "pgrefill_movable") == 0) pgrefill_movable = value;
3481 + else if(!pgsteal_kswapd_dma && strcmp(name, "pgsteal_kswapd_dma") == 0) pgsteal_kswapd_dma = value;
3482 + else if(!pgsteal_kswapd_dma32 && strcmp(name, "pgsteal_kswapd_dma32") == 0) pgsteal_kswapd_dma32 = value;
3483 + else if(!pgsteal_kswapd_normal && strcmp(name, "pgsteal_kswapd_normal") == 0) pgsteal_kswapd_normal = value;
3484 + else if(!pgsteal_kswapd_movable && strcmp(name, "pgsteal_kswapd_movable") == 0) pgsteal_kswapd_movable = value;
3485 + else if(!pgsteal_direct_dma && strcmp(name, "pgsteal_direct_dma") == 0) pgsteal_direct_dma = value;
3486 + else if(!pgsteal_direct_dma32 && strcmp(name, "pgsteal_direct_dma32") == 0) pgsteal_direct_dma32 = value;
3487 + else if(!pgsteal_direct_normal && strcmp(name, "pgsteal_direct_normal") == 0) pgsteal_direct_normal = value;
3488 + else if(!pgsteal_direct_movable && strcmp(name, "pgsteal_direct_movable") == 0) pgsteal_direct_movable = value;
3489 + else if(!pgscan_kswapd_dma && strcmp(name, "pgscan_kswapd_dma") == 0) pgscan_kswapd_dma = value;
3490 + else if(!pgscan_kswapd_dma32 && strcmp(name, "pgscan_kswapd_dma32") == 0) pgscan_kswapd_dma32 = value;
3491 + else if(!pgscan_kswapd_normal && strcmp(name, "pgscan_kswapd_normal") == 0) pgscan_kswapd_normal = value;
3492 + else if(!pgscan_kswapd_movable && strcmp(name, "pgscan_kswapd_movable") == 0) pgscan_kswapd_movable = value;
3493 + else if(!pgscan_direct_dma && strcmp(name, "pgscan_direct_dma") == 0) pgscan_direct_dma = value;
3494 + else if(!pgscan_direct_dma32 && strcmp(name, "pgscan_direct_dma32") == 0) pgscan_direct_dma32 = value;
3495 + else if(!pgscan_direct_normal && strcmp(name, "pgscan_direct_normal") == 0) pgscan_direct_normal = value;
3496 + else if(!pgscan_direct_movable && strcmp(name, "pgscan_direct_movable") == 0) pgscan_direct_movable = value;
3497 + else if(!pginodesteal && strcmp(name, "pginodesteal") == 0) pginodesteal = value;
3498 + else if(!slabs_scanned && strcmp(name, "slabs_scanned") == 0) slabs_scanned = value;
3499 + else if(!kswapd_inodesteal && strcmp(name, "kswapd_inodesteal") == 0) kswapd_inodesteal = value;
3500 + else if(!kswapd_low_wmark_hit_quickly && strcmp(name, "kswapd_low_wmark_hit_quickly") == 0) kswapd_low_wmark_hit_quickly = value;
3501 + else if(!kswapd_high_wmark_hit_quickly && strcmp(name, "kswapd_high_wmark_hit_quickly") == 0) kswapd_high_wmark_hit_quickly = value;
3502 + else if(!kswapd_skip_congestion_wait && strcmp(name, "kswapd_skip_congestion_wait") == 0) kswapd_skip_congestion_wait = value;
3503 + else if(!pageoutrun && strcmp(name, "pageoutrun") == 0) pageoutrun = value;
3504 + else if(!allocstall && strcmp(name, "allocstall") == 0) allocstall = value;
3505 + else if(!pgrotated && strcmp(name, "pgrotated") == 0) pgrotated = value;
3506 + else if(!compact_blocks_moved && strcmp(name, "compact_blocks_moved") == 0) compact_blocks_moved = value;
3507 + else if(!compact_pages_moved && strcmp(name, "compact_pages_moved") == 0) compact_pages_moved = value;
3508 + else if(!compact_pagemigrate_failed && strcmp(name, "compact_pagemigrate_failed") == 0) compact_pagemigrate_failed = value;
3509 + else if(!compact_stall && strcmp(name, "compact_stall") == 0) compact_stall = value;
3510 + else if(!compact_fail && strcmp(name, "compact_fail") == 0) compact_fail = value;
3511 + else if(!compact_success && strcmp(name, "compact_success") == 0) compact_success = value;
3512 + else if(!htlb_buddy_alloc_success && strcmp(name, "htlb_buddy_alloc_success") == 0) htlb_buddy_alloc_success = value;
3513 + else if(!htlb_buddy_alloc_fail && strcmp(name, "htlb_buddy_alloc_fail") == 0) htlb_buddy_alloc_fail = value;
3514 + else if(!unevictable_pgs_culled && strcmp(name, "unevictable_pgs_culled") == 0) unevictable_pgs_culled = value;
3515 + else if(!unevictable_pgs_scanned && strcmp(name, "unevictable_pgs_scanned") == 0) unevictable_pgs_scanned = value;
3516 + else if(!unevictable_pgs_rescued && strcmp(name, "unevictable_pgs_rescued") == 0) unevictable_pgs_rescued = value;
3517 + else if(!unevictable_pgs_mlocked && strcmp(name, "unevictable_pgs_mlocked") == 0) unevictable_pgs_mlocked = value;
3518 + else if(!unevictable_pgs_munlocked && strcmp(name, "unevictable_pgs_munlocked") == 0) unevictable_pgs_munlocked = value;
3519 + else if(!unevictable_pgs_cleared && strcmp(name, "unevictable_pgs_cleared") == 0) unevictable_pgs_cleared = value;
3520 + else if(!unevictable_pgs_stranded && strcmp(name, "unevictable_pgs_stranded") == 0) unevictable_pgs_stranded = value;
3521 + else if(!unevictable_pgs_mlockfreed && strcmp(name, "unevictable_pgs_mlockfreed") == 0) unevictable_pgs_mlockfreed = value;
3522 + else if(!thp_fault_alloc && strcmp(name, "thp_fault_alloc") == 0) thp_fault_alloc = value;
3523 + else if(!thp_fault_fallback && strcmp(name, "thp_fault_fallback") == 0) thp_fault_fallback = value;
3524 + else if(!thp_collapse_alloc && strcmp(name, "thp_collapse_alloc") == 0) thp_collapse_alloc = value;
3525 + else if(!thp_collapse_alloc_failed && strcmp(name, "thp_collapse_alloc_failed") == 0) thp_collapse_alloc_failed = value;
3526 + else if(!thp_split && strcmp(name, "thp_split") == 0) thp_split = value;
3527 + }
3528 + fclose(fp);
3529 +
3530 + RRD_STATS *st = rrd_stats_find("system.swapio");
3531 + if(!st) {
3532 + st = rrd_stats_create("system", "swapio", NULL, "system", "Swap I/O", "kilobytes/s", save_history);
3533 +
3534 + rrd_stats_dimension_add(st, "in", NULL, sizeof(unsigned long long), 0, sysconf(_SC_PAGESIZE), 1024, RRD_DIMENSION_INCREMENTAL, NULL);
3535 + rrd_stats_dimension_add(st, "out", NULL, sizeof(unsigned long long), 0, -sysconf(_SC_PAGESIZE), 1024, RRD_DIMENSION_INCREMENTAL, NULL);
3536 + }
3537 + else rrd_stats_next(st);
3538 +
3539 + rrd_stats_dimension_set(st, "in", &pswpin, NULL);
3540 + rrd_stats_dimension_set(st, "out", &pswpout, NULL);
3541 + rrd_stats_done(st);
3542 +
3543 + st = rrd_stats_find("system.io");
3544 + if(!st) {
3545 + st = rrd_stats_create("system", "io", NULL, "system", "Disk I/O", "kilobytes/s", save_history);
3546 +
3547 + rrd_stats_dimension_add(st, "in", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3548 + rrd_stats_dimension_add(st, "out", NULL, sizeof(unsigned long long), 0, -1, 1, RRD_DIMENSION_INCREMENTAL, NULL);
3549 + }
3550 + else rrd_stats_next(st);
3551 +
3552 + rrd_stats_dimension_set(st, "in", &pgpgin, NULL);
3553 + rrd_stats_dimension_set(st, "out", &pgpgout, NULL);
3554 + rrd_stats_done(st);
3555 +
3556 + return 0;
3557 +}
3558
3559 // ----------------------------------------------------------------------------
3560 // /proc processor
@@ -3125,6 +3575,7 @@ void *proc_main(void *ptr)
3575 int vdo_proc_net_ip_vs_stats = 0;
3576 int vdo_proc_stat = 0;
3577 int vdo_proc_meminfo = 0;
3578 + int vdo_proc_vmstat = 0;
3579
3580 for(;1;) {
3581 unsigned long long usec, susec;
@@ -3143,6 +3594,7 @@ void *proc_main(void *ptr)
3594 if(!vdo_proc_net_ip_vs_stats) vdo_proc_net_ip_vs_stats = do_proc_net_ip_vs_stats(usec);
3595 if(!vdo_proc_stat) vdo_proc_stat = do_proc_stat(usec);
3596 if(!vdo_proc_meminfo) vdo_proc_meminfo = do_proc_meminfo(usec);
3597 + if(!vdo_proc_vmstat) vdo_proc_vmstat = do_proc_vmstat(usec);
3598 // END -- the job is done
3599
3600 // find the time to sleep in order to wait exactly update_every seconds
@@ -3482,9 +3934,9 @@ void *cpuidlejitter_main(void *ptr)
3934 }
3935 usec -= (CPU_IDLEJITTER_SLEEP_TIME_MS * 1000);
3936
3485 - RRD_STATS *st = rrd_stats_find(RRD_TYPE_STAT ".idlejitter");
3937 + RRD_STATS *st = rrd_stats_find("system.idlejitter");
3938 if(!st) {
3487 - st = rrd_stats_create(RRD_TYPE_STAT, "idlejitter", NULL, RRD_TYPE_STAT, "CPU Idle Jitter", "microseconds lost/s", save_history);
3939 + st = rrd_stats_create("system", "idlejitter", NULL, "system", "CPU Idle Jitter", "microseconds lost/s", save_history);
3940
3941 rrd_stats_dimension_add(st, "jitter", NULL, sizeof(unsigned long long), 0, 1, 1, RRD_DIMENSION_ABSOLUTE, NULL);
3942 }
web/index.html
+10 -8
@@ -298,14 +298,15 @@
298 });
299
300 $.each(categories, function(i, a) {
301 - if(a.name == "net") a.priority = 1;
302 - else if(a.name == "tc") a.priority = 2;
303 - else if(a.name == "conntrack") a.priority = 3;
304 - else if(a.name == "ipvs") a.priority = 4;
305 - else if(a.name == "ipv4") a.priority = 5;
306 - else if(a.name == "cpu") a.priority = 6;
307 - else if(a.name == "mem") a.priority = 7;
308 - else if(a.name == "disk") a.priority = 8;
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>";
@@ -423,6 +424,7 @@
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>
web/netdata.js
+40 -21
@@ -216,7 +216,9 @@ function loadCharts(base_url, doNext) {
216 if(json.charts[i].usertitle) json.charts[i].title = json.charts[i].usertitle;
217
218 // check if the userpriority is IGNORE
219 - if(json.charts[i].userpriority == "IGNORE")
219 + if(json.charts[i].userpriority == "IGNORE"
220 + // || json.charts[i].isdetail
221 + )
222 json.charts[i].enabled = false;
223 else
224 json.charts[i].enabled = true;
@@ -231,47 +233,64 @@ function loadCharts(base_url, doNext) {
233 vAxis: {title: json.charts[i].units, viewWindowMode: 'pretty', minValue: 0, maxValue: 10},
234 focusTarget: 'category',
235 annotation: {'1': {style: 'line'}},
236 + //colors: ['blue', 'red', 'green', 'lime', 'olive', 'yellow', 'navy', 'fuchsia', 'maroon', 'aqua', 'teal', 'purple', 'black', 'gray', 'silver'],
237 //tooltip: {isHtml: true},
238 };
239
240 // set the chart type
238 - if((json.charts[i].type == "ipv4"
239 - || json.charts[i].type == "ipv6"
240 - || json.charts[i].type == "ipvs"
241 - || json.charts[i].type == "conntrack"
242 - || json.charts[i].id == "cpu.ctxt"
243 - || json.charts[i].id == "cpu.intr"
244 - || json.charts[i].id == "cpu.processes"
245 - || json.charts[i].id == "cpu.procs_running"
246 - || json.charts[i].id == "cpu.idlejitter"
247 - )
248 - && json.charts[i].name != "ipv4.net" && json.charts[i].name != "ipvs.net") {
249 -
250 - // default for all LineChart
251 - json.charts[i].chartType = "LineChart";
252 - json.charts[i].chartOptions.lineWidth = 2;
253 - json.charts[i].chartOptions.curveType = 'function';
254 - }
255 - else if(json.charts[i].type == "tc" || json.charts[i].type == "cpu" || json.charts[i].name == 'mem.ram') {
241 + if(json.charts[i].type == "tc" || json.charts[i].id.substring(0, 7) == "cpu.cpu" || json.charts[i].name == 'system.cpu' || json.charts[i].name == 'system.ram') {
242
243 // default for all stacked AreaChart
244 json.charts[i].chartType = "AreaChart";
245 json.charts[i].chartOptions.isStacked = true;
246 json.charts[i].chartOptions.areaOpacity = 0.85;
247 json.charts[i].chartOptions.lineWidth = 1;
248 + json.charts[i].chartOptions.vAxis.viewWindowMode = 'maximized';
249
250 json.charts[i].group_method = "average";
251 }
265 - else {
252 + else if(json.charts[i].type == "net"
253 + || json.charts[i].type == "disk"
254 + || json.charts[i].id == "system.ipv4"
255 + || json.charts[i].id == "system.io"
256 + || json.charts[i].id == "system.swapio"
257 + || json.charts[i].id == "ipv4.mcast"
258 + || json.charts[i].id == "ipv4.bcast"
259 + ) {
260
261 // default for all AreaChart
262 json.charts[i].chartType = "AreaChart";
263 json.charts[i].chartOptions.isStacked = false;
264 json.charts[i].chartOptions.areaOpacity = 0.3;
265 }
266 + else {
267 +
268 + // default for all LineChart
269 + json.charts[i].chartType = "LineChart";
270 + json.charts[i].chartOptions.lineWidth = 2;
271 + json.charts[i].chartOptions.curveType = 'function';
272 +
273 + json.charts[i].chartOptions.vAxis.minValue = -10;
274 + json.charts[i].chartOptions.vAxis.maxValue = 10;
275 + }
276
277 // the category name, and other options, per type
278 switch(json.charts[i].type) {
279 + case "system":
280 + json.charts[i].category = "System";
281 + json.charts[i].glyphicon = "glyphicon-dashboard";
282 + json.charts[i].group = 5;
283 +
284 + if(json.charts[i].id == "system.cpu" || json.charts[i].id == "system.ram") {
285 + json.charts[i].chartOptions.vAxis.minValue = 0;
286 + json.charts[i].chartOptions.vAxis.maxValue = 100;
287 + }
288 + else {
289 + json.charts[i].chartOptions.vAxis.minValue = -10;
290 + json.charts[i].chartOptions.vAxis.maxValue = 10;
291 + }
292 + break;
293 +
294 case "cpu":
295 json.charts[i].category = "CPU";
296 json.charts[i].glyphicon = "glyphicon-dashboard";
@@ -336,7 +355,7 @@ function loadCharts(base_url, doNext) {
355 break;
356
357 default:
339 - json.charts[i].category = "Unknown";
358 + json.charts[i].category = json.charts[i].type;
359 json.charts[i].glyphicon = "glyphicon-search";
360 json.charts[i].group = 5;
361 break;