@cryptotaxi247 / netdata-1 / commits / b6e836c47

properly use guest values in all CPU charts; host CPU charts substract guest from user and guest_nice from nice; application, users and user groups cpu charts now take into account guest and children guest (substracted from user time); fixes #729

Costa Tsaousis committed Jul 26, 2016 at 22:20 UTC b6e836c4781a98c7d379acd5f8ca61c575560342
2 files changed +138 -43
src/apps_plugin.c
+129 -41
@@ -152,8 +152,10 @@ struct target {
152 unsigned long long cmajflt;
153 unsigned long long utime;
154 unsigned long long stime;
155 + unsigned long long gtime;
156 unsigned long long cutime;
157 unsigned long long cstime;
158 + unsigned long long cgtime;
159 unsigned long long num_threads;
160 unsigned long long rss;
161
@@ -461,8 +463,10 @@ struct pid_stat {
463 unsigned long long cmajflt_raw;
464 unsigned long long utime_raw;
465 unsigned long long stime_raw;
466 + unsigned long long gtime_raw; // guest_time
467 unsigned long long cutime_raw;
468 unsigned long long cstime_raw;
469 + unsigned long long cgtime_raw; // cguest_time
470
471 // these are rates
472 unsigned long long minflt;
@@ -471,8 +475,10 @@ struct pid_stat {
475 unsigned long long cmajflt;
476 unsigned long long utime;
477 unsigned long long stime;
478 + unsigned long long gtime;
479 unsigned long long cutime;
480 unsigned long long cstime;
481 + unsigned long long cgtime;
482
483 // int64_t priority;
484 // int64_t nice;
@@ -499,8 +505,6 @@ struct pid_stat {
505 // uint32_t rt_priority;
506 // uint32_t policy;
507 // unsigned long long delayacct_blkio_ticks;
502 - // uint64_t guest_time;
503 - // int64_t cguest_time;
508
509 uid_t uid;
510 gid_t gid;
@@ -772,8 +776,11 @@ int read_proc_pid_stat(struct pid_stat *p) {
776 // p->rt_priority = strtoul(procfile_lineword(ff, 0, 39+i), NULL, 10);
777 // p->policy = strtoul(procfile_lineword(ff, 0, 40+i), NULL, 10);
778 // p->delayacct_blkio_ticks = strtoull(procfile_lineword(ff, 0, 41+i), NULL, 10);
775 - // p->guest_time = strtoull(procfile_lineword(ff, 0, 42+i), NULL, 10);
776 - // p->cguest_time = strtoull(procfile_lineword(ff, 0, 43), NULL, 10);
779 + p->gtime_raw = strtoull(procfile_lineword(ff, 0, 42+i), NULL, 10);
780 + p->cgtime_raw = strtoull(procfile_lineword(ff, 0, 43+i), NULL, 10);
781 +
782 + p->utime_raw -= p->gtime_raw;
783 + p->cutime_raw -= p->cgtime_raw;
784
785 if(unlikely(debug || (p->target && p->target->debug)))
786 fprintf(stderr, "apps.plugin: READ PROC/PID/STAT: %s/proc/%d/stat, process: '%s' on target '%s' (dt=%llu) VALUES: utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu, threads=%d\n", host_prefix, p->pid, p->comm, (p->target)?p->target->name:"UNSET", p->stat_collected_usec - p->last_stat_collected_usec, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt, p->num_threads);
@@ -785,8 +792,10 @@ int read_proc_pid_stat(struct pid_stat *p) {
792 p->cmajflt = 0;
793 p->utime = 0;
794 p->stime = 0;
795 + p->gtime = 0;
796 p->cutime = 0;
797 p->cstime = 0;
798 + p->cgtime = 0;
799 }
800
801 return 0;
@@ -798,8 +807,10 @@ cleanup:
807 p->cmajflt = 0;
808 p->utime = 0;
809 p->stime = 0;
810 + p->gtime = 0;
811 p->cutime = 0;
812 p->cstime = 0;
813 + p->cgtime = 0;
814 p->num_threads = 0;
815 p->rss = 0;
816 return 1;
@@ -921,11 +932,12 @@ cleanup:
932
933 unsigned long long global_utime = 0;
934 unsigned long long global_stime = 0;
935 +unsigned long long global_gtime = 0;
936
937 int read_proc_stat() {
938 static char filename[FILENAME_MAX + 1] = "";
939 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;
940 + static unsigned long long utime_raw = 0, stime_raw = 0, gtime_raw = 0, ntime_raw = 0, collected_usec = 0, last_collected_usec = 0;
941
942 if(unlikely(!ff)) {
943 snprintfz(filename, FILENAME_MAX, "%s/proc/stat", host_prefix);
@@ -955,9 +967,14 @@ int read_proc_stat() {
967 stime_raw = strtoull(procfile_lineword(ff, 0, 3), NULL, 10);
968 global_stime = (stime_raw - last) * (1000000ULL * RATES_DETAIL) / (collected_usec - last_collected_usec);
969
970 + last = gtime_raw;
971 + gtime_raw = strtoull(procfile_lineword(ff, 0, 3), NULL, 10);
972 + global_gtime = (gtime_raw - last) * (1000000ULL * RATES_DETAIL) / (collected_usec - last_collected_usec);
973 +
974 if(unlikely(global_iterations_counter == 1)) {
975 global_utime = 0;
976 global_stime = 0;
977 + global_gtime = 0;
978 }
979
980 return 0;
@@ -965,6 +982,7 @@ int read_proc_stat() {
982 cleanup:
983 global_utime = 0;
984 global_stime = 0;
985 + global_gtime = 0;
986 return 1;
987 }
988
@@ -1313,9 +1331,11 @@ int print_process_and_parents(struct pid_stat *p, unsigned long long time) {
1331 );
1332
1333 if(p->utime) fprintf(stderr, " utime=%llu", p->utime);
1316 - if(p->cutime) fprintf(stderr, " cutime=%llu", p->cutime);
1334 if(p->stime) fprintf(stderr, " stime=%llu", p->stime);
1335 + if(p->gtime) fprintf(stderr, " gtime=%llu", p->gtime);
1336 + if(p->cutime) fprintf(stderr, " cutime=%llu", p->cutime);
1337 if(p->cstime) fprintf(stderr, " cstime=%llu", p->cstime);
1338 + if(p->cgtime) fprintf(stderr, " cgtime=%llu", p->cgtime);
1339 if(p->minflt) fprintf(stderr, " minflt=%llu", p->minflt);
1340 if(p->cminflt) fprintf(stderr, " cminflt=%llu", p->cminflt);
1341 if(p->majflt) fprintf(stderr, " majflt=%llu", p->majflt);
@@ -1359,13 +1379,20 @@ void find_lost_child_debug(struct pid_stat *pe, unsigned long long lost, int typ
1379 found++;
1380 }
1381 break;
1362 -
1382 +
1383 case 4:
1384 if(p->cstime > lost) {
1385 fprintf(stderr, " > process %d (%s) could use the lost exited child stime %llu of process %d (%s)\n", p->pid, p->comm, lost, pe->pid, pe->comm);
1386 found++;
1387 }
1388 break;
1389 +
1390 + case 5:
1391 + if(p->cgtime > lost) {
1392 + fprintf(stderr, " > process %d (%s) could use the lost exited child gtime %llu of process %d (%s)\n", p->pid, p->comm, lost, pe->pid, pe->comm);
1393 + found++;
1394 + }
1395 + break;
1396 }
1397 }
1398
@@ -1382,10 +1409,14 @@ void find_lost_child_debug(struct pid_stat *pe, unsigned long long lost, int typ
1409 case 3:
1410 fprintf(stderr, " > cannot find any process to use the lost exited child utime %llu of process %d (%s)\n", lost, pe->pid, pe->comm);
1411 break;
1385 -
1412 +
1413 case 4:
1414 fprintf(stderr, " > cannot find any process to use the lost exited child stime %llu of process %d (%s)\n", lost, pe->pid, pe->comm);
1415 break;
1416 +
1417 + case 5:
1418 + fprintf(stderr, " > cannot find any process to use the lost exited child gtime %llu of process %d (%s)\n", lost, pe->pid, pe->comm);
1419 + break;
1420 }
1421 }
1422 }
@@ -1418,20 +1449,22 @@ void process_exited_processes() {
1449
1450 unsigned long long utime = (p->utime_raw + p->cutime_raw) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
1451 unsigned long long stime = (p->stime_raw + p->cstime_raw) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
1452 + unsigned long long gtime = (p->gtime_raw + p->cgtime_raw) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
1453 unsigned long long minflt = (p->minflt_raw + p->cminflt_raw) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
1454 unsigned long long majflt = (p->majflt_raw + p->cmajflt_raw) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
1455
1424 - if(utime + stime + minflt + majflt == 0)
1456 + if(utime + stime + gtime + minflt + majflt == 0)
1457 continue;
1458
1459 if(unlikely(debug)) {
1460 log_date(stderr);
1429 - fprintf(stderr, "Absorb %s (%d %s total resources: utime=%llu stime=%llu minflt=%llu majflt=%llu)\n"
1461 + fprintf(stderr, "Absorb %s (%d %s total resources: utime=%llu stime=%llu gtime=%llu minflt=%llu majflt=%llu)\n"
1462 , p->comm
1463 , p->pid
1464 , p->updated?"running":"exited"
1465 , utime
1466 , stime
1467 + , gtime
1468 , minflt
1469 , majflt
1470 );
@@ -1450,6 +1483,10 @@ void process_exited_processes() {
1483 if(unlikely(debug && absorbed))
1484 fprintf(stderr, " > process %s (%d %s) absorbed %llu stime (remaining: %llu)\n", pp->comm, pp->pid, pp->updated?"running":"exited", absorbed, stime);
1485
1486 + absorbed = remove_exited_child_from_parent(&gtime, &pp->cgtime);
1487 + if(unlikely(debug && absorbed))
1488 + fprintf(stderr, " > process %s (%d %s) absorbed %llu gtime (remaining: %llu)\n", pp->comm, pp->pid, pp->updated?"running":"exited", absorbed, gtime);
1489 +
1490 absorbed = remove_exited_child_from_parent(&minflt, &pp->cminflt);
1491 if(unlikely(debug && absorbed))
1492 fprintf(stderr, " > process %s (%d %s) absorbed %llu minflt (remaining: %llu)\n", pp->comm, pp->pid, pp->updated?"running":"exited", absorbed, minflt);
@@ -1459,10 +1496,11 @@ void process_exited_processes() {
1496 fprintf(stderr, " > process %s (%d %s) absorbed %llu majflt (remaining: %llu)\n", pp->comm, pp->pid, pp->updated?"running":"exited", absorbed, majflt);
1497 }
1498
1462 - if(unlikely(utime + stime + minflt + majflt > 0)) {
1499 + if(unlikely(utime + stime + gtime + minflt + majflt > 0)) {
1500 if(unlikely(debug)) {
1501 if(utime) find_lost_child_debug(p, utime, 3);
1502 if(stime) find_lost_child_debug(p, stime, 4);
1503 + if(gtime) find_lost_child_debug(p, gtime, 5);
1504 if(minflt) find_lost_child_debug(p, minflt, 1);
1505 if(majflt) find_lost_child_debug(p, majflt, 2);
1506 }
@@ -1470,12 +1508,13 @@ void process_exited_processes() {
1508 p->keep = 1;
1509
1510 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"
1511 + fprintf(stderr, " > remaining resources - KEEP - for another loop: %s (%d %s total resources: utime=%llu stime=%llu gtime=%llu minflt=%llu majflt=%llu)\n"
1512 , p->comm
1513 , p->pid
1514 , p->updated?"running":"exited"
1515 , utime
1516 , stime
1517 + , gtime
1518 , minflt
1519 , majflt
1520 );
@@ -1494,9 +1533,10 @@ void process_exited_processes() {
1533
1534 p->utime_raw = utime * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000ULL * RATES_DETAIL);
1535 p->stime_raw = stime * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000ULL * RATES_DETAIL);
1536 + p->gtime_raw = gtime * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000ULL * RATES_DETAIL);
1537 p->minflt_raw = minflt * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000ULL * RATES_DETAIL);
1538 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;
1539 + p->cutime_raw = p->cstime_raw = p->cgtime_raw = p->cminflt_raw = p->cmajflt_raw = 0;
1540
1541 if(unlikely(debug))
1542 fprintf(stderr, "\n");
@@ -1533,7 +1573,7 @@ void link_all_processes_to_their_parents(void) {
1573 pp->children_count++;
1574
1575 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);
1576 + fprintf(stderr, "apps.plugin: \tchild %d (%s, %s) on target '%s' has parent %d (%s, %s). Parent: utime=%llu, stime=%llu, gtime=%llu, minflt=%llu, majflt=%llu, cutime=%llu, cstime=%llu, cgtime=%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->gtime, pp->minflt, pp->majflt, pp->cutime, pp->cstime, pp->cgtime, pp->cminflt, pp->cmajflt);
1577 }
1578 else {
1579 p->parent = NULL;
@@ -1766,7 +1806,7 @@ void cleanup_exited_pids(void) {
1806
1807 for(p = root_of_pids; p ;) {
1808 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);
1809 +// fprintf(stderr, "\tEXITED %d %s [parent %d %s, target %s] utime=%llu, stime=%llu, gtime=%llu, cutime=%llu, cstime=%llu, cgtime=%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->gtime, p->cutime, p->cstime, p->cgtime, p->minflt, p->majflt, p->cminflt, p->cmajflt);
1810
1811 if(unlikely(debug && (p->keep || p->keeploops)))
1812 fprintf(stderr, " > CLEANUP cannot keep exited process %d (%s) anymore - removing it.\n", p->pid, p->comm);
@@ -1912,10 +1952,12 @@ long zero_all_targets(struct target *root) {
1952 w->majflt = 0;
1953 w->utime = 0;
1954 w->stime = 0;
1955 + w->gtime = 0;
1956 w->cminflt = 0;
1957 w->cmajflt = 0;
1958 w->cutime = 0;
1959 w->cstime = 0;
1960 + w->cgtime = 0;
1961 w->num_threads = 0;
1962 w->rss = 0;
1963 w->processes = 0;
@@ -1952,11 +1994,13 @@ void aggregate_pid_on_target(struct target *w, struct pid_stat *p, struct target
1994 if(likely(p->updated)) {
1995 w->cutime += p->cutime;
1996 w->cstime += p->cstime;
1997 + w->cgtime += p->cgtime;
1998 w->cminflt += p->cminflt;
1999 w->cmajflt += p->cmajflt;
2000
2001 w->utime += p->utime;
2002 w->stime += p->stime;
2003 + w->gtime += p->gtime;
2004 w->minflt += p->minflt;
2005 w->majflt += p->majflt;
2006
@@ -1995,7 +2039,7 @@ void aggregate_pid_on_target(struct target *w, struct pid_stat *p, struct target
2039 }
2040
2041 if(unlikely(debug || w->debug))
1998 - fprintf(stderr, "apps.plugin: \taggregating '%s' pid %d on target '%s' utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->comm, p->pid, w->name, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);
2042 + fprintf(stderr, "apps.plugin: \taggregating '%s' pid %d on target '%s' utime=%llu, stime=%llu, gtime=%llu, cutime=%llu, cstime=%llu, cgtime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->comm, p->pid, w->name, p->utime, p->stime, p->gtime, p->cutime, p->cstime, p->cgtime, p->minflt, p->majflt, p->cminflt, p->cmajflt);
2043 }
2044 }
2045
@@ -2130,7 +2174,7 @@ void calculate_netdata_statistics(void) {
2174 // ----------------------------------------------------------------------------
2175 // update chart dimensions
2176
2133 -double utime_fix_ratio = 1.0, stime_fix_ratio = 1.0, cutime_fix_ratio = 1.0, cstime_fix_ratio = 1.0;
2177 +double utime_fix_ratio = 1.0, stime_fix_ratio = 1.0, gtime_fix_ratio = 1.0, cutime_fix_ratio = 1.0, cstime_fix_ratio = 1.0, cgtime_fix_ratio = 1.0;
2178 double minflt_fix_ratio = 1.0, majflt_fix_ratio = 1.0, cminflt_fix_ratio = 1.0, cmajflt_fix_ratio = 1.0;
2179
2180 unsigned long long send_resource_usage_to_netdata() {
@@ -2181,6 +2225,7 @@ unsigned long long send_resource_usage_to_netdata() {
2225 "BEGIN netdata.apps_fix %llu\n"
2226 "SET utime = %llu\n"
2227 "SET stime = %llu\n"
2228 + "SET gtime = %llu\n"
2229 "SET minflt = %llu\n"
2230 "SET majflt = %llu\n"
2231 "END\n"
@@ -2195,6 +2240,7 @@ unsigned long long send_resource_usage_to_netdata() {
2240 , usec
2241 , (unsigned long long)(utime_fix_ratio * 100 * RATES_DETAIL)
2242 , (unsigned long long)(stime_fix_ratio * 100 * RATES_DETAIL)
2243 + , (unsigned long long)(gtime_fix_ratio * 100 * RATES_DETAIL)
2244 , (unsigned long long)(minflt_fix_ratio * 100 * RATES_DETAIL)
2245 , (unsigned long long)(majflt_fix_ratio * 100 * RATES_DETAIL)
2246 );
@@ -2204,12 +2250,14 @@ unsigned long long send_resource_usage_to_netdata() {
2250 "BEGIN netdata.apps_children_fix %llu\n"
2251 "SET cutime = %llu\n"
2252 "SET cstime = %llu\n"
2253 + "SET cgtime = %llu\n"
2254 "SET cminflt = %llu\n"
2255 "SET cmajflt = %llu\n"
2256 "END\n"
2257 , usec
2258 , (unsigned long long)(cutime_fix_ratio * 100 * RATES_DETAIL)
2259 , (unsigned long long)(cstime_fix_ratio * 100 * RATES_DETAIL)
2260 + , (unsigned long long)(cgtime_fix_ratio * 100 * RATES_DETAIL)
2261 , (unsigned long long)(cminflt_fix_ratio * 100 * RATES_DETAIL)
2262 , (unsigned long long)(cmajflt_fix_ratio * 100 * RATES_DETAIL)
2263 );
@@ -2225,18 +2273,21 @@ void normalize_data(struct target *root) {
2273 // or entirely. Of course, either way, we disable it just a single iteration.
2274
2275 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;
2276 + unsigned long long utime = 0, cutime = 0, stime = 0, cstime = 0, gtime = 0, cgtime = 0, minflt = 0, cminflt = 0, majflt = 0, cmajflt = 0;
2277
2278 if(global_utime > max) global_utime = max;
2279 if(global_stime > max) global_stime = max;
2280 + if(global_gtime > max) global_gtime = max;
2281
2282 for(w = root; w ; w = w->next) {
2283 if(w->target || (!w->processes && !w->exposed)) continue;
2284
2285 utime += w->utime;
2286 stime += w->stime;
2287 + gtime += w->gtime;
2288 cutime += w->cutime;
2289 cstime += w->cstime;
2290 + cgtime += w->cgtime;
2291
2292 minflt += w->minflt;
2293 majflt += w->majflt;
@@ -2244,48 +2295,60 @@ void normalize_data(struct target *root) {
2295 cmajflt += w->cmajflt;
2296 }
2297
2247 - if((global_utime || global_stime) && (utime || stime)) {
2248 - if(global_utime + global_stime > utime + cutime + stime + cstime) {
2298 + if((global_utime || global_stime || global_gtime) && (utime || stime || gtime)) {
2299 + if(global_utime + global_stime + global_gtime > utime + cutime + stime + cstime + gtime + cgtime) {
2300 // everything we collected fits
2301 utime_fix_ratio =
2302 stime_fix_ratio =
2303 + gtime_fix_ratio =
2304 cutime_fix_ratio =
2253 - cstime_fix_ratio = 1.0; //(double)(global_utime + global_stime) / (double)(utime + cutime + stime + cstime);
2305 + cstime_fix_ratio =
2306 + cgtime_fix_ratio = 1.0; //(double)(global_utime + global_stime) / (double)(utime + cutime + stime + cstime);
2307 }
2308 else if(global_utime + global_stime > utime + stime) {
2309 // childrens resources are too high
2310 // lower only the children resources
2311 utime_fix_ratio =
2259 - stime_fix_ratio = 1.0;
2312 + stime_fix_ratio =
2313 + gtime_fix_ratio = 1.0;
2314 cutime_fix_ratio =
2261 - cstime_fix_ratio = (double)((global_utime + global_stime) - (utime + stime)) / (double)(cutime + cstime);
2315 + cstime_fix_ratio =
2316 + cgtime_fix_ratio = (double)((global_utime + global_stime) - (utime + stime)) / (double)(cutime + cstime);
2317 }
2318 else {
2319 // even running processes are unrealistic
2320 // zero the children resources
2321 // lower the running processes resources
2322 utime_fix_ratio =
2268 - stime_fix_ratio = (double)(global_utime + global_stime) / (double)(utime + stime);
2323 + stime_fix_ratio =
2324 + gtime_fix_ratio = (double)(global_utime + global_stime) / (double)(utime + stime);
2325 cutime_fix_ratio =
2270 - cstime_fix_ratio = 0.0;
2326 + cstime_fix_ratio =
2327 + cgtime_fix_ratio = 0.0;
2328 }
2329 }
2330 else {
2331 utime_fix_ratio =
2332 stime_fix_ratio =
2333 + gtime_fix_ratio =
2334 cutime_fix_ratio =
2277 - cstime_fix_ratio = 0.0;
2335 + cstime_fix_ratio =
2336 + cgtime_fix_ratio = 0.0;
2337 }
2338
2339 if(utime_fix_ratio > 1.0) utime_fix_ratio = 1.0;
2340 if(cutime_fix_ratio > 1.0) cutime_fix_ratio = 1.0;
2341 if(stime_fix_ratio > 1.0) stime_fix_ratio = 1.0;
2342 if(cstime_fix_ratio > 1.0) cstime_fix_ratio = 1.0;
2343 + if(gtime_fix_ratio > 1.0) gtime_fix_ratio = 1.0;
2344 + if(cgtime_fix_ratio > 1.0) cgtime_fix_ratio = 1.0;
2345
2346 // if(utime_fix_ratio < 0.0) utime_fix_ratio = 0.0;
2347 // if(cutime_fix_ratio < 0.0) cutime_fix_ratio = 0.0;
2348 // if(stime_fix_ratio < 0.0) stime_fix_ratio = 0.0;
2349 // if(cstime_fix_ratio < 0.0) cstime_fix_ratio = 0.0;
2350 + // if(gtime_fix_ratio < 0.0) gtime_fix_ratio = 0.0;
2351 + // if(cgtime_fix_ratio < 0.0) cgtime_fix_ratio = 0.0;
2352
2353 // FIXME
2354 // we use cpu time to normalize page faults
@@ -2296,46 +2359,54 @@ void normalize_data(struct target *root) {
2359 // a better solution could be to somehow have netdata
2360 // do this normalization for us
2361
2299 - if(cutime || cstime)
2300 - cmajflt_fix_ratio =
2301 - cminflt_fix_ratio = (double)(cutime * cutime_fix_ratio + cstime * cstime_fix_ratio) / (double)(cutime + cstime);
2302 - else
2303 - cminflt_fix_ratio =
2304 - cmajflt_fix_ratio = 1.0;
2305 -
2306 - if(utime || stime)
2362 + if(utime || stime || gtime)
2363 majflt_fix_ratio =
2308 - minflt_fix_ratio = (double)(utime * utime_fix_ratio + stime * stime_fix_ratio) / (double)(utime + stime);
2364 + minflt_fix_ratio = (double)(utime * utime_fix_ratio + stime * stime_fix_ratio + gtime * gtime_fix_ratio) / (double)(utime + stime + gtime);
2365 else
2366 minflt_fix_ratio =
2367 majflt_fix_ratio = 1.0;
2368
2369 + if(cutime || cstime || cgtime)
2370 + cmajflt_fix_ratio =
2371 + cminflt_fix_ratio = (double)(cutime * cutime_fix_ratio + cstime * cstime_fix_ratio + cgtime * cgtime_fix_ratio) / (double)(cutime + cstime + cgtime);
2372 + else
2373 + cminflt_fix_ratio =
2374 + cmajflt_fix_ratio = 1.0;
2375 +
2376 // the report
2377
2378 if(unlikely(debug)) {
2379 fprintf(stderr,
2317 - "SYSTEM: u=%llu s=%llu "
2318 - "COLLECTED: u=%llu s=%llu cu=%llu cs=%llu "
2319 - "DELTA: u=%lld s=%lld "
2320 - "FIX: u=%0.2f s=%0.2f cu=%0.2f cs=%0.2f "
2321 - "FINALLY: u=%llu s=%llu cu=%llu cs=%llu "
2380 + "SYSTEM: u=%llu s=%llu g=%llu "
2381 + "COLLECTED: u=%llu s=%llu g=%llu cu=%llu cs=%llu cg=%llu "
2382 + "DELTA: u=%lld s=%lld g=%lld "
2383 + "FIX: u=%0.2f s=%0.2f g=%0.2f cu=%0.2f cs=%0.2f cg=%0.2f "
2384 + "FINALLY: u=%llu s=%llu g=%llu cu=%llu cs=%llu cg=%llu "
2385 "\n"
2386 , global_utime
2387 , global_stime
2388 + , global_gtime
2389 , utime
2390 , stime
2391 + , gtime
2392 , cutime
2393 , cstime
2394 + , cgtime
2395 , (long long)utime + (long long)cutime - (long long)global_utime
2396 , (long long)stime + (long long)cstime - (long long)global_stime
2397 + , (long long)gtime + (long long)cgtime - (long long)global_gtime
2398 , utime_fix_ratio
2399 , stime_fix_ratio
2400 + , gtime_fix_ratio
2401 , cutime_fix_ratio
2402 , cstime_fix_ratio
2403 + , cgtime_fix_ratio
2404 , (unsigned long long)(utime * utime_fix_ratio)
2405 , (unsigned long long)(stime * stime_fix_ratio)
2406 + , (unsigned long long)(gtime * gtime_fix_ratio)
2407 , (unsigned long long)(cutime * cutime_fix_ratio)
2408 , (unsigned long long)(cstime * cstime_fix_ratio)
2409 + , (unsigned long long)(cgtime * cgtime_fix_ratio)
2410 );
2411 }
2412 }
@@ -2347,7 +2418,7 @@ void send_collected_data_to_netdata(struct target *root, const char *type, unsig
2418 for (w = root; w ; w = w->next) {
2419 if(w->target || (!w->processes && !w->exposed)) continue;
2420
2350 - 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));
2421 + fprintf(stdout, "SET %s = %llu\n", w->name, (unsigned long long)(w->utime * utime_fix_ratio) + (unsigned long long)(w->stime * stime_fix_ratio) + (unsigned long long)(w->gtime * gtime_fix_ratio) + (include_exited_childs?((unsigned long long)(w->cutime * cutime_fix_ratio) + (unsigned long long)(w->cstime * cstime_fix_ratio) + (unsigned long long)(w->cgtime * cgtime_fix_ratio)):0ULL));
2422 }
2423 fprintf(stdout, "END\n");
2424
@@ -2367,6 +2438,14 @@ void send_collected_data_to_netdata(struct target *root, const char *type, unsig
2438 }
2439 fprintf(stdout, "END\n");
2440
2441 + fprintf(stdout, "BEGIN %s.cpu_guest %llu\n", type, usec);
2442 + for (w = root; w ; w = w->next) {
2443 + if(w->target || (!w->processes && !w->exposed)) continue;
2444 +
2445 + fprintf(stdout, "SET %s = %llu\n", w->name, (unsigned long long)(w->gtime * gtime_fix_ratio) + (include_exited_childs?((unsigned long long)(w->cgtime * cgtime_fix_ratio)):0ULL));
2446 + }
2447 + fprintf(stdout, "END\n");
2448 +
2449 fprintf(stdout, "BEGIN %s.threads %llu\n", type, usec);
2450 for (w = root; w ; w = w->next) {
2451 if(w->target || (!w->processes && !w->exposed)) continue;
@@ -2529,6 +2608,13 @@ void send_charts_updates_to_netdata(struct target *root, const char *type, const
2608 fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, hz * RATES_DETAIL / 100LLU);
2609 }
2610
2611 + fprintf(stdout, "CHART %s.cpu_guest '' '%s CPU Guest Time (%d%% = %d core%s)' 'cpu time %%' cpu %s.cpu_system stacked 20022 %d\n", type, title, (processors * 100), processors, (processors>1)?"s":"", type, update_every);
2612 + for (w = root; w ; w = w->next) {
2613 + if(w->target || (!w->processes && !w->exposed)) continue;
2614 +
2615 + fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, hz * RATES_DETAIL / 100LLU);
2616 + }
2617 +
2618 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);
2619 for (w = root; w ; w = w->next) {
2620 if(w->target || (!w->processes && !w->exposed)) continue;
@@ -2718,6 +2804,7 @@ int main(int argc, char **argv)
2804 "CHART netdata.apps_fix '' 'Apps Plugin Normalization Ratios' 'percentage' apps.plugin netdata.apps_fix line 140002 %1$d\n"
2805 "DIMENSION utime '' absolute 1 %2$llu\n"
2806 "DIMENSION stime '' absolute 1 %2$llu\n"
2807 + "DIMENSION gtime '' absolute 1 %2$llu\n"
2808 "DIMENSION minflt '' absolute 1 %2$llu\n"
2809 "DIMENSION majflt '' absolute 1 %2$llu\n"
2810 , update_every
@@ -2729,6 +2816,7 @@ int main(int argc, char **argv)
2816 "CHART netdata.apps_children_fix '' 'Apps Plugin Exited Children Normalization Ratios' 'percentage' apps.plugin netdata.apps_children_fix line 140003 %1$d\n"
2817 "DIMENSION cutime '' absolute 1 %2$llu\n"
2818 "DIMENSION cstime '' absolute 1 %2$llu\n"
2819 + "DIMENSION cgtime '' absolute 1 %2$llu\n"
2820 "DIMENSION cminflt '' absolute 1 %2$llu\n"
2821 "DIMENSION cmajflt '' absolute 1 %2$llu\n"
2822 , update_every
src/proc_stat.c
+9 -2
@@ -74,8 +74,15 @@ int do_proc_stat(int update_every, unsigned long long dt) {
74 irq = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
75 softirq = strtoull(procfile_lineword(ff, l, 7), NULL, 10);
76 steal = strtoull(procfile_lineword(ff, l, 8), NULL, 10);
77 - if(words >= 10) guest = strtoull(procfile_lineword(ff, l, 9), NULL, 10);
78 - if(words >= 11) guest_nice = strtoull(procfile_lineword(ff, l, 10), NULL, 10);
77 +
78 + if(words >= 10) {
79 + guest = strtoull(procfile_lineword(ff, l, 9), NULL, 10);
80 + user -= guest;
81 + }
82 + if(words >= 11) {
83 + guest_nice = strtoull(procfile_lineword(ff, l, 10), NULL, 10);
84 + nice -= guest_nice;
85 + }
86
87 char *title, *type, *context, *family;
88 long priority;