]> arthur.barton.de Git - netdata.git/commitdiff
properly use guest values in all CPU charts; host CPU charts substract guest from...
authorCosta Tsaousis <costa@tsaousis.gr>
Tue, 26 Jul 2016 19:20:28 +0000 (22:20 +0300)
committerCosta Tsaousis <costa@tsaousis.gr>
Tue, 26 Jul 2016 19:20:28 +0000 (22:20 +0300)
src/apps_plugin.c
src/proc_stat.c

index 8cd2ef122d4c04566076590a3882c1f510550dd0..8346635c9c9d3f5b3406f02979ea4546bb4c1791 100644 (file)
@@ -152,8 +152,10 @@ struct target {
        unsigned long long cmajflt;
        unsigned long long utime;
        unsigned long long stime;
+       unsigned long long gtime;
        unsigned long long cutime;
        unsigned long long cstime;
+       unsigned long long cgtime;
        unsigned long long num_threads;
        unsigned long long rss;
 
@@ -461,8 +463,10 @@ struct pid_stat {
        unsigned long long cmajflt_raw;
        unsigned long long utime_raw;
        unsigned long long stime_raw;
+       unsigned long long gtime_raw; // guest_time
        unsigned long long cutime_raw;
        unsigned long long cstime_raw;
+       unsigned long long cgtime_raw; // cguest_time
 
        // these are rates
        unsigned long long minflt;
@@ -471,8 +475,10 @@ struct pid_stat {
        unsigned long long cmajflt;
        unsigned long long utime;
        unsigned long long stime;
+       unsigned long long gtime;
        unsigned long long cutime;
        unsigned long long cstime;
+       unsigned long long cgtime;
 
        // int64_t priority;
        // int64_t nice;
@@ -499,8 +505,6 @@ struct pid_stat {
        // uint32_t rt_priority;
        // uint32_t policy;
        // unsigned long long delayacct_blkio_ticks;
-       // uint64_t guest_time;
-       // int64_t cguest_time;
 
        uid_t uid;
        gid_t gid;
@@ -772,8 +776,11 @@ int read_proc_pid_stat(struct pid_stat *p) {
        // p->rt_priority       = strtoul(procfile_lineword(ff, 0, 39+i), NULL, 10);
        // p->policy            = strtoul(procfile_lineword(ff, 0, 40+i), NULL, 10);
        // p->delayacct_blkio_ticks             = strtoull(procfile_lineword(ff, 0, 41+i), NULL, 10);
-       // p->guest_time        = strtoull(procfile_lineword(ff, 0, 42+i), NULL, 10);
-       // p->cguest_time       = strtoull(procfile_lineword(ff, 0, 43), NULL, 10);
+       p->gtime_raw            = strtoull(procfile_lineword(ff, 0, 42+i), NULL, 10);
+       p->cgtime_raw           = strtoull(procfile_lineword(ff, 0, 43+i), NULL, 10);
+
+       p->utime_raw  -= p->gtime_raw;
+       p->cutime_raw -= p->cgtime_raw;
 
        if(unlikely(debug || (p->target && p->target->debug)))
                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) {
                p->cmajflt                      = 0;
                p->utime                        = 0;
                p->stime                        = 0;
+               p->gtime                        = 0;
                p->cutime                       = 0;
                p->cstime                       = 0;
+               p->cgtime                       = 0;
        }
 
        return 0;
@@ -798,8 +807,10 @@ cleanup:
        p->cmajflt                      = 0;
        p->utime                        = 0;
        p->stime                        = 0;
+       p->gtime                        = 0;
        p->cutime                       = 0;
        p->cstime                       = 0;
+       p->cgtime                       = 0;
        p->num_threads          = 0;
        p->rss                          = 0;
        return 1;
@@ -921,11 +932,12 @@ cleanup:
 
 unsigned long long global_utime = 0;
 unsigned long long global_stime = 0;
+unsigned long long global_gtime = 0;
 
 int read_proc_stat() {
        static char filename[FILENAME_MAX + 1] = "";
        static procfile *ff = NULL;
-       static unsigned long long utime_raw = 0, stime_raw = 0, ntime_raw = 0, collected_usec = 0, last_collected_usec = 0;
+       static unsigned long long utime_raw = 0, stime_raw = 0, gtime_raw = 0, ntime_raw = 0, collected_usec = 0, last_collected_usec = 0;
 
        if(unlikely(!ff)) {
                snprintfz(filename, FILENAME_MAX, "%s/proc/stat", host_prefix);
@@ -955,9 +967,14 @@ int read_proc_stat() {
        stime_raw = strtoull(procfile_lineword(ff, 0, 3), NULL, 10);
        global_stime = (stime_raw - last) * (1000000ULL * RATES_DETAIL) / (collected_usec - last_collected_usec);
 
+       last = gtime_raw;
+       gtime_raw = strtoull(procfile_lineword(ff, 0, 3), NULL, 10);
+       global_gtime = (gtime_raw - last) * (1000000ULL * RATES_DETAIL) / (collected_usec - last_collected_usec);
+
        if(unlikely(global_iterations_counter == 1)) {
                global_utime = 0;
                global_stime = 0;
+               global_gtime = 0;
        }
 
        return 0;
@@ -965,6 +982,7 @@ int read_proc_stat() {
 cleanup:
        global_utime = 0;
        global_stime = 0;
+       global_gtime = 0;
        return 1;
 }
 
@@ -1313,9 +1331,11 @@ int print_process_and_parents(struct pid_stat *p, unsigned long long time) {
                );
 
        if(p->utime)   fprintf(stderr, " utime=%llu",   p->utime);
-       if(p->cutime)  fprintf(stderr, " cutime=%llu",  p->cutime);
        if(p->stime)   fprintf(stderr, " stime=%llu",   p->stime);
+       if(p->gtime)   fprintf(stderr, " gtime=%llu",   p->gtime);
+       if(p->cutime)  fprintf(stderr, " cutime=%llu",  p->cutime);
        if(p->cstime)  fprintf(stderr, " cstime=%llu",  p->cstime);
+       if(p->cgtime)  fprintf(stderr, " cgtime=%llu",  p->cgtime);
        if(p->minflt)  fprintf(stderr, " minflt=%llu",  p->minflt);
        if(p->cminflt) fprintf(stderr, " cminflt=%llu", p->cminflt);
        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
                                        found++;
                                }
                                break;
-                               
+
                        case 4:
                                if(p->cstime > lost) {
                                        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);
                                        found++;
                                }
                                break;
+
+                       case 5:
+                               if(p->cgtime > lost) {
+                                       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);
+                                       found++;
+                               }
+                               break;
                }
        }
 
@@ -1382,10 +1409,14 @@ void find_lost_child_debug(struct pid_stat *pe, unsigned long long lost, int typ
                        case 3:
                                fprintf(stderr, " > cannot find any process to use the lost exited child utime %llu of process %d (%s)\n", lost, pe->pid, pe->comm);
                                break;
-                               
+
                        case 4:
                                fprintf(stderr, " > cannot find any process to use the lost exited child stime %llu of process %d (%s)\n", lost, pe->pid, pe->comm);
                                break;
+
+                       case 5:
+                               fprintf(stderr, " > cannot find any process to use the lost exited child gtime %llu of process %d (%s)\n", lost, pe->pid, pe->comm);
+                               break;
                }
        }
 }
