]> arthur.barton.de Git - netdata.git/commitdiff
removed child resource usage from counter, they were causing sudden spikes in charts...
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Wed, 7 May 2014 00:24:21 +0000 (03:24 +0300)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Wed, 7 May 2014 00:24:21 +0000 (03:24 +0300)
apps_plugin.c
netdata.c

index 11881c7988302b6baf1be84e94665f83f803830e..38b5f41bd1adc4e5c1cb4f9f1bed79d4bc6ee13c 100755 (executable)
@@ -25,8 +25,6 @@
 #define MAX_NAME 100\r
 \r
 \r
-#define add_childs 1ULL\r
-\r
 unsigned long long Hertz = 1;\r
 \r
 long pid_max = 32768;\r
@@ -168,7 +166,6 @@ struct pid_stat {
        int new_entry;\r
        unsigned long merge_count;\r
        struct wanted *target;\r
-       int target_inherited;\r
        struct pid_stat *parent;\r
        struct pid_stat *prev;\r
        struct pid_stat *next;\r
@@ -204,6 +201,8 @@ void del_entry(pid_t pid)
 {\r
        if(!all_pids[pid]) return;\r
 \r
+       if(debug) fprintf(stderr, "Process %d %s exited, deleting it.\n", pid, all_pids[pid]->comm);\r
+\r
        if(root == all_pids[pid]) root = all_pids[pid]->next;\r
        if(all_pids[pid]->next) all_pids[pid]->next->prev = all_pids[pid]->prev;\r
        if(all_pids[pid]->prev) all_pids[pid]->prev->next = all_pids[pid]->next;\r
@@ -231,8 +230,6 @@ int update_from_proc(void)
                p->merged = 0;\r
                p->new_entry = 0;\r
                p->merge_count = 0;\r
-\r
-               if(p->target_inherited) p->target = NULL;\r
        }\r
 \r
        while((file = readdir(dir))) {\r
@@ -257,6 +254,8 @@ int update_from_proc(void)
 \r
                close(fd);\r
                if(bytes < 100) continue;\r
+               buffer[bytes] = '\0';\r
+               if(debug) fprintf(stderr, "READ: %s", buffer);\r
 \r
                p = get_entry(pid);\r
                if(!p) continue;\r
@@ -298,6 +297,8 @@ int update_from_proc(void)
                strncpy(p->comm, name, MAX_COMPARE_NAME + 2);\r
                p->comm[MAX_COMPARE_NAME + 2] = '\0';\r
 \r
+               if(debug) fprintf(stderr, "VALUES: %s utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->comm, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);\r
+\r
                if(parsed < 39) fprintf(stderr, "file %s gave %d results (expected 44)\n", filename, parsed);\r
 \r
                // check if it is wanted\r
@@ -319,17 +320,18 @@ int update_from_proc(void)
                }\r
 \r
                // just a few checks\r
-               if(p->ppid < 1 || p->ppid > pid_max) p->ppid = 1;\r
+               if(p->ppid < 0 || p->ppid > pid_max) p->ppid = 0;\r
 \r
                // mark it as updated\r
                p->updated = 1;\r
        }\r
        closedir(dir);\r
 \r
-       // cleanup all un-updated\r
+       // cleanup all un-updated processed (exited, killed, etc)\r
        int c;\r
        for(p = root, c = 0; p ; c++) {\r
                if(!p->updated) {\r
+                       \r
                        pid_t r = p->pid;\r
                        p = p->next;\r
                        del_entry(r);\r
@@ -337,43 +339,61 @@ int update_from_proc(void)
                else p = p->next;\r
        }\r
 \r
-       if(debug) fprintf(stderr, "There are %d processes active\n", c);\r
-\r
        return 1;\r
 }\r
 \r
+void walk_down(pid_t pid, int level) {\r
+       struct pid_stat *p = NULL;\r
+       char b[level+3];\r
+       int i;\r
+\r
+       for(i = 0; i < level; i++) b[i] = '\t';\r
+       b[level] = '|';\r
+       b[level+1] = '-';\r
+       b[level+2] = '\0';\r
+\r
+       p = all_pids[pid];\r
+       if(p) fprintf(stderr, "%s %s %d [%s] c=%d u=%llu, s=%llu, cu=%llu, cs=%llu, n=%llu, j=%llu, cn=%llu, cj=%llu\n", b, p->comm, p->pid, p->updated?"OK":"KILLED", p->childs, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);\r
+\r
+       for(p = root; p ; p = p->next) {\r
+               if(p->ppid == pid) {\r
+                       walk_down(p->pid, level+1);\r
+               }\r
+       }\r
+}\r
+\r
 void merge_processes(void)\r
 {\r
        struct pid_stat *p = NULL;\r
 \r
+       if(debug) walk_down(0, 1);\r
+\r
        // link all parents and update childs count\r
        for(p = root; p ; p = p->next) {\r
-               if(p->ppid > 1 && p->ppid <= pid_max && all_pids[p->ppid]) {\r
+               if(p->ppid > 0 && p->ppid <= pid_max && all_pids[p->ppid]) {\r
                        if(debug) fprintf(stderr, "\tParent of %d %s is %d %s\n", p->pid, p->comm, p->ppid, all_pids[p->ppid]->comm);\r
                        \r
                        p->parent = all_pids[p->ppid];\r
-                       if(!p->parent) {\r
-                               if(debug) fprintf(stderr, "\t\tpid %d %s states parent %d, but the later does not exist.\n", p->pid, p->comm, p->ppid);\r
-                               continue;\r
-                       }\r
-\r
                        p->parent->childs++;\r
                }\r
+               else if(p->ppid != 0) fprintf(stderr, "\t\tWRONG! pid %d %s states parent %d, but the later does not exist.\n", p->pid, p->comm, p->ppid);\r
        }\r
 \r
        // find all the procs with 0 childs and merge them to their parents\r
        // repeat, until nothing more can be done.\r
        int found = 1;\r
-       for( ; found ; ) {\r
+       while(found) {\r
                found = 0;\r
                for(p = root; p ; p = p->next) {\r
-                       // if this process does not any childs, and\r
+                       // if this process does not have any childs, and\r
                        // is not already merged, and\r
-                       // its parents has childs waiting to be merged, and\r
+                       // its parent has childs waiting to be merged, and\r
                        // the target of this process and its parent is the same, or the parent does not have a target, or this process does not have a parent\r
+                       // and its parent is not init\r
                        // then... merge them!\r
-                       if(!p->childs && !p->merged && p->parent && p->parent->childs && (p->target == p->parent->target || !p->parent->target || !p->target)) {\r
-                               if(debug) fprintf(stderr, "\tMerging %d %s to %d %s (count: %lu)\n", p->pid, p->comm, p->ppid, all_pids[p->ppid]->comm, p->parent->merge_count+1);\r
+                       if(!p->childs && !p->merged && p->parent && p->parent->childs && (p->target == p->parent->target || !p->parent->target || !p->target) && p->ppid != 1) {\r
+\r
+                               if(debug) fprintf(stderr, "\n\t\tPARENT BEFORE MERGE: %d %s utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->parent->pid, p->parent->comm, p->parent->utime, p->parent->stime, p->parent->cutime, p->parent->cstime, p->parent->minflt, p->parent->majflt, p->parent->cminflt, p->parent->cmajflt);\r
 \r
                                p->parent->minflt += p->minflt;\r
                                p->parent->majflt += p->majflt;\r
@@ -388,15 +408,18 @@ void merge_processes(void)
                                p->parent->num_threads += p->num_threads;\r
                                p->parent->rss += p->rss;\r
 \r
+                               if(debug) fprintf(stderr, "\tMERGED %d %s to %d %s utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->pid, p->comm, p->ppid, all_pids[p->ppid]->comm, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);\r
+\r
                                p->parent->childs--;\r
                                p->merged = 1;\r
 \r
+                               if(debug) fprintf(stderr, "\t\tPARENT AFTER  MERGE: %d %s utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->parent->pid, p->parent->comm, p->parent->utime, p->parent->stime, p->parent->cutime, p->parent->cstime, p->parent->minflt, p->parent->majflt, p->parent->cminflt, p->parent->cmajflt);\r
+\r
                                p->parent->merge_count += p->merge_count + 1;\r
 \r
                                // the parent inherits the child's target, if it does not have a target itself\r
                                if(p->target && !p->parent->target) {\r
                                        p->parent->target = p->target;\r
-                                       p->parent->target_inherited = 1;\r
                                        if(debug) fprintf(stderr, "\t\ttarget %s is inherited by %d %s from its child %d %s.\n", p->target->name, p->parent->pid, p->parent->comm, p->pid, p->comm);\r
                                }\r
 \r
@@ -406,16 +429,29 @@ void merge_processes(void)
                if(debug) fprintf(stderr, "Merged %d processes\n", found);\r
        }\r
 \r
-       if(debug) {\r
-               fprintf(stderr, "Root level processes: \n");\r
-               for(p = root, found = 0; p ; p = p->next) {\r
-                       if(!p->childs && !p->merged && !p->parent) {\r
-                               fprintf(stderr, "\t\t%s %d on target %s\n", p->comm, p->pid, p->target?p->target->name:"-");\r
+       // give a default target on all top level processes\r
+       // init goes always to default target\r
+       if(all_pids[1]) all_pids[1]->target = default_target;\r
+\r
+       for(p = root, found = 0; p ; p = p->next) {\r
+               // if the process is not merged itself\r
+               // then is is a top level process\r
+               if(!p->merged && !p->target) p->target = default_target;\r
+       }\r
+\r
+       // give a target to all merged child processes\r
+       found = 1;\r
+       while(found) {\r
+               found = 0;\r
+               for(p = root; p ; p = p->next) {\r
+                       if(!p->target && p->merged && p->parent && p->parent->target) {\r
+                               p->target = p->parent->target;\r
+                               found++;\r
                        }\r
                }\r
        }\r
 \r
-       // zero the targets\r
+       // zero all the targets\r
        struct wanted *w;\r
        for (w = wanted_root; w ; w = w->next) {\r
                w->minflt = 0;\r
@@ -435,14 +471,14 @@ void merge_processes(void)
        for(p = root; p ; p = p->next) {\r
                //if(p->parent && !p->merged) fprintf(stderr, "\tprocess %s pid %d has a parent, but has not been merged!\n", p->comm, p->pid);\r
                //if(p->childs) fprintf(stderr, "\tprocess %s pid %d has %d childs that have not been merged!\n", p->comm, p->pid, p->childs);\r
-               if(p->merged) continue;\r
 \r
                if(!p->target) {\r
-                       p->target = default_target;\r
-                       p->target_inherited = 1;\r
-                       if(debug) fprintf(stderr, "\tprocess %s pid %d is orphan\n", p->comm, p->pid);\r
+                       fprintf(stderr, "WRONG! pid %d %s was left without a target!\n", p->pid, p->comm);\r
+                       continue;\r
                }\r
 \r
+               if(p->merged) continue;\r
+\r
                p->target->minflt += p->minflt;\r
                p->target->majflt += p->majflt;\r
                p->target->utime += p->utime;\r
@@ -455,7 +491,8 @@ void merge_processes(void)
                p->target->rss += p->rss;\r
 \r
                p->target->merge_count += p->merge_count + 1;\r
-               if(debug) fprintf(stderr, "\tAgregating %s pid %d on %s (count: %lu)\n", p->comm, p->pid, p->target->name, p->target->merge_count);\r
+\r
+               if(debug) fprintf(stderr, "\tAgregating %s pid %d on %s (count: %lu) utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->comm, p->pid, p->target->name, p->target->merge_count, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);\r
        }\r
 }\r
 \r
@@ -468,7 +505,7 @@ void show_dimensions(void)
        for (w = wanted_root; w ; w = w->next) {\r
                if(w->target || (!w->merge_count && !w->exposed)) continue;\r
 \r
-               fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + w->stime + (w->cutime * add_childs) + (w->cstime * add_childs));\r
+               fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + w->stime);\r
        }\r
        fprintf(stdout, "END\n");\r
 \r
@@ -476,7 +513,7 @@ void show_dimensions(void)
        for (w = wanted_root; w ; w = w->next) {\r
                if(w->target || (!w->merge_count && !w->exposed)) continue;\r
 \r
-               fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + (w->cutime * add_childs));\r
+               fprintf(stdout, "SET %s = %llu\n", w->name, w->utime);\r
        }\r
        fprintf(stdout, "END\n");\r
 \r
@@ -484,7 +521,7 @@ void show_dimensions(void)
        for (w = wanted_root; w ; w = w->next) {\r
                if(w->target || (!w->merge_count && !w->exposed)) continue;\r
 \r
-               fprintf(stdout, "SET %s = %llu\n", w->name, w->stime + (w->cstime * add_childs));\r
+               fprintf(stdout, "SET %s = %llu\n", w->name, w->stime);\r
        }\r
        fprintf(stdout, "END\n");\r
 \r
@@ -516,7 +553,7 @@ void show_dimensions(void)
        for (w = wanted_root; w ; w = w->next) {\r
                if(w->target || (!w->merge_count && !w->exposed)) continue;\r
 \r
-               fprintf(stdout, "SET %s = %llu\n", w->name, w->minflt + (w->cminflt * add_childs));\r
+               fprintf(stdout, "SET %s = %llu\n", w->name, w->minflt);\r
        }\r
        fprintf(stdout, "END\n");\r
 \r
@@ -524,11 +561,11 @@ void show_dimensions(void)
        for (w = wanted_root; w ; w = w->next) {\r
                if(w->target || (!w->merge_count && !w->exposed)) continue;\r
 \r
-               fprintf(stdout, "SET %s = %llu\n", w->name, w->majflt + (w->cmajflt * add_childs));\r
+               fprintf(stdout, "SET %s = %llu\n", w->name, w->majflt);\r
        }\r
        fprintf(stdout, "END\n");\r
 \r
-       fflush(stdout);\r
+       fflush(NULL);\r
 }\r
 \r
 void show_charts(void)\r
@@ -604,7 +641,7 @@ void show_charts(void)
                fprintf(stdout, "DIMENSION %s '' incremental 1 1\n", w->name);\r
        }\r
 \r
-       fflush(stdout);\r
+       fflush(NULL);\r
 }\r
 \r
 unsigned long long get_hertz(void)\r
@@ -624,7 +661,7 @@ unsigned long long get_hertz(void)
        hz = (sizeof(long)==sizeof(int) || htons(999)==999) ? 100UL : 1024UL;\r
 #endif\r
 \r
-       fprintf(stderr, "Unknown HZ value. Assuming %llu", hz);\r
+       fprintf(stderr, "Unknown HZ value. Assuming %llu.\n", hz);\r
        return hz;\r
 }\r
 \r
index 1d525e80c19315ca65bae7a70d1cb5f24fd34371..b9af2d87694465a9c314897e30b4ec1af51f8cd0 100644 (file)
--- a/netdata.c
+++ b/netdata.c
@@ -1315,8 +1315,12 @@ unsigned long long rrd_stats_done(RRD_STATS *st)
                                        // we need the incremental calculation to produce per second results
                                        // so, we multiply with 1.000.000 and divide by the microseconds passed since
                                        // the last entry
-                                       if(rd->last_collected_value > rd->collected_value) rd->calculated_value = 0;
-                                       else rd->calculated_value =
+
+                                       // if the new is smaller than the old (an overflow, or reset), set the old equal to the new
+                                       // to reset the calculation (it will give zero as the calculation for this second)
+                                       if(rd->last_collected_value > rd->collected_value) rd->last_collected_value = rd->collected_value;
+
+                                       rd->calculated_value =
                                                  (calculated_number)10
                                                * (calculated_number)1000000
                                                * (calculated_number)(rd->collected_value - rd->last_collected_value)