@cryptotaxi247 / netdata-1 / commits / 1b05cbc47

now it correctly calcs the values when processes are exiting; there is a lot of commenting code in an attempt to find a method of taking into account the exited childs resources too - commented because there is success yet

Costa Tsaousis (ktsaou) committed May 8, 2014 at 02:00 UTC 1b05cbc477c2d58c15b5d2c427ac84990228c7d1
1 file changed +219 -97
apps_plugin.c
+219 -97
@@ -46,7 +46,16 @@ struct wanted {
46 unsigned long long num_threads;
47 unsigned long long rss;
48
49 - unsigned long merge_count; // how many processes have been merged to this
49 + unsigned long long fix_minflt;
50 + unsigned long long fix_cminflt;
51 + unsigned long long fix_majflt;
52 + unsigned long long fix_cmajflt;
53 + unsigned long long fix_utime;
54 + unsigned long long fix_stime;
55 + unsigned long long fix_cutime;
56 + unsigned long long fix_cstime;
57 +
58 + unsigned long processes; // how many processes have been merged to this
59 int exposed; // if set, we have sent this to netdata
60
61 struct wanted *target; // the one that will be reported to netdata
@@ -55,9 +64,13 @@ struct wanted {
64
65 int update_every = 1;
66
58 -struct wanted *add_wanted(const char *id, struct wanted *target)
67 +struct wanted *get_wanted(const char *id, struct wanted *target)
68 {
60 - struct wanted *w = calloc(sizeof(struct wanted), 1);
69 + struct wanted *w;
70 + for(w = wanted_root ; w ; w = w->next)
71 + if(strncmp(id, w->id, MAX_NAME) == 0) return w;
72 +
73 + w = calloc(sizeof(struct wanted), 1);
74 if(!w) {
75 fprintf(stderr, "Cannot allocate %ld bytes of memory\n", sizeof(struct wanted));
76 return NULL;
@@ -104,12 +117,12 @@ void parse_args(int argc, char **argv)
117 break;
118 }
119
107 - struct wanted *n = add_wanted(t, w);
120 + struct wanted *n = get_wanted(t, w);
121 if(!w) w = n;
122 }
123 }
124
112 - default_target = add_wanted("all_other_processes", NULL);
125 + default_target = get_wanted("all_other_processes", NULL);
126 strncpy(default_target->name, "other", MAX_NAME);
127 }
128
@@ -160,11 +173,31 @@ struct pid_stat {
173 uint64_t guest_time;
174 int64_t cguest_time;
175
176 +/* unsigned long long old_utime;
177 + unsigned long long old_stime;
178 + unsigned long long old_minflt;
179 + unsigned long long old_majflt;
180 +
181 + unsigned long long old_cutime;
182 + unsigned long long old_cstime;
183 + unsigned long long old_cminflt;
184 + unsigned long long old_cmajflt;
185 +
186 + unsigned long long fix_cutime;
187 + unsigned long long fix_cstime;
188 + unsigned long long fix_cminflt;
189 + unsigned long long fix_cmajflt;
190 +
191 + unsigned long long diff_cutime;
192 + unsigned long long diff_cstime;
193 + unsigned long long diff_cminflt;
194 + unsigned long long diff_cmajflt;
195 +*/
196 +
197 int childs; // number of processes directly referencing this
198 int updated;
199 int merged;
200 int new_entry;
167 - unsigned long merge_count;
201 struct wanted *target;
202 struct pid_stat *parent;
203 struct pid_stat *prev;
@@ -229,7 +262,6 @@ int update_from_proc(void)
262 p->childs = 0;
263 p->merged = 0;
264 p->new_entry = 0;
232 - p->merge_count = 0;
265 }
266
267 while((file = readdir(dir))) {
@@ -241,7 +273,7 @@ int update_from_proc(void)
273
274 int fd = open(filename, O_RDONLY);
275 if(fd == -1) {
244 - if(errno != ENOENT && errno != ESRCH) fprintf(stderr, "Cannot open file '%s' for reading (%s).\n", filename, strerror(errno));
276 + if(errno != ENOENT && errno != ESRCH) fprintf(stderr, "Cannot open file '%s' for reading (%d, %s).\n", filename, errno, strerror(errno));
277 continue;
278 }
279
@@ -327,47 +359,49 @@ int update_from_proc(void)
359 }
360 closedir(dir);
361
330 - // cleanup all un-updated processed (exited, killed, etc)
331 - int c;
332 - for(p = root, c = 0; p ; c++) {
333 - if(!p->updated) {
334 -
335 - pid_t r = p->pid;
336 - p = p->next;
337 - del_entry(r);
338 - }
339 - else p = p->next;
340 - }
341 -
362 return 1;
363 }
344 -
345 -void walk_down(pid_t pid, int level) {
364 +/*
365 +int walk_down(pid_t pid, int level) {
366 struct pid_stat *p = NULL;
367 char b[level+3];
348 - int i;
368 + int i, ret = 0;
369
370 for(i = 0; i < level; i++) b[i] = '\t';
371 b[level] = '|';
372 b[level+1] = '-';
373 b[level+2] = '\0';
374
355 - p = all_pids[pid];
356 - 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);
357 -
375 for(p = root; p ; p = p->next) {
376 if(p->ppid == pid) {
360 - walk_down(p->pid, level+1);
377 + ret += walk_down(p->pid, level+1);
378 }
379 }
380 +
381 + p = all_pids[pid];
382 + if(p) {
383 + if(!p->updated) ret += 1;
384 + if(ret) fprintf(stderr, "%s %s %d [%s, %s] c=%d u=%llu+%llu, s=%llu+%llu, cu=%llu+%llu, cs=%llu+%llu, n=%llu+%llu, j=%llu+%llu, cn=%llu+%llu, cj=%llu+%llu\n"
385 + , b, p->comm, p->pid, p->updated?"OK":"KILLED", p->target->name, p->childs
386 + , p->utime, p->utime - p->old_utime
387 + , p->stime, p->stime - p->old_stime
388 + , p->cutime, p->cutime - p->old_cutime
389 + , p->cstime, p->cstime - p->old_cstime
390 + , p->minflt, p->minflt - p->old_minflt
391 + , p->majflt, p->majflt - p->old_majflt
392 + , p->cminflt, p->cminflt - p->old_cminflt
393 + , p->cmajflt, p->cmajflt - p->old_cmajflt
394 + );
395 + }
396 +
397 + return ret;
398 }
399 +*/
400
365 -void merge_processes(void)
401 +void update_statistics(void)
402 {
403 struct pid_stat *p = NULL;
404
369 - if(debug) walk_down(0, 1);
370 -
405 // link all parents and update childs count
406 for(p = root; p ; p = p->next) {
407 if(p->ppid > 0 && p->ppid <= pid_max && all_pids[p->ppid]) {
@@ -392,31 +426,9 @@ void merge_processes(void)
426 // and its parent is not init
427 // then... merge them!
428 if(!p->childs && !p->merged && p->parent && p->parent->childs && (p->target == p->parent->target || !p->parent->target || !p->target) && p->ppid != 1) {
395 -
396 - 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);
397 -
398 - p->parent->minflt += p->minflt;
399 - p->parent->majflt += p->majflt;
400 - p->parent->utime += p->utime;
401 - p->parent->stime += p->stime;
402 -
403 - p->parent->cminflt += p->cminflt;
404 - p->parent->cmajflt += p->cmajflt;
405 - p->parent->cutime += p->cutime;
406 - p->parent->cstime += p->cstime;
407 -
408 - p->parent->num_threads += p->num_threads;
409 - p->parent->rss += p->rss;
410 -
411 - 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);
412 -
429 p->parent->childs--;
430 p->merged = 1;
431
416 - 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);
417 -
418 - p->parent->merge_count += p->merge_count + 1;
419 -
432 // the parent inherits the child's target, if it does not have a target itself
433 if(p->target && !p->parent->target) {
434 p->parent->target = p->target;
@@ -433,11 +445,18 @@ void merge_processes(void)
445 // init goes always to default target
446 if(all_pids[1]) all_pids[1]->target = default_target;
447
436 - for(p = root, found = 0; p ; p = p->next) {
448 + for(p = root; p ; p = p->next) {
449 // if the process is not merged itself
450 // then is is a top level process
451 if(!p->merged && !p->target) p->target = default_target;
440 - }
452 +
453 +/* // by the way, update the diffs
454 + // will be used later for substracting killed process times
455 + p->diff_cutime = p->utime - p->cutime;
456 + p->diff_cstime = p->stime - p->cstime;
457 + p->diff_cminflt = p->minflt - p->cminflt;
458 + p->diff_cmajflt = p->majflt - p->cmajflt;
459 +*/ }
460
461 // give a target to all merged child processes
462 found = 1;
@@ -451,6 +470,59 @@ void merge_processes(void)
470 }
471 }
472
473 +/* // for each killed process, remove its values from the parents
474 + // sums (we had already added them in a previous loop)
475 + for(p = root; p ; p = p->next) {
476 + if(p->updated) continue;
477 +
478 + fprintf(stderr, "UNMERGING %d %s\n", p->pid, p->comm);
479 +
480 + unsigned long long diff_utime = p->utime + p->cutime + p->fix_cutime;
481 + unsigned long long diff_stime = p->stime + p->cstime + p->fix_cstime;
482 + unsigned long long diff_minflt = p->minflt + p->cminflt + p->fix_cminflt;
483 + unsigned long long diff_majflt = p->majflt + p->cmajflt + p->fix_cmajflt;
484 +
485 + struct pid_stat *t = p;
486 + while((t = t->parent)) {
487 + if(!t->updated) continue;
488 +
489 + unsigned long long x;
490 + if(diff_utime && t->diff_cutime) {
491 + x = (t->diff_cutime < diff_utime)?t->diff_cutime:diff_utime;
492 + diff_utime -= x;
493 + t->diff_cutime -= x;
494 + t->fix_cutime += x;
495 + fprintf(stderr, "\t cutime %llu from %d %s %s\n", x, t->pid, t->comm, t->target->name);
496 + }
497 + if(diff_stime && t->diff_cstime) {
498 + x = (t->diff_cstime < diff_stime)?t->diff_cstime:diff_stime;
499 + diff_stime -= x;
500 + t->diff_cstime -= x;
501 + t->fix_cstime += x;
502 + fprintf(stderr, "\t cstime %llu from %d %s %s\n", x, t->pid, t->comm, t->target->name);
503 + }
504 + if(diff_minflt && t->diff_cminflt) {
505 + x = (t->diff_cminflt < diff_minflt)?t->diff_cminflt:diff_minflt;
506 + diff_minflt -= x;
507 + t->diff_cminflt -= x;
508 + t->fix_cminflt += x;
509 + fprintf(stderr, "\t cminflt %llu from %d %s %s\n", x, t->pid, t->comm, t->target->name);
510 + }
511 + if(diff_majflt && t->diff_cmajflt) {
512 + x = (t->diff_cmajflt < diff_majflt)?t->diff_cmajflt:diff_majflt;
513 + diff_majflt -= x;
514 + t->diff_cmajflt -= x;
515 + t->fix_cmajflt += x;
516 + fprintf(stderr, "\t cmajflt %llu from %d %s %s\n", x, t->pid, t->comm, t->target->name);
517 + }
518 + }
519 +
520 + if(diff_utime) fprintf(stderr, "\t cannot fix up utime %llu\n", diff_utime);
521 + if(diff_stime) fprintf(stderr, "\t cannot fix up stime %llu\n", diff_stime);
522 + if(diff_minflt) fprintf(stderr, "\t cannot fix up minflt %llu\n", diff_minflt);
523 + if(diff_majflt) fprintf(stderr, "\t cannot fix up majflt %llu\n", diff_majflt);
524 + }
525 +*/
526 // zero all the targets
527 struct wanted *w;
528 for (w = wanted_root; w ; w = w->next) {
@@ -464,35 +536,85 @@ void merge_processes(void)
536 w->cstime = 0;
537 w->num_threads = 0;
538 w->rss = 0;
467 - w->merge_count = 0;
539 + w->processes = 0;
540 }
541
542 +/* walk_down(0, 1);
543 +*/
544 // concentrate everything on the targets
545 for(p = root; p ; p = p->next) {
472 - //if(p->parent && !p->merged) fprintf(stderr, "\tprocess %s pid %d has a parent, but has not been merged!\n", p->comm, p->pid);
473 - //if(p->childs) fprintf(stderr, "\tprocess %s pid %d has %d childs that have not been merged!\n", p->comm, p->pid, p->childs);
474 -
546 if(!p->target) {
547 fprintf(stderr, "WRONG! pid %d %s was left without a target!\n", p->pid, p->comm);
548 continue;
549 }
550
480 - if(p->merged) continue;
481 -
482 - p->target->minflt += p->minflt;
483 - p->target->majflt += p->majflt;
484 - p->target->utime += p->utime;
485 - p->target->stime += p->stime;
486 - p->target->cminflt += p->cminflt;
487 - p->target->cmajflt += p->cmajflt;
488 - p->target->cutime += p->cutime;
489 - p->target->cstime += p->cstime;
490 - p->target->num_threads += p->num_threads;
491 - p->target->rss += p->rss;
492 -
493 - p->target->merge_count += p->merge_count + 1;
551 + if(p->updated) {
552 + p->target->cutime += p->cutime; // - p->fix_cutime;
553 + p->target->cstime += p->cstime; // - p->fix_cstime;
554 + p->target->cminflt += p->cminflt; // - p->fix_cminflt;
555 + p->target->cmajflt += p->cmajflt; // - p->fix_cmajflt;
556 +
557 + p->target->utime += p->utime; //+ (p->pid != 1)?(p->cutime - p->fix_cutime):0;
558 + p->target->stime += p->stime; //+ (p->pid != 1)?(p->cstime - p->fix_cstime):0;
559 + p->target->minflt += p->minflt; //+ (p->pid != 1)?(p->cminflt - p->fix_cminflt):0;
560 + p->target->majflt += p->majflt; //+ (p->pid != 1)?(p->cmajflt - p->fix_cmajflt):0;
561 +
562 + p->target->num_threads += p->num_threads;
563 + p->target->rss += p->rss;
564 +
565 + p->target->processes++;
566 +
567 + if(debug) fprintf(stderr, "\tAgregating %s pid %d on %s 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->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);
568 +
569 +/* if(p->utime - p->old_utime > 100) fprintf(stderr, "BIG CHANGE: %d %s utime increased by %llu from %llu to %llu\n", p->pid, p->comm, p->utime - p->old_utime, p->old_utime, p->utime);
570 + if(p->cutime - p->old_cutime > 100) fprintf(stderr, "BIG CHANGE: %d %s cutime increased by %llu from %llu to %llu\n", p->pid, p->comm, p->cutime - p->old_cutime, p->old_cutime, p->cutime);
571 + if(p->stime - p->old_stime > 100) fprintf(stderr, "BIG CHANGE: %d %s stime increased by %llu from %llu to %llu\n", p->pid, p->comm, p->stime - p->old_stime, p->old_stime, p->stime);
572 + if(p->cstime - p->old_cstime > 100) fprintf(stderr, "BIG CHANGE: %d %s cstime increased by %llu from %llu to %llu\n", p->pid, p->comm, p->cstime - p->old_cstime, p->old_cstime, p->cstime);
573 + if(p->minflt - p->old_minflt > 5000) fprintf(stderr, "BIG CHANGE: %d %s minflt increased by %llu from %llu to %llu\n", p->pid, p->comm, p->minflt - p->old_minflt, p->old_minflt, p->minflt);
574 + if(p->majflt - p->old_majflt > 5000) fprintf(stderr, "BIG CHANGE: %d %s majflt increased by %llu from %llu to %llu\n", p->pid, p->comm, p->majflt - p->old_majflt, p->old_majflt, p->majflt);
575 + if(p->cminflt - p->old_cminflt > 15000) fprintf(stderr, "BIG CHANGE: %d %s cminflt increased by %llu from %llu to %llu\n", p->pid, p->comm, p->cminflt - p->old_cminflt, p->old_cminflt, p->cminflt);
576 + if(p->cmajflt - p->old_cmajflt > 15000) fprintf(stderr, "BIG CHANGE: %d %s cmajflt increased by %llu from %llu to %llu\n", p->pid, p->comm, p->cmajflt - p->old_cmajflt, p->old_cmajflt, p->cmajflt);
577 +
578 + p->old_utime = p->utime;
579 + p->old_cutime = p->cutime;
580 + p->old_stime = p->stime;
581 + p->old_cstime = p->cstime;
582 + p->old_minflt = p->minflt;
583 + p->old_majflt = p->majflt;
584 + p->old_cminflt = p->cminflt;
585 + p->old_cmajflt = p->cmajflt;
586 +*/ }
587 + else {
588 + // since the process has exited, the user
589 + // will see a drop in our charts, because the incremental
590 + // values of this process will not be there
591 +
592 + // add them to the fix_* values and they will be added to
593 + // the reported values, so that the report goes steady
594 + p->target->fix_minflt += p->minflt;
595 + p->target->fix_majflt += p->majflt;
596 + p->target->fix_utime += p->utime;
597 + p->target->fix_stime += p->stime;
598 + p->target->fix_cminflt += p->cminflt;
599 + p->target->fix_cmajflt += p->cmajflt;
600 + p->target->fix_cutime += p->cutime;
601 + p->target->fix_cstime += p->cstime;
602 + }
603 + }
604
495 - 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);
605 +/* fprintf(stderr, "\n");
606 +*/
607 + // cleanup all un-updated processed (exited, killed, etc)
608 + int c;
609 + for(p = root, c = 0; p ; c++) {
610 + if(!p->updated) {
611 +/* 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);
612 +*/
613 + pid_t r = p->pid;
614 + p = p->next;
615 + del_entry(r);
616 + }
617 + else p = p->next;
618 }
619 }
620
@@ -503,31 +625,31 @@ void show_dimensions(void)
625
626 fprintf(stdout, "BEGIN apps.cpu\n");
627 for (w = wanted_root; w ; w = w->next) {
506 - if(w->target || (!w->merge_count && !w->exposed)) continue;
628 + if(w->target || (!w->processes && !w->exposed)) continue;
629
508 - fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + w->stime);
630 + fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + w->stime + w->fix_utime + w->fix_stime);
631 }
632 fprintf(stdout, "END\n");
633
634 fprintf(stdout, "BEGIN apps.cpu_user\n");
635 for (w = wanted_root; w ; w = w->next) {
514 - if(w->target || (!w->merge_count && !w->exposed)) continue;
636 + if(w->target || (!w->processes && !w->exposed)) continue;
637
516 - fprintf(stdout, "SET %s = %llu\n", w->name, w->utime);
638 + fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + w->fix_utime);
639 }
640 fprintf(stdout, "END\n");
641
642 fprintf(stdout, "BEGIN apps.cpu_system\n");
643 for (w = wanted_root; w ; w = w->next) {
522 - if(w->target || (!w->merge_count && !w->exposed)) continue;
644 + if(w->target || (!w->processes && !w->exposed)) continue;
645
524 - fprintf(stdout, "SET %s = %llu\n", w->name, w->stime);
646 + fprintf(stdout, "SET %s = %llu\n", w->name, w->stime + w->fix_stime);
647 }
648 fprintf(stdout, "END\n");
649
650 fprintf(stdout, "BEGIN apps.threads\n");
651 for (w = wanted_root; w ; w = w->next) {
530 - if(w->target || (!w->merge_count && !w->exposed)) continue;
652 + if(w->target || (!w->processes && !w->exposed)) continue;
653
654 fprintf(stdout, "SET %s = %llu\n", w->name, w->num_threads);
655 }
@@ -535,15 +657,15 @@ void show_dimensions(void)
657
658 fprintf(stdout, "BEGIN apps.processes\n");
659 for (w = wanted_root; w ; w = w->next) {
538 - if(w->target || (!w->merge_count && !w->exposed)) continue;
660 + if(w->target || (!w->processes && !w->exposed)) continue;
661
540 - fprintf(stdout, "SET %s = %lu\n", w->name, w->merge_count);
662 + fprintf(stdout, "SET %s = %lu\n", w->name, w->processes);
663 }
664 fprintf(stdout, "END\n");
665
666 fprintf(stdout, "BEGIN apps.rss\n");
667 for (w = wanted_root; w ; w = w->next) {
546 - if(w->target || (!w->merge_count && !w->exposed)) continue;
668 + if(w->target || (!w->processes && !w->exposed)) continue;
669
670 fprintf(stdout, "SET %s = %llu\n", w->name, (unsigned long long)w->rss);
671 }
@@ -551,17 +673,17 @@ void show_dimensions(void)
673
674 fprintf(stdout, "BEGIN apps.minor_faults\n");
675 for (w = wanted_root; w ; w = w->next) {
554 - if(w->target || (!w->merge_count && !w->exposed)) continue;
676 + if(w->target || (!w->processes && !w->exposed)) continue;
677
556 - fprintf(stdout, "SET %s = %llu\n", w->name, w->minflt);
678 + fprintf(stdout, "SET %s = %llu\n", w->name, w->minflt + w->fix_minflt);
679 }
680 fprintf(stdout, "END\n");
681
682 fprintf(stdout, "BEGIN apps.major_faults\n");
683 for (w = wanted_root; w ; w = w->next) {
562 - if(w->target || (!w->merge_count && !w->exposed)) continue;
684 + if(w->target || (!w->processes && !w->exposed)) continue;
685
564 - fprintf(stdout, "SET %s = %llu\n", w->name, w->majflt);
686 + fprintf(stdout, "SET %s = %llu\n", w->name, w->majflt + w->fix_majflt);
687 }
688 fprintf(stdout, "END\n");
689
@@ -574,7 +696,7 @@ void show_charts(void)
696 int newly_added = 0;
697
698 for(w = wanted_root ; w ; w = w->next)
577 - if(!w->exposed && w->merge_count) {
699 + if(!w->exposed && w->processes) {
700 newly_added++;
701 w->exposed = 1;
702 if(debug) fprintf(stderr, "%s just added - regenerating charts.\n", w->name);
@@ -587,56 +709,56 @@ void show_charts(void)
709 // update the charts
710 fprintf(stdout, "CHART apps.cpu '' 'Applications CPU Time' 'cpu time %%' apps apps stacked 20001 %d\n", update_every);
711 for (w = wanted_root; w ; w = w->next) {
590 - if(w->target || (!w->merge_count && !w->exposed)) continue;
712 + if(w->target || (!w->processes && !w->exposed)) continue;
713
714 fprintf(stdout, "DIMENSION %s '' incremental 100 %llu\n", w->name, Hertz);
715 }
716
717 fprintf(stdout, "CHART apps.rss '' 'Applications Memory' 'MB' apps apps stacked 20002 %d\n", update_every);
718 for (w = wanted_root; w ; w = w->next) {
597 - if(w->target || (!w->merge_count && !w->exposed)) continue;
719 + if(w->target || (!w->processes && !w->exposed)) continue;
720
721 fprintf(stdout, "DIMENSION %s '' absolute %ld %ld\n", w->name, sysconf(_SC_PAGESIZE), 1024L*1024L);
722 }
723
724 fprintf(stdout, "CHART apps.threads '' 'Applications Threads' 'threads' apps apps stacked 20005 %d\n", update_every);
725 for (w = wanted_root; w ; w = w->next) {
604 - if(w->target || (!w->merge_count && !w->exposed)) continue;
726 + if(w->target || (!w->processes && !w->exposed)) continue;
727
728 fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
729 }
730
731 fprintf(stdout, "CHART apps.processes '' 'Applications Processes' 'processes' apps apps stacked 20004 %d\n", update_every);
732 for (w = wanted_root; w ; w = w->next) {
611 - if(w->target || (!w->merge_count && !w->exposed)) continue;
733 + if(w->target || (!w->processes && !w->exposed)) continue;
734
735 fprintf(stdout, "DIMENSION %s '' absolute 1 1\n", w->name);
736 }
737
738 fprintf(stdout, "CHART apps.cpu_user '' 'Applications CPU User Time' 'cpu time %%' apps none stacked 20020 %d\n", update_every);
739 for (w = wanted_root; w ; w = w->next) {
618 - if(w->target || (!w->merge_count && !w->exposed)) continue;
740 + if(w->target || (!w->processes && !w->exposed)) continue;
741
742 fprintf(stdout, "DIMENSION %s '' incremental 100 %llu\n", w->name, Hertz);
743 }
744
745 fprintf(stdout, "CHART apps.cpu_system '' 'Applications CPU System Time' 'cpu time %%' apps none stacked 20021 %d\n", update_every);
746 for (w = wanted_root; w ; w = w->next) {
625 - if(w->target || (!w->merge_count && !w->exposed)) continue;
747 + if(w->target || (!w->processes && !w->exposed)) continue;
748
749 fprintf(stdout, "DIMENSION %s '' incremental 100 %llu\n", w->name, Hertz);
750 }
751
752 fprintf(stdout, "CHART apps.major_faults '' 'Applications Major Page Faults' 'page faults/s' apps apps stacked 20010 %d\n", update_every);
753 for (w = wanted_root; w ; w = w->next) {
632 - if(w->target || (!w->merge_count && !w->exposed)) continue;
754 + if(w->target || (!w->processes && !w->exposed)) continue;
755
756 fprintf(stdout, "DIMENSION %s '' incremental 1 1\n", w->name);
757 }
758
759 fprintf(stdout, "CHART apps.minor_faults '' 'Applications Minor Page Faults' 'page faults/s' apps apps stacked 20011 %d\n", update_every);
760 for (w = wanted_root; w ; w = w->next) {
639 - if(w->target || (!w->merge_count && !w->exposed)) continue;
761 + if(w->target || (!w->processes && !w->exposed)) continue;
762
763 fprintf(stdout, "DIMENSION %s '' incremental 1 1\n", w->name);
764 }
@@ -720,7 +842,7 @@ int main(int argc, char **argv)
842 exit(1);
843 }
844
723 - merge_processes();
845 + update_statistics();
846 show_charts(); // this is smart enough to show only newly added apps, when needed
847 show_dimensions();
848