@@ -1418,20 +1449,22 @@ void process_exited_processes() {
 
                unsigned long long utime  = (p->utime_raw + p->cutime_raw)   * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
                unsigned long long stime  = (p->stime_raw + p->cstime_raw)   * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
+               unsigned long long gtime  = (p->gtime_raw + p->cgtime_raw)   * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
                unsigned long long minflt = (p->minflt_raw + p->cminflt_raw) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
                unsigned long long majflt = (p->majflt_raw + p->cmajflt_raw) * (1000000ULL * RATES_DETAIL) / (p->stat_collected_usec - p->last_stat_collected_usec);
 
-               if(utime + stime + minflt + majflt == 0)
+               if(utime + stime + gtime + minflt + majflt == 0)
                        continue;
 
                if(unlikely(debug)) {
                        log_date(stderr);
-                       fprintf(stderr, "Absorb %s (%d %s total resources: utime=%llu stime=%llu minflt=%llu majflt=%llu)\n"
+                       fprintf(stderr, "Absorb %s (%d %s total resources: utime=%llu stime=%llu gtime=%llu minflt=%llu majflt=%llu)\n"
                                , p->comm
                                , p->pid
                                , p->updated?"running":"exited"
                                , utime
                                , stime
+                               , gtime
                                , minflt
                                , majflt
                                );
@@ -1450,6 +1483,10 @@ void process_exited_processes() {
                        if(unlikely(debug && absorbed))
                                fprintf(stderr, " > process %s (%d %s) absorbed %llu stime (remaining: %llu)\n", pp->comm, pp->pid, pp->updated?"running":"exited", absorbed, stime);
 
+                       absorbed = remove_exited_child_from_parent(&gtime,  &pp->cgtime);
+                       if(unlikely(debug && absorbed))
+                               fprintf(stderr, " > process %s (%d %s) absorbed %llu gtime (remaining: %llu)\n", pp->comm, pp->pid, pp->updated?"running":"exited", absorbed, gtime);
+
                        absorbed = remove_exited_child_from_parent(&minflt, &pp->cminflt);
                        if(unlikely(debug && absorbed))
                                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() {
                                fprintf(stderr, " > process %s (%d %s) absorbed %llu majflt (remaining: %llu)\n", pp->comm, pp->pid, pp->updated?"running":"exited", absorbed, majflt);
                }
 
-               if(unlikely(utime + stime + minflt + majflt > 0)) {
+               if(unlikely(utime + stime + gtime + minflt + majflt > 0)) {
                        if(unlikely(debug)) {
                                if(utime)  find_lost_child_debug(p, utime,  3);
                                if(stime)  find_lost_child_debug(p, stime,  4);
+                               if(gtime)  find_lost_child_debug(p, gtime,  5);
                                if(minflt) find_lost_child_debug(p, minflt, 1);
                                if(majflt) find_lost_child_debug(p, majflt, 2);
                        }
@@ -1470,12 +1508,13 @@ void process_exited_processes() {
                        p->keep = 1;
 
                        if(unlikely(debug))
-                               fprintf(stderr, " > remaining resources - KEEP - for another loop: %s (%d %s total resources: utime=%llu stime=%llu minflt=%llu majflt=%llu)\n"
+                               fprintf(stderr, " > remaining resources - KEEP - for another loop: %s (%d %s total resources: utime=%llu stime=%llu gtime=%llu minflt=%llu majflt=%llu)\n"
                                        , p->comm
                                        , p->pid
                                        , p->updated?"running":"exited"
                                        , utime
                                        , stime
+                                       , gtime
                                        , minflt
                                        , majflt
                                        );
@@ -1494,9 +1533,10 @@ void process_exited_processes() {
 
                        p->utime_raw   = utime  * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000ULL * RATES_DETAIL);
                        p->stime_raw   = stime  * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000ULL * RATES_DETAIL);
+                       p->gtime_raw   = gtime  * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000ULL * RATES_DETAIL);
                        p->minflt_raw  = minflt * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000ULL * RATES_DETAIL);
                        p->majflt_raw  = majflt * (p->stat_collected_usec - p->last_stat_collected_usec) / (1000000ULL * RATES_DETAIL);
-                       p->cutime_raw = p->cstime_raw = p->cminflt_raw = p->cmajflt_raw = 0;
+                       p->cutime_raw = p->cstime_raw = p->cgtime_raw = p->cminflt_raw = p->cmajflt_raw = 0;
 
                        if(unlikely(debug))
                                fprintf(stderr, "\n");
@@ -1533,7 +1573,7 @@ void link_all_processes_to_their_parents(void) {
                        pp->children_count++;
 
                        if(unlikely(debug || (p->target && p->target->debug)))
-                               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);
+                               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);
                }
                else {
                        p->parent = NULL;
@@ -1766,7 +1806,7 @@ void cleanup_exited_pids(void) {
 
        for(p = root_of_pids; p ;) {
                if(!p->updated && (!p->keep || p->keeploops > 0)) {
-//                     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);
+//                     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);
 
                        if(unlikely(debug && (p->keep || p->keeploops)))
                                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) {
                w->majflt = 0;
                w->utime = 0;
                w->stime = 0;
+               w->gtime = 0;
                w->cminflt = 0;
                w->cmajflt = 0;
                w->cutime = 0;
                w->cstime = 0;
+               w->cgtime = 0;
                w->num_threads = 0;
                w->rss = 0;
                w->processes = 0;
@@ -1952,11 +1994,13 @@ void aggregate_pid_on_target(struct target *w, struct pid_stat *p, struct target
        if(likely(p->updated)) {
                w->cutime  += p->cutime;
                w->cstime  += p->cstime;
+               w->cgtime  += p->cgtime;
                w->cminflt += p->cminflt;
                w->cmajflt += p->cmajflt;
 
                w->utime  += p->utime;
                w->stime  += p->stime;
+               w->gtime  += p->gtime;
                w->minflt += p->minflt;
                w->majflt += p->majflt;
 
@@ -1995,7 +2039,7 @@ void aggregate_pid_on_target(struct target *w, struct pid_stat *p, struct target
                }
 
                if(unlikely(debug || w->debug))
-                       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);
+                       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);
        }
 }
 
@@ -2130,7 +2174,7 @@ void calculate_netdata_statistics(void) {
 // ----------------------------------------------------------------------------
 // update chart dimensions
 
-double utime_fix_ratio = 1.0, stime_fix_ratio = 1.0, cutime_fix_ratio = 1.0, cstime_fix_ratio = 1.0;
+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;
 double minflt_fix_ratio = 1.0, majflt_fix_ratio = 1.0, cminflt_fix_ratio = 1.0, cmajflt_fix_ratio = 1.0;
 
 unsigned long long send_resource_usage_to_netdata() {
@@ -2181,6 +2225,7 @@ unsigned long long send_resource_usage_to_netdata() {
                "BEGIN netdata.apps_fix %llu\n"
                "SET utime = %llu\n"
                "SET stime = %llu\n"
+               "SET gtime = %llu\n"
                "SET minflt = %llu\n"
                "SET majflt = %llu\n"
                "END\n"
@@ -2195,6 +2240,7 @@ unsigned long long send_resource_usage_to_netdata() {
                , usec
                , (unsigned long long)(utime_fix_ratio   * 100 * RATES_DETAIL)
                , (unsigned long long)(stime_fix_ratio   * 100 * RATES_DETAIL)
+               , (unsigned long long)(gtime_fix_ratio   * 100 * RATES_DETAIL)
                , (unsigned long long)(minflt_fix_ratio  * 100 * RATES_DETAIL)
                , (unsigned long long)(majflt_fix_ratio  * 100 * RATES_DETAIL)
                );
@@ -2204,12 +2250,14 @@ unsigned long long send_resource_usage_to_netdata() {
                        "BEGIN netdata.apps_children_fix %llu\n"
                        "SET cutime = %llu\n"
                        "SET cstime = %llu\n"
+                       "SET cgtime = %llu\n"
                        "SET cminflt = %llu\n"
                        "SET cmajflt = %llu\n"
                        "END\n"
                        , usec
                        , (unsigned long long)(cutime_fix_ratio  * 100 * RATES_DETAIL)
                        , (unsigned long long)(cstime_fix_ratio  * 100 * RATES_DETAIL)
+                       , (unsigned long long)(cgtime_fix_ratio  * 100 * RATES_DETAIL)
                        , (unsigned long long)(cminflt_fix_ratio * 100 * RATES_DETAIL)
                        , (unsigned long long)(cmajflt_fix_ratio * 100 * RATES_DETAIL)
                        );
@@ -2225,18 +2273,21 @@ void normalize_data(struct target *root) {
        // or entirely. Of course, either way, we disable it just a single iteration.
 
        unsigned long long max = processors * hz * RATES_DETAIL;
-       unsigned long long utime = 0, cutime = 0, stime = 0, cstime = 0, minflt = 0, cminflt = 0, majflt = 0, cmajflt = 0;
+       unsigned long long utime = 0, cutime = 0, stime = 0, cstime = 0, gtime = 0, cgtime = 0, minflt = 0, cminflt = 0, majflt = 0, cmajflt = 0;
 
        if(global_utime > max) global_utime = max;
        if(global_stime > max) global_stime = max;
+       if(global_gtime > max) global_gtime = max;
 
        for(w = root; w ; w = w->next) {
                if(w->target || (!w->processes && !w->exposed)) continue;
 
                utime   += w->utime;
                stime   += w->stime;
+               gtime   += w->gtime;
                cutime  += w->cutime;
                cstime  += w->cstime;
+               cgtime  += w->cgtime;
 
                minflt  += w->minflt;
                majflt  += w->majflt;
@@ -2244,48 +2295,60 @@ void normalize_data(struct target *root) {
                cmajflt += w->cmajflt;
        }
 
-       if((global_utime || global_stime) && (utime || stime)) {
-               if(global_utime + global_stime > utime + cutime + stime + cstime) {
+       if((global_utime || global_stime || global_gtime) && (utime || stime || gtime)) {
+               if(global_utime + global_stime + global_gtime > utime + cutime + stime + cstime + gtime + cgtime) {
                        // everything we collected fits
                        utime_fix_ratio  =
                        stime_fix_ratio  =
+                       gtime_fix_ratio  =
                        cutime_fix_ratio =
-                       cstime_fix_ratio = 1.0; //(double)(global_utime + global_stime) / (double)(utime + cutime + stime + cstime);
+                       cstime_fix_ratio =
+                       cgtime_fix_ratio = 1.0; //(double)(global_utime + global_stime) / (double)(utime + cutime + stime + cstime);
                }
                else if(global_utime + global_stime > utime + stime) {
                        // childrens resources are too high
                        // lower only the children resources
                        utime_fix_ratio  =
-                       stime_fix_ratio  = 1.0;
+                       stime_fix_ratio  =
+                       gtime_fix_ratio  = 1.0;
                        cutime_fix_ratio =
-                       cstime_fix_ratio = (double)((global_utime + global_stime) - (utime + stime)) / (double)(cutime + cstime);
+                       cstime_fix_ratio =
+                       cgtime_fix_ratio = (double)((global_utime + global_stime) - (utime + stime)) / (double)(cutime + cstime);
                }
                else {
                        // even running processes are unrealistic
                        // zero the children resources
                        // lower the running processes resources
                        utime_fix_ratio  =
-                       stime_fix_ratio  = (double)(global_utime + global_stime) / (double)(utime + stime);
+                       stime_fix_ratio  =
+                       gtime_fix_ratio  = (double)(global_utime + global_stime) / (double)(utime + stime);
                        cutime_fix_ratio =
-                       cstime_fix_ratio = 0.0;
+                       cstime_fix_ratio =
+                       cgtime_fix_ratio = 0.0;
                }
        }
        else {
                utime_fix_ratio  =
                stime_fix_ratio  =
+               gtime_fix_ratio  =
                cutime_fix_ratio =
-               cstime_fix_ratio = 0.0;
+               cstime_fix_ratio =
+               cgtime_fix_ratio = 0.0;
        }
 
        if(utime_fix_ratio  > 1.0) utime_fix_ratio  = 1.0;
        if(cutime_fix_ratio > 1.0) cutime_fix_ratio = 1.0;
        if(stime_fix_ratio  > 1.0) stime_fix_ratio  = 1.0;
        if(cstime_fix_ratio > 1.0) cstime_fix_ratio = 1.0;
+       if(gtime_fix_ratio  > 1.0) gtime_fix_ratio  = 1.0;
+       if(cgtime_fix_ratio > 1.0) cgtime_fix_ratio = 1.0;
 
        // if(utime_fix_ratio  < 0.0) utime_fix_ratio  = 0.0;
        // if(cutime_fix_ratio < 0.0) cutime_fix_ratio = 0.0;
        // if(stime_fix_ratio  < 0.0) stime_fix_ratio  = 0.0;
        // if(cstime_fix_ratio < 0.0) cstime_fix_ratio = 0.0;
+       // if(gtime_fix_ratio  < 0.0) gtime_fix_ratio  = 0.0;
+       // if(cgtime_fix_ratio < 0.0) cgtime_fix_ratio = 0.0;
 
        // FIXME
        // we use cpu time to normalize page faults
@@ -2296,46 +2359,54 @@ void normalize_data(struct target *root) {
        // a better solution could be to somehow have netdata
        // do this normalization for us
 
-       if(cutime || cstime)
-               cmajflt_fix_ratio =
-               cminflt_fix_ratio = (double)(cutime * cutime_fix_ratio + cstime * cstime_fix_ratio) / (double)(cutime + cstime);
-       else
-               cminflt_fix_ratio =
-               cmajflt_fix_ratio = 1.0;
-
-       if(utime || stime)
+       if(utime || stime || gtime)
                majflt_fix_ratio =
-               minflt_fix_ratio = (double)(utime * utime_fix_ratio + stime * stime_fix_ratio) / (double)(utime + stime);
+               minflt_fix_ratio = (double)(utime * utime_fix_ratio + stime * stime_fix_ratio + gtime * gtime_fix_ratio) / (double)(utime + stime + gtime);
        else
                minflt_fix_ratio =
                majflt_fix_ratio = 1.0;
 
+       if(cutime || cstime || cgtime)
+               cmajflt_fix_ratio =
+               cminflt_fix_ratio = (double)(cutime * cutime_fix_ratio + cstime * cstime_fix_ratio + cgtime * cgtime_fix_ratio) / (double)(cutime + cstime + cgtime);
+       else
+               cminflt_fix_ratio =
+               cmajflt_fix_ratio = 1.0;
+
        // the report
 
        if(unlikely(debug)) {
                fprintf(stderr,
-                       "SYSTEM: u=%llu s=%llu "
-                       "COLLECTED: u=%llu s=%llu cu=%llu cs=%llu "
-                       "DELTA: u=%lld s=%lld "
-                       "FIX: u=%0.2f s=%0.2f cu=%0.2f cs=%0.2f "
-                       "FINALLY: u=%llu s=%llu cu=%llu cs=%llu "
+                       "SYSTEM: u=%llu s=%llu g=%llu "
+                       "COLLECTED: u=%llu s=%llu g=%llu cu=%llu cs=%llu cg=%llu "
+                       "DELTA: u=%lld s=%lld g=%lld "
+                       "FIX: u=%0.2f s=%0.2f g=%0.2f cu=%0.2f cs=%0.2f cg=%0.2f "
+                       "FINALLY: u=%llu s=%llu g=%llu cu=%llu cs=%llu cg=%llu "
                        "\n"
                        , global_utime
                        , global_stime
+                       , global_gtime
                        , utime
                        , stime
+                       , gtime
                        , cutime
                        , cstime
+                       , cgtime
                        , (long long)utime + (long long)cutime - (long long)global_utime
                        , (long long)stime + (long long)cstime - (long long)global_stime
+                       , (long long)gtime + (long long)cgtime - (long long)global_gtime
                        , utime_fix_ratio
                        , stime_fix_ratio
+                       , gtime_fix_ratio
                        , cutime_fix_ratio
                        , cstime_fix_ratio
+                       , cgtime_fix_ratio
                        , (unsigned long long)(utime * utime_fix_ratio)
                        , (unsigned long long)(stime * stime_fix_ratio)
+                       , (unsigned long long)(gtime * gtime_fix_ratio)
                        , (unsigned long long)(cutime * cutime_fix_ratio)
                        , (unsigned long long)(cstime * cstime_fix_ratio)
+                       , (unsigned long long)(cgtime * cgtime_fix_ratio)
                        );
        }
 }
@@ -2347,7 +2418,7 @@ void send_collected_data_to_netdata(struct target *root, const char *type, unsig
        for (w = root; w ; w = w->next) {
                if(w->target || (!w->processes && !w->exposed)) continue;
 
-               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));
+               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));
        }
        fprintf(stdout, "END\n");
 
@@ -2367,6 +2438,14 @@ void send_collected_data_to_netdata(struct target *root, const char *type, unsig
        }
        fprintf(stdout, "END\n");
 
+       fprintf(stdout, "BEGIN %s.cpu_guest %llu\n", type, usec);
+       for (w = root; w ; w = w->next) {
+               if(w->target || (!w->processes && !w->exposed)) continue;
+
+               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));
+       }
+       fprintf(stdout, "END\n");
+
        fprintf(stdout, "BEGIN %s.threads %llu\n", type, usec);
        for (w = root; w ; w = w->next) {
                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
                fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, hz * RATES_DETAIL / 100LLU);
        }
 
+       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);
+       for (w = root; w ; w = w->next) {
+               if(w->target || (!w->processes && !w->exposed)) continue;
+
+               fprintf(stdout, "DIMENSION %s '' absolute 1 %llu\n", w->name, hz * RATES_DETAIL / 100LLU);
+       }
+
        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);
        for (w = root; w ; w = w->next) {
                if(w->target || (!w->processes && !w->exposed)) continue;
@@ -2718,6 +2804,7 @@ int main(int argc, char **argv)
                "CHART netdata.apps_fix '' 'Apps Plugin Normalization Ratios' 'percentage' apps.plugin netdata.apps_fix line 140002 %1$d\n"
                "DIMENSION utime '' absolute 1 %2$llu\n"
                "DIMENSION stime '' absolute 1 %2$llu\n"
+               "DIMENSION gtime '' absolute 1 %2$llu\n"
                "DIMENSION minflt '' absolute 1 %2$llu\n"
                "DIMENSION majflt '' absolute 1 %2$llu\n"
                , update_every
@@ -2729,6 +2816,7 @@ int main(int argc, char **argv)
                        "CHART netdata.apps_children_fix '' 'Apps Plugin Exited Children Normalization Ratios' 'percentage' apps.plugin netdata.apps_children_fix line 140003 %1$d\n"
                        "DIMENSION cutime '' absolute 1 %2$llu\n"
                        "DIMENSION cstime '' absolute 1 %2$llu\n"
+                       "DIMENSION cgtime '' absolute 1 %2$llu\n"
                        "DIMENSION cminflt '' absolute 1 %2$llu\n"
                        "DIMENSION cmajflt '' absolute 1 %2$llu\n"
                        , update_every
index f96297941f776f073402be76db4a160bf813f951..13253f4e964084b136644af364c83f9559c4e344 100644 (file)
@@ -74,8 +74,15 @@ int do_proc_stat(int update_every, unsigned long long dt) {
                        irq                     = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
                        softirq         = strtoull(procfile_lineword(ff, l, 7), NULL, 10);
                        steal           = strtoull(procfile_lineword(ff, l, 8), NULL, 10);
-                       if(words >= 10) guest           = strtoull(procfile_lineword(ff, l, 9), NULL, 10);
-                       if(words >= 11) guest_nice      = strtoull(procfile_lineword(ff, l, 10), NULL, 10);
+
+                       if(words >= 10) {
+                               guest           = strtoull(procfile_lineword(ff, l, 9), NULL, 10);
+                               user -= guest;
+                       }
+                       if(words >= 11) {
+                               guest_nice      = strtoull(procfile_lineword(ff, l, 10), NULL, 10);
+                               nice -= guest_nice;
+                       }
 
                        char *title, *type, *context, *family;
                        long priority;