@cryptotaxi247 / netdata-1 / commits / d230a1173

apps.plugin now adjusts resources to system utilization; fixed a coupled of bugs too;

Costa Tsaousis (ktsaou) committed Jul 9, 2016 at 02:03 UTC d230a1173ca9a3ac83755cc28ca4e1f38aa4d345
1 file changed +469 -193
src/apps_plugin.c
+469 -193
@@ -43,6 +43,15 @@
43 #define MAX_NAME 100
44 #define MAX_CMDLINE 1024
45
46 +// the rates we are going to send to netdata
47 +// will have this detail
48 +// a value of:
49 +// 1 will send just integer parts to netdata
50 +// 100 will send 2 decimal points
51 +// 1000 will send 3 decimal points
52 +// etc.
53 +#define RATES_DETAIL 10000ULL
54 +
55 int processors = 1;
56 pid_t pid_max = 32768;
57 int debug = 0;
@@ -708,35 +717,35 @@ int read_proc_pid_stat(struct pid_stat *p) {
717
718 last = p->minflt_raw;
719 p->minflt_raw = strtoull(procfile_lineword(ff, 0, 9+i), NULL, 10);
711 - p->minflt = (p->minflt_raw - last) * (1000000 * 100) / (p->stat_collected_usec - p->last_stat_collected_usec);
720 + p->minflt = (p->minflt_raw - last) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
721
722 last = p->cminflt_raw;
723 p->cminflt_raw = strtoull(procfile_lineword(ff, 0, 10+i), NULL, 10);
715 - p->cminflt = (p->cminflt_raw - last) * (1000000 * 100) / (p->stat_collected_usec - p->last_stat_collected_usec);
724 + p->cminflt = (p->cminflt_raw - last) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
725
726 last = p->majflt_raw;
727 p->majflt_raw = strtoull(procfile_lineword(ff, 0, 11+i), NULL, 10);
719 - p->majflt = (p->majflt_raw - last) * (1000000 * 100) / (p->stat_collected_usec - p->last_stat_collected_usec);
728 + p->majflt = (p->majflt_raw - last) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
729
730 last = p->cmajflt_raw;
731 p->cmajflt_raw = strtoull(procfile_lineword(ff, 0, 12+i), NULL, 10);
723 - p->cmajflt = (p->cmajflt_raw - last) * (1000000 * 100) / (p->stat_collected_usec - p->last_stat_collected_usec);
732 + p->cmajflt = (p->cmajflt_raw - last) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
733
734 last = p->utime_raw;
735 p->utime_raw = strtoull(procfile_lineword(ff, 0, 13+i), NULL, 10);
727 - p->utime = (p->utime_raw - last) * (1000000 * 100) / (p->stat_collected_usec - p->last_stat_collected_usec);
736 + p->utime = (p->utime_raw - last) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
737
738 last = p->stime_raw;
739 p->stime_raw = strtoull(procfile_lineword(ff, 0, 14+i), NULL, 10);
731 - p->stime = (p->stime_raw - last) * (1000000 * 100) / (p->stat_collected_usec - p->last_stat_collected_usec);
740 + p->stime = (p->stime_raw - last) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
741
742 last = p->cutime_raw;
743 p->cutime_raw = strtoull(procfile_lineword(ff, 0, 15+i), NULL, 10);
735 - p->cutime = (p->cutime_raw - last) * (1000000 * 100) / (p->stat_collected_usec - p->last_stat_collected_usec);
744 + p->cutime = (p->cutime_raw - last) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
745
746 last = p->cstime_raw;
747 p->cstime_raw = strtoull(procfile_lineword(ff, 0, 16+i), NULL, 10);
739 - p->cstime = (p->cstime_raw - last) * (1000000 * 100) / (p->stat_collected_usec - p->last_stat_collected_usec);
748 + p->cstime = (p->cstime_raw - last) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
749
750 // p->priority = strtoull(procfile_lineword(ff, 0, 17+i), NULL, 10);
751 // p->nice = strtoull(procfile_lineword(ff, 0, 18+i), NULL, 10);
@@ -861,31 +870,31 @@ int read_proc_pid_io(struct pid_stat *p) {
870
871 last = p->io_logical_bytes_read_raw;
872 p->io_logical_bytes_read_raw = strtoull(procfile_lineword(ff, 0, 1), NULL, 10);
864 - p->io_logical_bytes_read = (p->io_logical_bytes_read_raw - last) * (1000000 * 100) / (p->io_collected_usec - p->last_io_collected_usec);
873 + p->io_logical_bytes_read = (p->io_logical_bytes_read_raw - last) * (1000000ULL * RATES_DETAIL) / (p->io_collected_usec - p->last_io_collected_usec);
874
875 last = p->io_logical_bytes_written_raw;
876 p->io_logical_bytes_written_raw = strtoull(procfile_lineword(ff, 1, 1), NULL, 10);
868 - p->io_logical_bytes_written = (p->io_logical_bytes_written_raw - last) * (1000000 * 100) / (p->io_collected_usec - p->last_io_collected_usec);
877 + p->io_logical_bytes_written = (p->io_logical_bytes_written_raw - last) * (1000000ULL * RATES_DETAIL) / (p->io_collected_usec - p->last_io_collected_usec);
878
879 last = p->io_read_calls_raw;
880 p->io_read_calls_raw = strtoull(procfile_lineword(ff, 2, 1), NULL, 10);
872 - p->io_read_calls = (p->io_read_calls_raw - last) * (1000000 * 100) / (p->io_collected_usec - p->last_io_collected_usec);
881 + p->io_read_calls = (p->io_read_calls_raw - last) * (1000000ULL * RATES_DETAIL) / (p->io_collected_usec - p->last_io_collected_usec);
882
883 last = p->io_write_calls_raw;
884 p->io_write_calls_raw = strtoull(procfile_lineword(ff, 3, 1), NULL, 10);
876 - p->io_write_calls = (p->io_write_calls_raw - last) * (1000000 * 100) / (p->io_collected_usec - p->last_io_collected_usec);
885 + p->io_write_calls = (p->io_write_calls_raw - last) * (1000000ULL * RATES_DETAIL) / (p->io_collected_usec - p->last_io_collected_usec);
886
887 last = p->io_storage_bytes_read_raw;
888 p->io_storage_bytes_read_raw = strtoull(procfile_lineword(ff, 4, 1), NULL, 10);
880 - p->io_storage_bytes_read = (p->io_storage_bytes_read_raw - last) * (1000000 * 100) / (p->io_collected_usec - p->last_io_collected_usec);
889 + p->io_storage_bytes_read = (p->io_storage_bytes_read_raw - last) * (1000000ULL * RATES_DETAIL) / (p->io_collected_usec - p->last_io_collected_usec);
890
891 last = p->io_storage_bytes_written_raw;
892 p->io_storage_bytes_written_raw = strtoull(procfile_lineword(ff, 5, 1), NULL, 10);
884 - p->io_storage_bytes_written = (p->io_storage_bytes_written_raw - last) * (1000000 * 100) / (p->io_collected_usec - p->last_io_collected_usec);
893 + p->io_storage_bytes_written = (p->io_storage_bytes_written_raw - last) * (1000000ULL * RATES_DETAIL) / (p->io_collected_usec - p->last_io_collected_usec);
894
895 last = p->io_cancelled_write_bytes_raw;
896 p->io_cancelled_write_bytes_raw = strtoull(procfile_lineword(ff, 6, 1), NULL, 10);
888 - p->io_cancelled_write_bytes = (p->io_cancelled_write_bytes_raw - last) * (1000000 * 100) / (p->io_collected_usec - p->last_io_collected_usec);
897 + p->io_cancelled_write_bytes = (p->io_cancelled_write_bytes_raw - last) * (1000000ULL * RATES_DETAIL) / (p->io_collected_usec - p->last_io_collected_usec);
898
899 if(unlikely(global_iterations_counter == 1)) {
900 p->io_logical_bytes_read = 0;
@@ -910,6 +919,55 @@ cleanup:
919 return 1;
920 }
921
922 +unsigned long long global_utime = 0;
923 +unsigned long long global_stime = 0;
924 +
925 +int read_proc_stat() {
926 + static char filename[FILENAME_MAX + 1] = "";
927 + static procfile *ff = NULL;
928 + static unsigned long long utime_raw = 0, stime_raw = 0, ntime_raw = 0, collected_usec = 0, last_collected_usec = 0;
929 +
930 + if(unlikely(!ff)) {
931 + snprintfz(filename, FILENAME_MAX, "%s/proc/stat", host_prefix);
932 + ff = procfile_open(filename, " \t:", PROCFILE_FLAG_DEFAULT);
933 + if(unlikely(!ff)) goto cleanup;
934 + }
935 +
936 + ff = procfile_readall(ff);
937 + if(unlikely(!ff)) goto cleanup;
938 +
939 + last_collected_usec = collected_usec;
940 + collected_usec = timems();
941 +
942 + file_counter++;
943 +
944 + unsigned long long last;
945 +
946 + last = utime_raw;
947 + utime_raw = strtoull(procfile_lineword(ff, 0, 1), NULL, 10);
948 + global_utime = (utime_raw - last) * (1000000ULL * RATES_DETAIL) / (collected_usec - last_collected_usec);
949 +
950 + last = ntime_raw;
951 + ntime_raw = strtoull(procfile_lineword(ff, 0, 2), NULL, 10);
952 + global_utime += (ntime_raw - last) * (1000000ULL * RATES_DETAIL) / (collected_usec - last_collected_usec);
953 +
954 + last = stime_raw;
955 + stime_raw = strtoull(procfile_lineword(ff, 0, 3), NULL, 10);
956 + global_stime = (stime_raw - last) * (1000000ULL * RATES_DETAIL) / (collected_usec - last_collected_usec);
957 +
958 + if(unlikely(global_iterations_counter == 1)) {
959 + global_utime = 0;
960 + global_stime = 0;
961 + }
962 +
963 + return 0;
964 +
965 +cleanup:
966 + global_utime = 0;
967 + global_stime = 0;
968 + return 1;
969 +}
970 +
971
972 // ----------------------------------------------------------------------------
973 // file descriptor
@@ -1230,17 +1288,52 @@ int read_pid_file_descriptors(struct pid_stat *p) {
1288
1289 // ----------------------------------------------------------------------------
1290
1233 -#ifdef NETDATA_INTERNAL_CHECKS
1234 -void find_lost_child_debug(struct pid_stat *pe, struct pid_stat *ppe, unsigned long long lost, int type) {
1235 - int found = 0;
1236 - struct pid_stat *p = NULL, *pp = pe->parent;
1291 +int print_process_and_parents(struct pid_stat *p, unsigned long long time) {
1292 + char *prefix = "\\_ ";
1293 + int indent = 0;
1294 +
1295 + if(p->parent)
1296 + indent = print_process_and_parents(p->parent, p->stat_collected_usec);
1297 + else
1298 + prefix = " > ";
1299 +
1300 + char buffer[indent + 1];
1301 + int i;
1302 +
1303 + for(i = 0; i < indent ;i++) buffer[i] = ' ';
1304 + buffer[i] = '\0';
1305 +
1306 + fprintf(stderr, " %s %s%s (%d %s %lld"
1307 + , buffer
1308 + , prefix
1309 + , p->comm
1310 + , p->pid
1311 + , p->updated?"running":"exited"
1312 + , (long long)p->stat_collected_usec - (long long)time
1313 + );
1314 +
1315 + if(p->utime) fprintf(stderr, " utime=%llu", p->utime);
1316 + if(p->cutime) fprintf(stderr, " cutime=%llu", p->cutime);
1317 + if(p->stime) fprintf(stderr, " stime=%llu", p->stime);
1318 + if(p->cstime) fprintf(stderr, " cstime=%llu", p->cstime);
1319 + if(p->minflt) fprintf(stderr, " minflt=%llu", p->minflt);
1320 + if(p->cminflt) fprintf(stderr, " cminflt=%llu", p->cminflt);
1321 + if(p->majflt) fprintf(stderr, " majflt=%llu", p->majflt);
1322 + if(p->cmajflt) fprintf(stderr, " cmajflt=%llu", p->cmajflt);
1323 + fprintf(stderr, ")\n");
1324 +
1325 + return indent + 1;
1326 +}
1327
1328 +void print_process_tree(struct pid_stat *p, char *msg) {
1329 log_date(stderr);
1239 - fprintf(stderr, "Searching for candidate of lost resources of process %d (%s, %s) which is aggregated on %d (%s, %s)\n", pe->pid, pe->comm, pe->updated?"running":"exited", ppe->pid, ppe->comm, ppe->updated?"running":"exited");
1240 - while(pp) {
1241 - fprintf(stderr, " >> parent %d (%s, %s)\n", pp->pid, pp->comm, pp->updated?"running":"exited");
1242 - pp = pp->parent;
1243 - }
1330 + fprintf(stderr, "%s: process %s (%d, %s) with parents:\n", msg, p->comm, p->pid, p->updated?"running":"exited");
1331 + print_process_and_parents(p, p->stat_collected_usec);
1332 +}
1333 +
1334 +void find_lost_child_debug(struct pid_stat *pe, unsigned long long lost, int type) {
1335 + int found = 0;
1336 + struct pid_stat *p = NULL;
1337
1338 for(p = root_of_pids; p ; p = p->next) {
1339 if(p == pe) continue;
@@ -1296,104 +1389,156 @@ void find_lost_child_debug(struct pid_stat *pe, struct pid_stat *ppe, unsigned l
1389 }
1390 }
1391 }
1299 -#endif /* NETDATA_INTERNAL_CHECKS */
1392
1301 -void remove_exited_child_from_parent(unsigned long long *field, unsigned long long *pfield, unsigned long long *ifield, struct pid_stat *pe, struct pid_stat *ppe, int type) {
1302 - if(pfield) {
1303 - if(*field > *pfield) {
1304 - *field -= *pfield;
1305 - *pfield = 0;
1306 - }
1307 - else {
1308 - *pfield -= *field;
1309 - *field = 0;
1310 - }
1311 - }
1393 +unsigned long long remove_exited_child_from_parent(unsigned long long *field, unsigned long long *pfield) {
1394 + unsigned long long absorbed = 0;
1395
1313 - if(*field) {
1314 - if(ifield && ifield != pfield) {
1315 - if(*field > *ifield) {
1316 - *field -= *ifield;
1317 - *ifield = 0;
1318 - }
1319 - else {
1320 - *ifield -= *field;
1321 - *field = 0;
1322 - }
1323 - }
1396 + if(*field > *pfield) {
1397 + absorbed += *pfield;
1398 + *field -= *pfield;
1399 + *pfield = 0;
1400 }
1325 -
1326 - if(*field) {
1327 -#ifdef NETDATA_INTERNAL_CHECKS
1328 - find_lost_child_debug(pe, ppe, *field, type);
1329 -#endif
1330 - while(pe && !pe->updated) {
1331 - pe->keep = 1;
1332 - pe = pe->parent;
1333 - }
1401 + else {
1402 + absorbed += *field;
1403 + *pfield -= *field;
1404 + *field = 0;
1405 }
1406 +
1407 + return absorbed;
1408 }
1409
1410 void process_exited_processes() {
1338 - struct pid_stat *init = all_pids[1];
1411 struct pid_stat *p;
1412
1413 for(p = root_of_pids; p ; p = p->next) {
1342 - if(p->updated || !p->stat_collected_usec) continue;
1414 + if(p->updated || !p->stat_collected_usec)
1415 + continue;
1416
1417 struct pid_stat *pp = p->parent;
1418
1346 - // find the first parent that is running
1347 - while(pp && !pp->updated)
1348 - pp = pp->parent;
1349 -
1350 - unsigned long long rate;
1419 + unsigned long long utime = (p->utime_raw + p->cutime_raw) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
1420 + unsigned long long stime = (p->stime_raw + p->cstime_raw) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
1421 + unsigned long long minflt = (p->minflt_raw + p->cminflt_raw) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
1422 + unsigned long long majflt = (p->majflt_raw + p->cmajflt_raw) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
1423 +
1424 + if(utime + stime + minflt + majflt == 0)
1425 + continue;
1426 +
1427 + if(unlikely(debug)) {
1428 + log_date(stderr);
1429 + fprintf(stderr, "Absorb %s (%d %s total resources: utime=%llu stime=%llu minflt=%llu majflt=%llu)\n"
1430 + , p->comm
1431 + , p->pid
1432 + , p->updated?"running":"exited"
1433 + , utime
1434 + , stime
1435 + , minflt
1436 + , majflt
1437 + );
1438 + print_process_tree(p, "Searching parents");
1439 + }
1440 +
1441 + for(pp = p->parent; pp ; pp = pp->parent) {
1442 + if(!pp->updated) continue;
1443 +
1444 + unsigned long long absorbed;
1445 + absorbed = remove_exited_child_from_parent(&utime, &pp->cutime);
1446 + if(unlikely(debug && absorbed))
1447 + fprintf(stderr, " > process %s (%d %s) absorbed %llu utime (remaining: %llu)\n", pp->comm, pp->pid, pp->updated?"running":"exited", absorbed, utime);
1448 +
1449 + absorbed = remove_exited_child_from_parent(&stime, &pp->cstime);
1450 + if(unlikely(debug && absorbed))
1451 + fprintf(stderr, " > process %s (%d %s) absorbed %llu stime (remaining: %llu)\n", pp->comm, pp->pid, pp->updated?"running":"exited", absorbed, stime);
1452 +
1453 + absorbed = remove_exited_child_from_parent(&minflt, &pp->cminflt);
1454 + if(unlikely(debug && absorbed))
1455 + fprintf(stderr, " > process %s (%d %s) absorbed %llu minflt (remaining: %llu)\n", pp->comm, pp->pid, pp->updated?"running":"exited", absorbed, minflt);
1456 +
1457 + absorbed = remove_exited_child_from_parent(&majflt, &pp->cmajflt);
1458 + if(unlikely(debug && absorbed))
1459 + fprintf(stderr, " > process %s (%d %s) absorbed %llu majflt (remaining: %llu)\n", pp->comm, pp->pid, pp->updated?"running":"exited", absorbed, majflt);
1460 + }
1461 +
1462 + if(unlikely(utime + stime + minflt + majflt > 0)) {
1463 + if(unlikely(debug)) {
1464 + if(utime) find_lost_child_debug(p, utime, 3);
1465 + if(stime) find_lost_child_debug(p, stime, 4);
1466 + if(minflt) find_lost_child_debug(p, minflt, 1);
1467 + if(majflt) find_lost_child_debug(p, majflt, 2);
1468 + }
1469 +
1470 + p->keep = 1;
1471
1352 - rate = (p->utime_raw + p->cutime_raw) * (1000000 * 100) / (p->stat_collected_usec - p->last_stat_collected_usec);
1353 - remove_exited_child_from_parent(&rate, (pp)?&pp->cutime:NULL, (init)?&init->cutime:NULL, p, pp, 3);
1354 - p->cutime_raw = 0;
1355 - p->utime_raw = rate * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000 * 100);
1472 + if(unlikely(debug))
1473 + fprintf(stderr, " > remaining resources - KEEP - for another loop: %s (%d %s total resources: utime=%llu stime=%llu minflt=%llu majflt=%llu)\n"
1474 + , p->comm
1475 + , p->pid
1476 + , p->updated?"running":"exited"
1477 + , utime
1478 + , stime
1479 + , minflt
1480 + , majflt
1481 + );
1482 +
1483 + for(pp = p->parent; pp ; pp = pp->parent) {
1484 + if(pp->updated) break;
1485 + pp->keep = 1;
1486
1357 - rate = (p->stime_raw + p->cstime_raw) * (1000000 * 100) / (p->stat_collected_usec - p->last_stat_collected_usec);
1358 - remove_exited_child_from_parent(&rate, (pp)?&pp->cstime:NULL, (init)?&init->cstime:NULL, p, pp, 4);
1359 - p->cstime_raw = 0;
1360 - p->stime_raw = rate * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000 * 100);
1487 + if(unlikely(debug))
1488 + fprintf(stderr, " > - KEEP - parent for another loop: %s (%d %s)\n"
1489 + , pp->comm
1490 + , pp->pid
1491 + , pp->updated?"running":"exited"
1492 + );
1493 + }
1494
1362 - rate = (p->minflt_raw + p->cminflt_raw) * (1000000 * 100) / (p->stat_collected_usec - p->last_stat_collected_usec);
1363 - remove_exited_child_from_parent(&rate, (pp)?&pp->cminflt:NULL, (init)?&init->cminflt:NULL, p, pp, 1);
1364 - p->cminflt_raw = 0;
1365 - p->minflt_raw = rate * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000 * 100);
1495 + p->utime_raw = utime * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000ULL * RATES_DETAIL);
1496 + p->stime_raw = stime * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000ULL * RATES_DETAIL);
1497 + p->minflt_raw = minflt * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000ULL * RATES_DETAIL);
1498 + p->majflt_raw = majflt * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000ULL * RATES_DETAIL);
1499 + p->cutime_raw = p->cstime_raw = p->cminflt_raw = p->cmajflt_raw = 0;
1500
1367 - rate = (p->majflt_raw + p->cmajflt_raw) * (1000000 * 100) / (p->stat_collected_usec - p->last_stat_collected_usec);
1368 - remove_exited_child_from_parent(&rate, (pp)?&pp->cmajflt:NULL, (init)?&init->cmajflt:NULL, p, pp, 2);
1369 - p->cmajflt_raw = 0;
1370 - p->majflt_raw = rate * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000 * 100);
1501 + if(unlikely(debug))
1502 + fprintf(stderr, "\n");
1503 + }
1504 + else if(unlikely(debug)) {
1505 + fprintf(stderr, " > totally absorbed - DONE - %s (%d %s)\n"
1506 + , p->comm
1507 + , p->pid
1508 + , p->updated?"running":"exited"
1509 + );
1510 + }
1511 }
1512 }
1513
1514 void link_all_processes_to_their_parents(void) {
1375 - struct pid_stat *p = NULL;
1515 + struct pid_stat *p, *pp;
1516
1517 // link all children to their parents
1518 // and update children count on parents
1519 for(p = root_of_pids; p ; p = p->next) {
1380 - // for each process found running
1520 + // for each process found
1521
1382 - if(likely(p->ppid > 0 && all_pids[p->ppid])) {
1383 - // valid parent processes
1522 + p->sortlist = 0;
1523 + p->parent = NULL;
1524
1385 - struct pid_stat *pp;
1525 + if(unlikely(!p->ppid)) {
1526 + p->parent = NULL;
1527 + continue;
1528 + }
1529
1387 - p->parent = pp = all_pids[p->ppid];
1388 - p->parent->children_count++;
1530 + pp = all_pids[p->ppid];
1531 + if(likely(pp)) {
1532 + p->parent = pp;
1533 + pp->children_count++;
1534
1535 if(unlikely(debug || (p->target && p->target->debug)))
1536 fprintf(stderr, "apps.plugin: \tchild %d (%s, %s) on target '%s' has parent %d (%s, %s). Parent: utime=%llu, stime=%llu, minflt=%llu, majflt=%llu, cutime=%llu, cstime=%llu, cminflt=%llu, cmajflt=%llu\n", p->pid, p->comm, p->updated?"running":"exited", (p->target)?p->target->name:"UNSET", pp->pid, pp->comm, pp->updated?"running":"exited", pp->utime, pp->stime, pp->minflt, pp->majflt, pp->cutime, pp->cstime, pp->cminflt, pp->cmajflt);
1537 }
1393 - else if(unlikely(p->ppid != 0))
1538 + else {
1539 + p->parent = NULL;
1540 error("pid %d %s states parent %d, but the later does not exist.", p->pid, p->comm, p->ppid);
1395 -
1396 - p->sortlist = 0;
1541 + }
1542 }
1543 }
1544
@@ -1523,10 +1668,8 @@ void collect_data_for_pid(pid_t pid) {
1668 // --------------------------------------------------------------------
1669 // done!
1670
1526 -#ifdef NETDATA_INTERNAL_CHECKS
1527 - if(unlikely(all_pids_count && p->ppid && all_pids[p->ppid] && !all_pids[p->ppid]->read))
1671 + if(unlikely(debug && include_exited_childs && all_pids_count && p->ppid && all_pids[p->ppid] && !all_pids[p->ppid]->read))
1672 fprintf(stderr, "Read process %d (%s) sortlisted %d, but its parent %d (%s) sortlisted %d, is not read\n", p->pid, p->comm, p->sortlist, all_pids[p->ppid]->pid, all_pids[p->ppid]->comm, all_pids[p->ppid]->sortlist);
1529 -#endif
1673
1674 // mark it as updated
1675 p->updated = 1;
@@ -1553,17 +1696,19 @@ int collect_data_for_all_processes_from_proc(void) {
1696 p->children_count = 0;
1697 p->parent = NULL;
1698
1556 -#ifdef NETDATA_INTERNAL_CHECKS
1557 - if(unlikely(slc >= all_pids_count))
1558 - error("Internal error: I was thinking I had %ld processes in my arrays, but it seems there are more.", all_pids_count);
1559 -#endif
1699 all_pids_sortlist[slc++] = p->pid;
1700 }
1701
1563 - qsort((void *)all_pids_sortlist, all_pids_count, sizeof(pid_t), compar_pid);
1702 + if(unlikely(slc != all_pids_count)) {
1703 + error("Internal error: I was thinking I had %ld processes in my arrays, but it seems there are more.", all_pids_count);
1704 + all_pids_count = slc;
1705 + }
1706
1565 - for(slc = 0; slc < all_pids_count; slc++)
1566 - collect_data_for_pid(all_pids_sortlist[slc]);
1707 + if(include_exited_childs) {
1708 + qsort((void *)all_pids_sortlist, all_pids_count, sizeof(pid_t), compar_pid);
1709 + for(slc = 0; slc < all_pids_count; slc++)
1710 + collect_data_for_pid(all_pids_sortlist[slc]);
1711 + }
1712 }
1713
1714 char dirname[FILENAME_MAX + 1];
@@ -1592,6 +1737,7 @@ int collect_data_for_all_processes_from_proc(void) {
1737 // we do this by collecting the ownership of process
1738 // if we manage to get the ownership, the process still runs
1739
1740 + read_proc_stat();
1741 link_all_processes_to_their_parents();
1742 process_exited_processes();
1743
@@ -1619,13 +1765,11 @@ void cleanup_exited_pids(void) {
1765 struct pid_stat *p = NULL;
1766
1767 for(p = root_of_pids; p ;) {
1622 - if(!p->updated && (!p->keep || p->keeploops > 1)) {
1768 + if(!p->updated && (!p->keep || p->keeploops > 0)) {
1769 // fprintf(stderr, "\tEXITED %d %s [parent %d %s, target %s] utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->pid, p->comm, p->parent->pid, p->parent->comm, p->target->name, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);
1770
1625 -#ifdef NETDATA_INTERNAL_CHECKS
1626 - if(p->keep)
1627 - fprintf(stderr, " > cannot keep exited process %d (%s) anymore - removing it.\n", p->pid, p->comm);
1628 -#endif
1771 + if(unlikely(debug && (p->keep || p->keeploops)))
1772 + fprintf(stderr, " > CLEANUP cannot keep exited process %d (%s) anymore - removing it.\n", p->pid, p->comm);
1773
1774 for(c = 0 ; c < p->fds_size ; c++) if(p->fds[c] > 0) {
1775 file_descriptor_not_used(p->fds[c]);
@@ -1677,6 +1821,9 @@ void apply_apps_groups_targets_inheritance(void) {
1821 found = 0;
1822
1823 for(p = root_of_pids; p ; p = p->next) {
1824 + if(unlikely(!p->sortlist && !p->children_count))
1825 + p->sortlist = sortlist++;
1826 +
1827 // if this process does not have any children
1828 // and is not already merged
1829 // and has a parent
@@ -1705,11 +1852,6 @@ void apply_apps_groups_targets_inheritance(void) {
1852
1853 found++;
1854 }
1708 -
1709 - // since this process does not have any childs
1710 - // assign it to the current sortlist
1711 - if(unlikely(!p->sortlist && !p->children_count))
1712 - p->sortlist = sortlist++;
1855 }
1856
1857 if(unlikely(debug))
@@ -1733,6 +1875,9 @@ void apply_apps_groups_targets_inheritance(void) {
1875 p->sortlist = sortlist++;
1876 }
1877
1878 + if(all_pids[1])
1879 + all_pids[1]->sortlist = sortlist++;
1880 +
1881 // give a target to all merged child processes
1882 found = 1;
1883 while(found) {
@@ -1985,6 +2130,9 @@ void calculate_netdata_statistics(void) {
2130 // ----------------------------------------------------------------------------
2131 // update chart dimensions
2132
2133 +double utime_fix_ratio = 1.0, stime_fix_ratio = 1.0, cutime_fix_ratio = 1.0, cstime_fix_ratio = 1.0;
2134 +double minflt_fix_ratio = 1.0, majflt_fix_ratio = 1.0, cminflt_fix_ratio = 1.0, cmajflt_fix_ratio = 1.0;
2135 +
2136 unsigned long long send_resource_usage_to_netdata() {
2137 static struct timeval last = { 0, 0 };
2138 static struct rusage me_last;
@@ -2019,86 +2167,193 @@ unsigned long long send_resource_usage_to_netdata() {
2167 bcopy(&me, &me_last, sizeof(struct rusage));
2168 }
2169
2022 - fprintf(stdout, "BEGIN netdata.apps_cpu %llu\n", usec);
2023 - fprintf(stdout, "SET user = %llu\n", cpuuser);
2024 - fprintf(stdout, "SET system = %llu\n", cpusyst);
2025 - fprintf(stdout, "END\n");
2170 + fprintf(stdout,
2171 + "BEGIN netdata.apps_cpu %llu\n"
2172 + "SET user = %llu\n"
2173 + "SET system = %llu\n"
2174 + "END\n"
2175 + "BEGIN netdata.apps_files %llu\n"
2176 + "SET files = %llu\n"
2177 + "SET pids = %ld\n"
2178 + "SET fds = %d\n"
2179 + "SET targets = %ld\n"
2180 + "END\n"
2181 + "BEGIN netdata.apps_fix %llu\n"
2182 + "SET utime = %llu\n"
2183 + "SET stime = %llu\n"
2184 + "SET minflt = %llu\n"
2185 + "SET majflt = %llu\n"
2186 + "END\n"
2187 + , usec
2188 + , cpuuser
2189 + , cpusyst
2190 + , usec
2191 + , file_counter
2192 + , all_pids_count
2193 + , all_files_len
2194 + , apps_groups_targets
2195 + , usec
2196 + , (unsigned long long)(utime_fix_ratio * 100 * RATES_DETAIL)
2197 + , (unsigned long long)(stime_fix_ratio * 100 * RATES_DETAIL)
2198 + , (unsigned long long)(minflt_fix_ratio * 100 * RATES_DETAIL)
2199 + , (unsigned long long)(majflt_fix_ratio * 100 * RATES_DETAIL)
2200 + );
2201
2027 - fprintf(stdout, "BEGIN netdata.apps_files %llu\n", usec);
2028 - fprintf(stdout, "SET files = %llu\n", file_counter);
2029 - fprintf(stdout, "SET pids = %ld\n", all_pids_count);
2030 - fprintf(stdout, "SET fds = %d\n", all_files_len);
2031 - fprintf(stdout, "SET targets = %ld\n", apps_groups_targets);
2032 - fprintf(stdout, "END\n");
2202 + if(include_exited_childs)
2203 + fprintf(stdout,
2204 + "BEGIN netdata.apps_children_fix %llu\n"
2205 + "SET cutime = %llu\n"
2206 + "SET cstime = %llu\n"
2207 + "SET cminflt = %llu\n"
2208 + "SET cmajflt = %llu\n"
2209 + "END\n"
2210 + , usec
2211 + , (unsigned long long)(cutime_fix_ratio * 100 * RATES_DETAIL)
2212 + , (unsigned long long)(cstime_fix_ratio * 100 * RATES_DETAIL)
2213 + , (unsigned long long)(cminflt_fix_ratio * 100 * RATES_DETAIL)
2214 + , (unsigned long long)(cmajflt_fix_ratio * 100 * RATES_DETAIL)
2215 + );
2216
2217 return usec;
2218 }
2219
2037 -void send_collected_data_to_netdata(struct target *root, const char *type, unsigned long long usec)
2038 -{
2220 +void normalize_data(struct target *root) {
2221 struct target *w;
2040 - int childs = include_exited_childs;
2222
2042 - {
2043 - // childs processing introduces spikes
2044 - // here we try to eliminate them by disabling childs processing either for specific dimensions
2045 - // or entirely. Of course, either way, we disable it just a single iteration.
2223 + // childs processing introduces spikes
2224 + // here we try to eliminate them by disabling childs processing either for specific dimensions
2225 + // or entirely. Of course, either way, we disable it just a single iteration.
2226
2047 - unsigned long long max = processors * hz * 100;
2048 - unsigned long long utime = 0, cutime = 0, stime = 0, cstime = 0, minflt = 0, cminflt = 0, majflt = 0, cmajflt = 0;
2227 + unsigned long long max = processors * hz * RATES_DETAIL;
2228 + unsigned long long utime = 0, cutime = 0, stime = 0, cstime = 0, minflt = 0, cminflt = 0, majflt = 0, cmajflt = 0;
2229
2050 - for (w = root; w ; w = w->next) {
2051 - if(w->target || (!w->processes && !w->exposed)) continue;
2230 + if(global_utime > max) global_utime = max;
2231 + if(global_stime > max) global_stime = max;
2232
2053 - if((w->utime + w->stime + w->cutime + w->cstime) > max) {
2054 -#ifdef NETDATA_INTERNAL_CHECKS
2055 - log_date(stderr);
2056 - fprintf(stderr, "Prevented a spike on target '%s', reported CPU time = %llu (without childs = %llu)\n", w->name, (w->utime + w->stime + w->cutime + w->cstime) / 100, (w->utime + w->stime) / 100);
2057 -#endif
2058 - w->cutime = w->cstime = w->cminflt = w->majflt = 0;
2059 - }
2233 + for(w = root; w ; w = w->next) {
2234 + if(w->target || (!w->processes && !w->exposed)) continue;
2235
2061 - utime += w->utime;
2062 - cutime += w->cutime;
2063 - stime += w->stime;
2064 - cstime += w->cstime;
2065 - minflt += w->minflt;
2066 - cminflt += w->cminflt;
2067 - majflt += w->majflt;
2068 - cmajflt += w->cmajflt;
2236 + utime += w->utime;
2237 + cutime += w->cutime;
2238 + stime += w->stime;
2239 + cstime += w->cstime;
2240 + minflt += w->minflt;
2241 + cminflt += w->cminflt;
2242 + majflt += w->majflt;
2243 + cmajflt += w->cmajflt;
2244 + }
2245 +
2246 + if(global_utime && utime) {
2247 + if(global_utime > utime + cutime) {
2248 + // everything we collected is short
2249 + cutime_fix_ratio =
2250 + utime_fix_ratio = (double)global_utime / (double)(utime + cutime);
2251 }
2070 -
2071 - if((utime + stime + cutime + cstime) > max) {
2072 - childs = 0;
2073 -#ifdef NETDATA_INTERNAL_CHECKS
2074 - log_date(stderr);
2075 - fprintf(stderr, "Prevented a spike because the total CPU of all dimensions = %llu (without childs = %llu)\n", (utime + stime + cutime + cstime) / 100, (utime + stime) / 100);
2076 -#endif
2252 + else if(global_utime > utime) {
2253 + // cutime seems unrealistic
2254 + cutime_fix_ratio = (double)(global_utime - utime) / (double)cutime;
2255 + utime_fix_ratio = 1.0;
2256 + }
2257 + else {
2258 + // even utime is unrealistic
2259 + cutime_fix_ratio = 0.0;
2260 + utime_fix_ratio = (double)global_utime / (double)utime;
2261 }
2262 + }
2263 + else {
2264 + cutime_fix_ratio = 0.0;
2265 + utime_fix_ratio = 0.0;
2266 + }
2267
2079 - if((utime + stime) > max) {
2080 - childs = 0;
2081 - unsigned long long multiplier = max, divider = utime + stime;
2082 - for (w = root; w ; w = w->next) {
2083 - w->utime = w->utime * multiplier / divider;
2084 - w->stime = w->stime * multiplier / divider;
2085 - w->minflt = w->minflt * multiplier / divider;
2086 - w->majflt = w->majflt * multiplier / divider;
2087 - }
2268 + if(utime_fix_ratio > 1.0) utime_fix_ratio = 1.0;
2269 + if(cutime_fix_ratio > 1.0) cutime_fix_ratio = 1.0;
2270
2089 -#ifdef NETDATA_INTERNAL_CHECKS
2090 - log_date(stderr);
2091 - fprintf(stderr, "Reduced processes utilization (without childs) by %0.2f%% (CPU was %llu)\n", (float)(((utime + stime - max) * 100.0)/(float)max), (utime + stime) / 100);
2092 -#endif
2271 + if(global_utime && utime) {
2272 + if(global_stime > stime + cstime) {
2273 + // everything we collected is short
2274 + cstime_fix_ratio =
2275 + stime_fix_ratio = (double)global_stime / (double)(stime + cstime);
2276 + }
2277 + else if(global_stime > stime) {
2278 + // cstime seems unrealistic
2279 + cstime_fix_ratio = (double)(global_stime - stime) / (double)cstime;
2280 + stime_fix_ratio = 1.0;
2281 }
2282 + else {
2283 + // even stime is unrealistic
2284 + cstime_fix_ratio = 0.0;
2285 + stime_fix_ratio = (double)global_stime / (double)stime;
2286 + }
2287 + }
2288 + else {
2289 + cstime_fix_ratio = 0.0;
2290 + stime_fix_ratio = 0.0;
2291 + }
2292 +
2293 + if(stime_fix_ratio > 1.0) stime_fix_ratio = 1.0;
2294 + if(cstime_fix_ratio > 1.0) cstime_fix_ratio = 1.0;
2295 +
2296 + // FIXME
2297 + // we use cpu time to normalize page faults
2298 + // the problem is that to find the proper max values
2299 + // for page faults we have to parse /proc/vmstat
2300 + // which is quite big to do it again (netdata does it already)
2301 + //
2302 + // a better solution could be to somehow have netdata
2303 + // do this normalization for us
2304
2305 + if(cutime || cstime)
2306 + cmajflt_fix_ratio =
2307 + cminflt_fix_ratio = (double)(cutime * cutime_fix_ratio + cstime * cstime_fix_ratio) / (double)(cutime + cstime);
2308 + else
2309 + cminflt_fix_ratio =
2310 + cmajflt_fix_ratio = 1.0;
2311 +
2312 + if(utime || stime)
2313 + majflt_fix_ratio =
2314 + minflt_fix_ratio = (double)(utime * utime_fix_ratio + stime * stime_fix_ratio) / (double)(utime + stime);
2315 + else
2316 + minflt_fix_ratio =
2317 + majflt_fix_ratio = 1.0;
2318 +
2319 + // the report
2320 +
2321 + if(unlikely(debug)) {
2322 + fprintf(stderr,
2323 + "SYSTEM: u=%llu s=%llu "
2324 + "COLLECTED: u=%llu s=%llu cu=%llu cs=%llu "
2325 + "DELTA: u=%lld s=%lld "
2326 + "FIX: u=%0.2f s=%0.2f cu=%0.2f cs=%0.2f "
2327 + "FINALLY: u=%llu s=%llu cu=%llu cs=%llu "
2328 + "\n"
2329 + , global_utime
2330 + , global_stime
2331 + , utime
2332 + , stime
2333 + , cutime
2334 + , cstime
2335 + , (long long)utime + (long long)cutime - (long long)global_utime
2336 + , (long long)stime + (long long)cstime - (long long)global_stime
2337 + , utime_fix_ratio
2338 + , stime_fix_ratio
2339 + , cutime_fix_ratio
2340 + , cstime_fix_ratio
2341 + , (unsigned long long)(utime * utime_fix_ratio)
2342 + , (unsigned long long)(stime * stime_fix_ratio)
2343 + , (unsigned long long)(cutime * cutime_fix_ratio)
2344 + , (unsigned long long)(cstime * cstime_fix_ratio)
2345 + );
2346 }
2347 +}
2348 +
2349 +void send_collected_data_to_netdata(struct target *root, const char *type, unsigned long long usec) {
2350 + struct target *w;
2351
2352 fprintf(stdout, "BEGIN %s.cpu %llu\n", type, usec);
2353 for (w = root; w ; w = w->next) {
2354 if(w->target || (!w->processes && !w->exposed)) continue;
2355
2101 - fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + w->stime + (childs?(w->cutime + w->cstime):0));
2356 + fprintf(stdout, "SET %s = %llu\n", w->name, (unsigned long long)(w->utime * utime_fix_ratio) + (unsigned long long)(w->stime * stime_fix_ratio) + (include_exited_childs?((unsigned long long)(w->cutime * cutime_fix_ratio) + (unsigned long long)(w->cstime * cstime_fix_ratio)):0ULL));
2357 }
2358 fprintf(stdout, "END\n");
2359
@@ -2106,7 +2361,7 @@ void send_collected_data_to_netdata(struct target *root, const char *type, unsig
2361 for (w = root; w ; w = w->next) {
2362 if(w->target || (!w->processes && !w->exposed)) continue;
2363
2109 - fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + (childs?(w->cutime):0));
2364 + fprintf(stdout, "SET %s = %llu\n", w->name, (unsigned long long)(w->utime * utime_fix_ratio) + (include_exited_childs?((unsigned long long)(w->cutime * cutime_fix_ratio)):0ULL));
2365 }
2366 fprintf(stdout, "END\n");
2367
@@ -2114,7 +2369,7 @@ void send_collected_data_to_netdata(struct target *root, const char *type, unsig
2369 for (w = root; w ; w = w->next) {
2370 if(w->target || (!w->processes && !w->exposed)) continue;
2371
2117 - fprintf(stdout, "SET %s = %llu\n", w->name, w->stime + (childs?(w->cstime):0));
2372 + fprintf(stdout, "SET %s = %llu\n", w->name, (unsigned long long)(w->stime * stime_fix_ratio) + (include_exited_childs?((unsigned long long)(w->cstime * cstime_fix_ratio)):0ULL));
2373 }
2374 fprintf(stdout, "END\n");
2375
@@ -2146,7 +2401,7 @@ void send_collected_data_to_netdata(struct target *root, const char *type, unsig
2401 for (w = root; w ; w = w->next) {
2402 if(w->target || (!w->processes && !w->exposed)) continue;
2403
2149 - fprintf(stdout, "SET %s = %llu\n", w->name, w->minflt + (childs?(w->cminflt):0));
2404 + fprintf(stdout, "SET %s = %llu\n", w->name, (unsigned long long)(w->minflt * minflt_fix_ratio) + (include_exited_childs?((unsigned long long)(w->cminflt * cminflt_fix_ratio)):0ULL));
2405 }
2406 fprintf(stdout, "END\n");
2407
@@ -2154,7 +2409,7 @@ void send_collected_data_to_netdata(struct target *root, const char *type, unsig
2409 for (w = root; w ; w = w->next) {
2410 if(w->target || (!w->processes && !w->exposed)) continue;
2411
2157 - fprintf(stdout, "SET %s = %llu\n", w->name, w->majflt + (childs?(w->cmajflt):0));
2412 + fprintf(stdout, "SET %s = %llu\n", w->name, (unsigned long long)(w->majflt * majflt_fix_ratio) + (include_exited_childs?((unsigned long long)(w->cmajflt * cmajflt_fix_ratio)):0ULL));
2413 }
2414 fprintf(stdout, "END\n");
2415
@@ -2242,105 +2497,105 @@ void send_charts_updates_to_netdata(struct target *root, const char *type, const
2497 for (w = root; w ; w = w->next) {
2498 if(w->target || (!w->processes && !w->exposed)) continue;
2499
2245 - fprintf(stdout, "DIMENSION %s '' absolute 1 %u %s\n", w->name, hz, w->hidden ? "hidden,noreset" : "noreset");
2500 + fprintf(stdout, "DIMENSION %s '' absolute 1 %llu %s\n", w->name, hz * RATES_DETAIL / 100, w->hidden ? "hidden" : "");
2501 }
2502
2503 fprintf(stdout, "CHART %s.mem '' '%s Dedicated Memory (w/o shared)' 'MB' mem %s.mem stacked 20003 %d\n", type, title, type, update_every);
2504 for (w = root; w ; w = w->next) {
2505 if(w->target || (!w->processes && !w->exposed)) continue;
2506
2252 - fprintf(stdout, "DIMENSION %s '' absolute %ld %ld noreset\n", w->name, sysconf(_SC_PAGESIZE), 1024L*1024L);
2507 + fprintf(stdout, "DIMENSION %s '' absolute %ld %ld\n", w->name, sysconf(_SC_PAGESIZE), 1024L*1024L);
2508 }
2509
2510 fprintf(stdout, "CHART %s.threads '' '%s Threads' 'threads' processes %s.threads stacked 20005 %d\n", type, title, type, update_every);
2511 for (w = root; w ; w = w->next) {
2512 if(w->target || (!w->processes && !w->exposed)) continue;
2513
2259 - fprintf(stdout, "DIMENSION %s '' absolute 1 1 noreset\n", w->name);
2514 + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
2515 }
2516
2517 fprintf(stdout, "CHART %s.processes '' '%s Processes' 'processes' processes %s.processes stacked 20004 %d\n", type, title, type, update_every);
2518 for (w = root; w ; w = w->next) {
2519 if(w->target || (!w->processes && !w->exposed)) continue;
2520
2266 - fprintf(stdout, "DIMENSION %s '' absolute 1 1 noreset\n", w->name);
2521 + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
2522 }
2523
2524 fprintf(stdout, "CHART %s.cpu_user '' '%s CPU User Time (%d%% = %d core%s)' 'cpu time %%' cpu %s.cpu_user stacked 20020 %d\n", type, title, (processors * 100), processors, (processors>1)?"s":"", type, update_every);
2525 for (w = root; w ; w = w->next) {
2526 if(w->target || (!w->processes && !w->exposed)) continue;
2527
2273 - fprintf(stdout, "DIMENSION %s '' absolute 1 %u noreset\n", w->name, hz);
2528 + fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, hz * RATES_DETAIL / 100LLU);
2529 }
2530
2531 fprintf(stdout, "CHART %s.cpu_system '' '%s CPU System Time (%d%% = %d core%s)' 'cpu time %%' cpu %s.cpu_system stacked 20021 %d\n", type, title, (processors * 100), processors, (processors>1)?"s":"", type, update_every);
2532 for (w = root; w ; w = w->next) {
2533 if(w->target || (!w->processes && !w->exposed)) continue;
2534
2280 - fprintf(stdout, "DIMENSION %s '' absolute 1 %u noreset\n", w->name, hz);
2535 + fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, hz * RATES_DETAIL / 100LLU);
2536 }
2537
2538 fprintf(stdout, "CHART %s.major_faults '' '%s Major Page Faults (swap read)' 'page faults/s' swap %s.major_faults stacked 20010 %d\n", type, title, type, update_every);
2539 for (w = root; w ; w = w->next) {
2540 if(w->target || (!w->processes && !w->exposed)) continue;
2541
2287 - fprintf(stdout, "DIMENSION %s '' absolute 1 100 noreset\n", w->name);
2542 + fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, RATES_DETAIL);
2543 }
2544
2545 fprintf(stdout, "CHART %s.minor_faults '' '%s Minor Page Faults' 'page faults/s' mem %s.minor_faults stacked 20011 %d\n", type, title, type, update_every);
2546 for (w = root; w ; w = w->next) {
2547 if(w->target || (!w->processes && !w->exposed)) continue;
2548
2294 - fprintf(stdout, "DIMENSION %s '' absolute 1 100 noreset\n", w->name);
2549 + fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, RATES_DETAIL);
2550 }
2551
2552 fprintf(stdout, "CHART %s.lreads '' '%s Disk Logical Reads' 'kilobytes/s' disk %s.lreads stacked 20042 %d\n", type, title, type, update_every);
2553 for (w = root; w ; w = w->next) {
2554 if(w->target || (!w->processes && !w->exposed)) continue;
2555
2301 - fprintf(stdout, "DIMENSION %s '' incremental 1 %d noreset\n", w->name, 1024*100);
2556 + fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, 1024LLU * RATES_DETAIL);
2557 }
2558
2559 fprintf(stdout, "CHART %s.lwrites '' '%s I/O Logical Writes' 'kilobytes/s' disk %s.lwrites stacked 20042 %d\n", type, title, type, update_every);
2560 for (w = root; w ; w = w->next) {
2561 if(w->target || (!w->processes && !w->exposed)) continue;
2562
2308 - fprintf(stdout, "DIMENSION %s '' incremental 1 %d noreset\n", w->name, 1024*100);
2563 + fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, 1024LLU * RATES_DETAIL);
2564 }
2565
2566 fprintf(stdout, "CHART %s.preads '' '%s Disk Reads' 'kilobytes/s' disk %s.preads stacked 20002 %d\n", type, title, type, update_every);
2567 for (w = root; w ; w = w->next) {
2568 if(w->target || (!w->processes && !w->exposed)) continue;
2569
2315 - fprintf(stdout, "DIMENSION %s '' incremental 1 %d noreset\n", w->name, 1024*100);
2570 + fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, 1024LLU * RATES_DETAIL);
2571 }
2572
2573 fprintf(stdout, "CHART %s.pwrites '' '%s Disk Writes' 'kilobytes/s' disk %s.pwrites stacked 20002 %d\n", type, title, type, update_every);
2574 for (w = root; w ; w = w->next) {
2575 if(w->target || (!w->processes && !w->exposed)) continue;
2576
2322 - fprintf(stdout, "DIMENSION %s '' incremental 1 %d noreset\n", w->name, 1024*100);
2577 + fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, 1024LLU * RATES_DETAIL);
2578 }
2579
2580 fprintf(stdout, "CHART %s.files '' '%s Open Files' 'open files' disk %s.files stacked 20050 %d\n", type, title, type, update_every);
2581 for (w = root; w ; w = w->next) {
2582 if(w->target || (!w->processes && !w->exposed)) continue;
2583
2329 - fprintf(stdout, "DIMENSION %s '' absolute 1 1 noreset\n", w->name);
2584 + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
2585 }
2586
2587 fprintf(stdout, "CHART %s.sockets '' '%s Open Sockets' 'open sockets' net %s.sockets stacked 20051 %d\n", type, title, type, update_every);
2588 for (w = root; w ; w = w->next) {
2589 if(w->target || (!w->processes && !w->exposed)) continue;
2590
2336 - fprintf(stdout, "DIMENSION %s '' absolute 1 1 noreset\n", w->name);
2591 + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
2592 }
2593
2594 fprintf(stdout, "CHART %s.pipes '' '%s Pipes' 'open pipes' processes %s.pipes stacked 20053 %d\n", type, title, type, update_every);
2595 for (w = root; w ; w = w->next) {
2596 if(w->target || (!w->processes && !w->exposed)) continue;
2597
2343 - fprintf(stdout, "DIMENSION %s '' absolute 1 1 noreset\n", w->name);
2598 + fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
2599 }
2600 }
2601
@@ -2457,14 +2712,34 @@ int main(int argc, char **argv)
2712 exit(1);
2713 }
2714
2460 - fprintf(stdout, "CHART netdata.apps_cpu '' 'Apps Plugin CPU' 'milliseconds/s' apps.plugin netdata.apps_cpu stacked 140000 %1$d\n"
2461 - "DIMENSION user '' incremental 1 1000\n"
2462 - "DIMENSION system '' incremental 1 1000\n"
2463 - "CHART netdata.apps_files '' 'Apps Plugin Files' 'files/s' apps.plugin netdata.apps_files line 140001 %1$d\n"
2464 - "DIMENSION files '' incremental 1 1\n"
2465 - "DIMENSION pids '' absolute 1 1\n"
2466 - "DIMENSION fds '' absolute 1 1\n"
2467 - "DIMENSION targets '' absolute 1 1\n", update_every);
2715 + fprintf(stdout,
2716 + "CHART netdata.apps_cpu '' 'Apps Plugin CPU' 'milliseconds/s' apps.plugin netdata.apps_cpu stacked 140000 %1$d\n"
2717 + "DIMENSION user '' incremental 1 1000\n"
2718 + "DIMENSION system '' incremental 1 1000\n"
2719 + "CHART netdata.apps_files '' 'Apps Plugin Files' 'files/s' apps.plugin netdata.apps_files line 140001 %1$d\n"
2720 + "DIMENSION files '' incremental 1 1\n"
2721 + "DIMENSION pids '' absolute 1 1\n"
2722 + "DIMENSION fds '' absolute 1 1\n"
2723 + "DIMENSION targets '' absolute 1 1\n"
2724 + "CHART netdata.apps_fix '' 'Apps Plugin Normalization Ratios' 'percentage' apps.plugin netdata.apps_fix line 140002 %1$d\n"
2725 + "DIMENSION utime '' absolute 1 %2$llu\n"
2726 + "DIMENSION stime '' absolute 1 %2$llu\n"
2727 + "DIMENSION minflt '' absolute 1 %2$llu\n"
2728 + "DIMENSION majflt '' absolute 1 %2$llu\n"
2729 + , update_every
2730 + , RATES_DETAIL
2731 + );
2732 +
2733 + if(include_exited_childs)
2734 + fprintf(stdout,
2735 + "CHART netdata.apps_children_fix '' 'Apps Plugin Exited Children Normalization Ratios' 'percentage' apps.plugin netdata.apps_children_fix line 140003 %1$d\n"
2736 + "DIMENSION cutime '' absolute 1 %2$llu\n"
2737 + "DIMENSION cstime '' absolute 1 %2$llu\n"
2738 + "DIMENSION cminflt '' absolute 1 %2$llu\n"
2739 + "DIMENSION cmajflt '' absolute 1 %2$llu\n"
2740 + , update_every
2741 + , RATES_DETAIL
2742 + );
2743
2744 #ifndef PROFILING_MODE
2745 unsigned long long sunext = (time(NULL) - (time(NULL) % update_every) + update_every) * 1000000ULL;
@@ -2490,6 +2765,7 @@ int main(int argc, char **argv)
2765 }
2766
2767 calculate_netdata_statistics();
2768 + normalize_data(apps_groups_root_target);
2769
2770 unsigned long long dt = send_resource_usage_to_netdata();
2771