apps.plugin now reports exited children resources too
Costa Tsaousis (ktsaou) committed
Jun 27, 2016 at 10:34 UTC
3274015c70404e31f3719ff26e79167684389b0b
2 files changed
+153
-379
src/apps_plugin.c
+150
-376
@@ -47,8 +47,8 @@
47
#define MAX_NAME 100
48
#define MAX_CMDLINE 1024
49
50
-long processors = 1;
51
-long pid_max = 32768;
50
+int processors = 1;
51
+pid_t pid_max = 32768;
52
int debug = 0;
53
54
int update_every = 1;
@@ -58,160 +58,6 @@ int proc_pid_cmdline_is_needed = 0;
58
char *host_prefix = "";
59
char *config_dir = CONFIG_DIR;
60
61
-#ifdef NETDATA_INTERNAL_CHECKS
62
-// ----------------------------------------------------------------------------
63
-// memory debugger
64
-// do not use in production systems - it mis-aligns allocated memory
65
-
66
-struct allocations {
67
- size_t allocations;
68
- size_t allocated;
69
- size_t allocated_max;
70
-} allocations = { 0, 0, 0 };
71
-
72
-#define MALLOC_MARK (uint32_t)(0x0BADCAFE)
73
-#define MALLOC_PREFIX (sizeof(uint32_t) * 2)
74
-#define MALLOC_SUFFIX (sizeof(uint32_t))
75
-#define MALLOC_OVERHEAD (MALLOC_PREFIX + MALLOC_SUFFIX)
76
-
77
-void *mark_allocation(void *allocated_ptr, size_t size_without_overheads) {
78
- uint32_t *real_ptr = (uint32_t *)allocated_ptr;
79
- real_ptr[0] = MALLOC_MARK;
80
- real_ptr[1] = (uint32_t) size_without_overheads;
81
-
82
- uint32_t *end_ptr = (uint32_t *)(allocated_ptr + MALLOC_PREFIX + size_without_overheads);
83
- end_ptr[0] = MALLOC_MARK;
84
-
85
- // fprintf(stderr, "MEMORY_POINTER: Allocated at %p, returning %p.\n", allocated_ptr, (void *)(allocated_ptr + MALLOC_PREFIX));
86
-
87
- return allocated_ptr + MALLOC_PREFIX;
88
-}
89
-
90
-void *check_allocation(const char *file, int line, const char *function, void *marked_ptr, size_t *size_without_overheads_ptr) {
91
- uint32_t *real_ptr = (uint32_t *)(marked_ptr - MALLOC_PREFIX);
92
-
93
- // fprintf(stderr, "MEMORY_POINTER: Checking pointer at %p, real %p for %s/%u@%s.\n", marked_ptr, (void *)(marked_ptr - MALLOC_PREFIX), function, line, file);
94
-
95
- if(real_ptr[0] != MALLOC_MARK) fatal("MEMORY: prefix MARK is not valid for %s/%d@%s.", function, line, file);
96
-
97
- size_t size = real_ptr[1];
98
-
99
- uint32_t *end_ptr = (uint32_t *)(marked_ptr + size);
100
- if(end_ptr[0] != MALLOC_MARK) fatal("MEMORY: suffix MARK of allocation with size %zu is not valid for %s/%d@%s.", size, function, line, file);
101
-
102
- if(size_without_overheads_ptr) *size_without_overheads_ptr = size;
103
-
104
- return real_ptr;
105
-}
106
-
107
-void *malloc_debug(const char *file, int line, const char *function, size_t size) {
108
- void *ptr = malloc(size + MALLOC_OVERHEAD);
109
- if(!ptr) fatal("MEMORY: Cannot allocate %zu bytes for %s/%d@%s.", size, function, line, file);
110
-
111
- allocations.allocated += size;
112
- allocations.allocations++;
113
-
114
- debug(D_MEMORY, "MEMORY: Allocated %zu bytes for %s/%d@%s."
115
- " Status: allocated %zu in %zu allocs."
116
- , size
117
- , function, line, file
118
- , allocations.allocated
119
- , allocations.allocations
120
- );
121
-
122
- if(allocations.allocated > allocations.allocated_max) {
123
- debug(D_MEMORY, "MEMORY: total allocation peak increased from %zu to %zu", allocations.allocated_max, allocations.allocated);
124
- allocations.allocated_max = allocations.allocated;
125
- }
126
-
127
- size_t csize;
128
- check_allocation(file, line, function, mark_allocation(ptr, size), &csize);
129
- if(size != csize) {
130
- fatal("Invalid size.");
131
- }
132
-
133
- return mark_allocation(ptr, size);
134
-}
135
-
136
-void *calloc_debug(const char *file, int line, const char *function, size_t nmemb, size_t size) {
137
- void *ptr = malloc_debug(file, line, function, (nmemb * size));
138
- bzero(ptr, nmemb * size);
139
- return ptr;
140
-}
141
-
142
-void free_debug(const char *file, int line, const char *function, void *ptr) {
143
- size_t size;
144
- void *real_ptr = check_allocation(file, line, function, ptr, &size);
145
-
146
- bzero(real_ptr, size + MALLOC_OVERHEAD);
147
-
148
- free(real_ptr);
149
- allocations.allocated -= size;
150
- allocations.allocations--;
151
-
152
- debug(D_MEMORY, "MEMORY: freed %zu bytes for %s/%d@%s."
153
- " Status: allocated %zu in %zu allocs."
154
- , size
155
- , function, line, file
156
- , allocations.allocated
157
- , allocations.allocations
158
- );
159
-}
160
-
161
-void *realloc_debug(const char *file, int line, const char *function, void *ptr, size_t size) {
162
- if(!ptr) return malloc_debug(file, line, function, size);
163
- if(!size) { free_debug(file, line, function, ptr); return NULL; }
164
-
165
- size_t old_size;
166
- void *real_ptr = check_allocation(file, line, function, ptr, &old_size);
167
-
168
- void *new_ptr = realloc(real_ptr, size + MALLOC_OVERHEAD);
169
- if(!new_ptr) fatal("MEMORY: Cannot allocate %zu bytes for %s/%d@%s.", size, function, line, file);
170
-
171
- allocations.allocated += size;
172
- allocations.allocated -= old_size;
173
-
174
- debug(D_MEMORY, "MEMORY: Re-allocated from %zu to %zu bytes for %s/%d@%s."
175
- " Status: allocated %zu in %zu allocs."
176
- , old_size, size
177
- , function, line, file
178
- , allocations.allocated
179
- , allocations.allocations
180
- );
181
-
182
- if(allocations.allocated > allocations.allocated_max) {
183
- debug(D_MEMORY, "MEMORY: total allocation peak increased from %zu to %zu", allocations.allocated_max, allocations.allocated);
184
- allocations.allocated_max = allocations.allocated;
185
- }
186
-
187
- return mark_allocation(new_ptr, size);
188
-}
189
-
190
-char *strdup_debug(const char *file, int line, const char *function, const char *ptr) {
191
- size_t size = 0;
192
- const char *s = ptr;
193
-
194
- while(*s++) size++;
195
- size++;
196
-
197
- char *p = malloc_debug(file, line, function, size);
198
- if(!p) fatal("Cannot allocate %zu bytes.", size);
199
-
200
- memcpy(p, ptr, size);
201
- return p;
202
-}
203
-
204
-#define malloc(size) malloc_debug(__FILE__, __LINE__, __FUNCTION__, (size))
205
-#define calloc(nmemb, size) calloc_debug(__FILE__, __LINE__, __FUNCTION__, (nmemb), (size))
206
-#define realloc(ptr, size) realloc_debug(__FILE__, __LINE__, __FUNCTION__, (ptr), (size))
207
-#define free(ptr) free_debug(__FILE__, __LINE__, __FUNCTION__, (ptr))
208
-
209
-#ifdef strdup
210
-#undef strdup
211
-#endif
212
-#define strdup(ptr) strdup_debug(__FILE__, __LINE__, __FUNCTION__, (ptr))
213
-
214
-#endif /* NETDATA_INTERNAL_CHECKS */
61
62
// ----------------------------------------------------------------------------
63
@@ -254,9 +100,9 @@ long get_system_cpus(void) {
100
return processors;
101
}
102
257
-long get_system_pid_max(void) {
103
+pid_t get_system_pid_max(void) {
104
procfile *ff = NULL;
259
- long mpid = 32768;
105
+ pid_t mpid = 32768;
106
107
char filename[FILENAME_MAX + 1];
108
snprintfz(filename, FILENAME_MAX, "%s/proc/sys/kernel/pid_max", host_prefix);
@@ -269,7 +115,7 @@ long get_system_pid_max(void) {
115
return mpid;
116
}
117
272
- mpid = atol(procfile_lineword(ff, 0, 0));
118
+ mpid = (pid_t)atoi(procfile_lineword(ff, 0, 0));
119
if(!mpid) mpid = 32768;
120
121
procfile_close(ff);
@@ -304,14 +150,14 @@ struct target {
150
unsigned long long num_threads;
151
unsigned long long rss;
152
307
- unsigned long long fix_minflt;
308
- unsigned long long fix_cminflt;
309
- unsigned long long fix_majflt;
310
- unsigned long long fix_cmajflt;
311
- unsigned long long fix_utime;
312
- unsigned long long fix_stime;
313
- unsigned long long fix_cutime;
314
- unsigned long long fix_cstime;
153
+ long long fix_minflt;
154
+ long long fix_cminflt;
155
+ long long fix_majflt;
156
+ long long fix_cmajflt;
157
+ long long fix_utime;
158
+ long long fix_stime;
159
+ long long fix_cutime;
160
+ long long fix_cstime;
161
162
unsigned long long statm_size;
163
unsigned long long statm_resident;
@@ -675,14 +521,20 @@ struct pid_stat {
521
// we will subtract these values from the old
522
// target
523
unsigned long long last_minflt;
678
- unsigned long long last_cminflt;
524
unsigned long long last_majflt;
680
- unsigned long long last_cmajflt;
525
unsigned long long last_utime;
526
unsigned long long last_stime;
527
+
528
+ unsigned long long last_cminflt;
529
+ unsigned long long last_cmajflt;
530
unsigned long long last_cutime;
531
unsigned long long last_cstime;
532
533
+ unsigned long long last_fix_cminflt;
534
+ unsigned long long last_fix_cmajflt;
535
+ unsigned long long last_fix_cutime;
536
+ unsigned long long last_fix_cstime;
537
+
538
unsigned long long last_io_logical_bytes_read;
539
unsigned long long last_io_logical_bytes_written;
540
unsigned long long last_io_read_calls;
@@ -691,27 +543,10 @@ struct pid_stat {
543
unsigned long long last_io_storage_bytes_written;
544
unsigned long long last_io_cancelled_write_bytes;
545
694
-#ifdef AGGREGATE_CHILDREN_TO_PARENTS
695
- unsigned long long old_utime;
696
- unsigned long long old_stime;
697
- unsigned long long old_minflt;
698
- unsigned long long old_majflt;
699
-
700
- unsigned long long old_cutime;
701
- unsigned long long old_cstime;
702
- unsigned long long old_cminflt;
703
- unsigned long long old_cmajflt;
704
-
705
- unsigned long long fix_cutime;
706
- unsigned long long fix_cstime;
546
unsigned long long fix_cminflt;
547
unsigned long long fix_cmajflt;
709
-
710
- unsigned long long diff_cutime;
711
- unsigned long long diff_cstime;
712
- unsigned long long diff_cminflt;
713
- unsigned long long diff_cmajflt;
714
-#endif /* AGGREGATE_CHILDREN_TO_PARENTS */
548
+ unsigned long long fix_cutime;
549
+ unsigned long long fix_cstime;
550
551
int *fds; // array of fds it uses
552
int fds_size; // the size of the fds array
@@ -765,7 +600,8 @@ void del_pid_entry(pid_t pid)
600
{
601
if(!all_pids[pid]) return;
602
768
- if(debug) fprintf(stderr, "apps.plugin: process %d %s exited, deleting it.\n", pid, all_pids[pid]->comm);
603
+ if(unlikely(debug))
604
+ fprintf(stderr, "apps.plugin: process %d %s exited, deleting it.\n", pid, all_pids[pid]->comm);
605
606
if(root_of_pids == all_pids[pid]) root_of_pids = all_pids[pid]->next;
607
if(all_pids[pid]->next) all_pids[pid]->next->prev = all_pids[pid]->prev;
@@ -898,7 +734,7 @@ int read_proc_pid_stat(struct pid_stat *p) {
734
// p->guest_time = strtoull(procfile_lineword(ff, 0, 42+i), NULL, 10);
735
// p->cguest_time = strtoull(procfile_lineword(ff, 0, 43), NULL, 10);
736
901
- if(debug || (p->target && p->target->debug))
737
+ if(unlikely(debug || (p->target && p->target->debug)))
738
fprintf(stderr, "apps.plugin: READ PROC/PID/STAT: %s/proc/%d/stat, process: '%s' 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->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt, p->num_threads);
739
740
// procfile_close(ff);
@@ -1048,13 +884,16 @@ void file_descriptor_not_used(int id)
884
}
885
#endif /* NETDATA_INTERNAL_CHECKS */
886
1051
- if(debug) fprintf(stderr, "apps.plugin: decreasing slot %d (count = %d).\n", id, all_files[id].count);
887
+ if(unlikely(debug))
888
+ fprintf(stderr, "apps.plugin: decreasing slot %d (count = %d).\n", id, all_files[id].count);
889
890
if(all_files[id].count > 0) {
891
all_files[id].count--;
892
893
if(!all_files[id].count) {
1057
- if(debug) fprintf(stderr, "apps.plugin: >> slot %d is empty.\n", id);
894
+ if(unlikely(debug))
895
+ fprintf(stderr, "apps.plugin: >> slot %d is empty.\n", id);
896
+
897
file_descriptor_remove(&all_files[id]);
898
#ifdef NETDATA_INTERNAL_CHECKS
899
all_files[id].magic = 0x00000000;
@@ -1073,12 +912,15 @@ int file_descriptor_find_or_add(const char *name)
912
static int last_pos = 0;
913
uint32_t hash = simple_hash(name);
914
1076
- if(debug) fprintf(stderr, "apps.plugin: adding or finding name '%s' with hash %u\n", name, hash);
915
+ if(unlikely(debug))
916
+ fprintf(stderr, "apps.plugin: adding or finding name '%s' with hash %u\n", name, hash);
917
918
struct file_descriptor *fd = file_descriptor_find(name, hash);
919
if(fd) {
920
// found
1081
- if(debug) fprintf(stderr, "apps.plugin: >> found on slot %d\n", fd->pos);
921
+ if(unlikely(debug))
922
+ fprintf(stderr, "apps.plugin: >> found on slot %d\n", fd->pos);
923
+
924
fd->count++;
925
return fd->pos;
926
}
@@ -1090,19 +932,25 @@ int file_descriptor_find_or_add(const char *name)
932
int i;
933
934
// there is no empty slot
1093
- if(debug) fprintf(stderr, "apps.plugin: extending fd array to %d entries\n", all_files_size + FILE_DESCRIPTORS_INCREASE_STEP);
935
+ if(unlikely(debug))
936
+ fprintf(stderr, "apps.plugin: extending fd array to %d entries\n", all_files_size + FILE_DESCRIPTORS_INCREASE_STEP);
937
+
938
all_files = realloc(all_files, (all_files_size + FILE_DESCRIPTORS_INCREASE_STEP) * sizeof(struct file_descriptor));
939
940
// if the address changed, we have to rebuild the index
941
// since all pointers are now invalid
942
if(old && old != (void *)all_files) {
1099
- if(debug) fprintf(stderr, "apps.plugin: >> re-indexing.\n");
943
+ if(unlikely(debug))
944
+ fprintf(stderr, "apps.plugin: >> re-indexing.\n");
945
+
946
all_files_index.root = NULL;
947
for(i = 0; i < all_files_size; i++) {
948
if(!all_files[i].count) continue;
949
file_descriptor_add(&all_files[i]);
950
}
1105
- if(debug) fprintf(stderr, "apps.plugin: >> re-indexing done.\n");
951
+
952
+ if(unlikely(debug))
953
+ fprintf(stderr, "apps.plugin: >> re-indexing done.\n");
954
}
955
956
for(i = all_files_size; i < (all_files_size + FILE_DESCRIPTORS_INCREASE_STEP); i++) {
@@ -1118,7 +966,8 @@ int file_descriptor_find_or_add(const char *name)
966
all_files_size += FILE_DESCRIPTORS_INCREASE_STEP;
967
}
968
1121
- if(debug) fprintf(stderr, "apps.plugin: >> searching for empty slot.\n");
969
+ if(unlikely(debug))
970
+ fprintf(stderr, "apps.plugin: >> searching for empty slot.\n");
971
972
// search for an empty slot
973
int i, c;
@@ -1127,14 +976,17 @@ int file_descriptor_find_or_add(const char *name)
976
if(c == 0) continue;
977
978
if(!all_files[c].count) {
1130
- if(debug) fprintf(stderr, "apps.plugin: >> Examining slot %d.\n", c);
979
+ if(unlikely(debug))
980
+ fprintf(stderr, "apps.plugin: >> Examining slot %d.\n", c);
981
982
#ifdef NETDATA_INTERNAL_CHECKS
983
if(all_files[c].magic == 0x0BADCAFE && all_files[c].name && file_descriptor_find(all_files[c].name, all_files[c].hash))
984
error("fd on position %d is not cleared properly. It still has %s in it.\n", c, all_files[c].name);
985
#endif /* NETDATA_INTERNAL_CHECKS */
986
1137
- if(debug) fprintf(stderr, "apps.plugin: >> %s fd position %d for %s (last name: %s)\n", all_files[c].name?"re-using":"using", c, name, all_files[c].name);
987
+ if(unlikely(debug))
988
+ fprintf(stderr, "apps.plugin: >> %s fd position %d for %s (last name: %s)\n", all_files[c].name?"re-using":"using", c, name, all_files[c].name);
989
+
990
if(all_files[c].name) free((void *)all_files[c].name);
991
all_files[c].name = NULL;
992
last_pos = c;
@@ -1145,7 +997,9 @@ int file_descriptor_find_or_add(const char *name)
997
fatal("We should find an empty slot, but there isn't any");
998
exit(1);
999
}
1148
- if(debug) fprintf(stderr, "apps.plugin: >> updating slot %d.\n", c);
1000
+
1001
+ if(unlikely(debug))
1002
+ fprintf(stderr, "apps.plugin: >> updating slot %d.\n", c);
1003
1004
all_files_len++;
1005
@@ -1161,11 +1015,15 @@ int file_descriptor_find_or_add(const char *name)
1015
else if(strcmp(name, "anon_inode:[timerfd]") == 0) type = FILETYPE_TIMERFD;
1016
else if(strcmp(name, "anon_inode:[signalfd]") == 0) type = FILETYPE_SIGNALFD;
1017
else if(strncmp(name, "anon_inode:", 11) == 0) {
1164
- if(debug) fprintf(stderr, "apps.plugin: FIXME: unknown anonymous inode: %s\n", name);
1018
+ if(unlikely(debug))
1019
+ fprintf(stderr, "apps.plugin: FIXME: unknown anonymous inode: %s\n", name);
1020
+
1021
type = FILETYPE_OTHER;
1022
}
1023
else {
1168
- if(debug) fprintf(stderr, "apps.plugin: FIXME: cannot understand linkname: %s\n", name);
1024
+ if(unlikely(debug))
1025
+ fprintf(stderr, "apps.plugin: FIXME: cannot understand linkname: %s\n", name);
1026
+
1027
type = FILETYPE_OTHER;
1028
}
1029
@@ -1179,7 +1037,8 @@ int file_descriptor_find_or_add(const char *name)
1037
#endif /* NETDATA_INTERNAL_CHECKS */
1038
file_descriptor_add(&all_files[c]);
1039
1182
- if(debug) fprintf(stderr, "apps.plugin: using fd position %d (name: %s)\n", c, all_files[c].name);
1040
+ if(unlikely(debug))
1041
+ fprintf(stderr, "apps.plugin: using fd position %d (name: %s)\n", c, all_files[c].name);
1042
1043
return c;
1044
}
@@ -1208,7 +1067,9 @@ int read_pid_file_descriptors(struct pid_stat *p) {
1067
if(fdid < 0) continue;
1068
if(fdid >= p->fds_size) {
1069
// it is small, extend it
1211
- if(debug) fprintf(stderr, "apps.plugin: extending fd memory slots for %s from %d to %d\n", p->comm, p->fds_size, fdid + 100);
1070
+ if(unlikely(debug))
1071
+ fprintf(stderr, "apps.plugin: extending fd memory slots for %s from %d to %d\n", p->comm, p->fds_size, fdid + 100);
1072
+
1073
p->fds = realloc(p->fds, (fdid + 100) * sizeof(int));
1074
if(!p->fds) {
1075
fatal("Cannot re-allocate fds for %s", p->comm);
@@ -1297,15 +1158,21 @@ int collect_data_for_all_processes_from_proc(void)
1158
p->merged = 0;
1159
p->new_entry = 0;
1160
1300
- p->last_minflt = p->minflt;
1301
- p->last_cminflt = p->cminflt;
1302
- p->last_majflt = p->majflt;
1303
- p->last_cmajflt = p->cmajflt;
1161
+ p->last_minflt = p->minflt;
1162
+ p->last_majflt = p->majflt;
1163
p->last_utime = p->utime;
1164
p->last_stime = p->stime;
1165
+
1166
+ p->last_cminflt = p->cminflt;
1167
+ p->last_cmajflt = p->cmajflt;
1168
p->last_cutime = p->cutime;
1169
p->last_cstime = p->cstime;
1170
1171
+ p->last_fix_cminflt = p->fix_cminflt;
1172
+ p->last_fix_cmajflt = p->fix_cmajflt;
1173
+ p->last_fix_cutime = p->fix_cutime;
1174
+ p->last_fix_cstime = p->fix_cstime;
1175
+
1176
p->last_io_logical_bytes_read = p->io_logical_bytes_read;
1177
p->last_io_logical_bytes_written = p->io_logical_bytes_written;
1178
p->last_io_read_calls = p->io_read_calls;
@@ -1320,8 +1187,13 @@ int collect_data_for_all_processes_from_proc(void)
1187
pid_t pid = (pid_t) strtoul(file->d_name, &endptr, 10);
1188
1189
// make sure we read a valid number
1323
- if(unlikely(pid <= 0 || pid > pid_max || endptr == file->d_name || *endptr != '\0'))
1190
+ if(unlikely(endptr == file->d_name || *endptr != '\0'))
1191
+ continue;
1192
+
1193
+ if(unlikely(pid <= 0 || pid > pid_max)) {
1194
+ error("Invalid pid %d read (expected 1 to %d). Ignoring process.", pid, pid_max);
1195
continue;
1196
+ }
1197
1198
p = get_pid_entry(pid);
1199
if(unlikely(!p)) continue;
@@ -1388,7 +1260,9 @@ int collect_data_for_all_processes_from_proc(void)
1260
// check if it is target
1261
// we do this only once, the first time this pid is loaded
1262
if(unlikely(p->new_entry)) {
1391
- if(debug) fprintf(stderr, "apps.plugin: \tJust added %s\n", p->comm);
1263
+ if(unlikely(debug))
1264
+ fprintf(stderr, "apps.plugin: \tJust added %s\n", p->comm);
1265
+
1266
uint32_t hash = simple_hash(p->comm);
1267
size_t pclen = strlen(p->comm);
1268
@@ -1434,49 +1308,6 @@ int collect_data_for_all_processes_from_proc(void)
1308
return 1;
1309
}
1310
1437
-
1438
-// ----------------------------------------------------------------------------
1439
-
1440
-#ifdef AGGREGATE_CHILDREN_TO_PARENTS
1441
-// print a tree view of all processes
1442
-int debug_childrens_aggregations(pid_t pid, int level) {
1443
- struct pid_stat *p = NULL;
1444
- char b[level+3];
1445
- int i, ret = 0;
1446
-
1447
- for(i = 0; i < level; i++) b[i] = '\t';
1448
- b[level] = '|';
1449
- b[level+1] = '-';
1450
- b[level+2] = '\0';
1451
-
1452
- for(p = root_of_pids; p ; p = p->next) {
1453
- if(p->ppid == pid) {
1454
- ret += debug_childrens_aggregations(p->pid, level+1);
1455
- }
1456
- }
1457
-
1458
- p = all_pids[pid];
1459
- if(p) {
1460
- if(!p->updated) ret += 1;
1461
- 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"
1462
- , b, p->comm, p->pid, p->updated?"OK":"KILLED", p->target->name, p->children_count
1463
- , p->utime, p->utime - p->old_utime
1464
- , p->stime, p->stime - p->old_stime
1465
- , p->cutime, p->cutime - p->old_cutime
1466
- , p->cstime, p->cstime - p->old_cstime
1467
- , p->minflt, p->minflt - p->old_minflt
1468
- , p->majflt, p->majflt - p->old_majflt
1469
- , p->cminflt, p->cminflt - p->old_cminflt
1470
- , p->cmajflt, p->cmajflt - p->old_cmajflt
1471
- );
1472
- }
1473
-
1474
- return ret;
1475
-}
1476
-#endif /* AGGREGATE_CHILDREN_TO_PARENTS */
1477
-
1478
-
1479
-
1311
// ----------------------------------------------------------------------------
1312
// update statistics on the targets
1313
@@ -1501,81 +1332,41 @@ void link_all_processes_to_their_parents(void) {
1332
for(p = root_of_pids; p ; p = p->next) {
1333
// for each process found running
1334
1504
- if(p->ppid > 0
1505
- && p->ppid <= pid_max
1506
- && all_pids[p->ppid]
1507
- ) {
1335
+ if(likely(p->ppid > 0 && all_pids[p->ppid])) {
1336
// for valid processes
1337
1510
- if(debug || (p->target && p->target->debug))
1338
+ if(unlikely(debug || (p->target && p->target->debug)))
1339
fprintf(stderr, "apps.plugin: \tparent of %d (%s) is %d (%s)\n", p->pid, p->comm, p->ppid, all_pids[p->ppid]->comm);
1340
1341
p->parent = all_pids[p->ppid];
1342
p->parent->children_count++;
1515
- }
1516
- else if(p->ppid != 0)
1517
- error("pid %d %s states parent %d, but the later does not exist.", p->pid, p->comm, p->ppid);
1518
- }
1519
-}
1343
1521
-#ifdef AGGREGATE_CHILDREN_TO_PARENTS
1522
-void aggregate_children_to_parents(void) {
1523
- struct pid_stat *p = NULL;
1344
+ if(unlikely(!p->updated)) {
1345
+ struct pid_stat *pp = p;
1346
1525
- // for each killed process, remove its values from the parents
1526
- // sums (we had already added them in a previous loop)
1527
- for(p = root_of_pids; p ; p = p->next) {
1528
- if(p->updated) continue;
1529
-
1530
- if(debug) fprintf(stderr, "apps.plugin: UNMERGING %d %s\n", p->pid, p->comm);
1531
-
1532
- unsigned long long diff_utime = p->utime + p->cutime + p->fix_cutime;
1533
- unsigned long long diff_stime = p->stime + p->cstime + p->fix_cstime;
1534
- unsigned long long diff_minflt = p->minflt + p->cminflt + p->fix_cminflt;
1535
- unsigned long long diff_majflt = p->majflt + p->cmajflt + p->fix_cmajflt;
1536
-
1537
- struct pid_stat *t = p;
1538
- while((t = t->parent)) {
1539
- if(!t->updated) continue;
1540
-
1541
- unsigned long long x;
1542
- if(diff_utime && t->diff_cutime) {
1543
- x = (t->diff_cutime < diff_utime)?t->diff_cutime:diff_utime;
1544
- diff_utime -= x;
1545
- t->diff_cutime -= x;
1546
- t->fix_cutime += x;
1547
- if(debug) fprintf(stderr, "apps.plugin: \t cutime %llu from %d %s %s\n", x, t->pid, t->comm, t->target->name);
1548
- }
1549
- if(diff_stime && t->diff_cstime) {
1550
- x = (t->diff_cstime < diff_stime)?t->diff_cstime:diff_stime;
1551
- diff_stime -= x;
1552
- t->diff_cstime -= x;
1553
- t->fix_cstime += x;
1554
- if(debug) fprintf(stderr, "apps.plugin: \t cstime %llu from %d %s %s\n", x, t->pid, t->comm, t->target->name);
1555
- }
1556
- if(diff_minflt && t->diff_cminflt) {
1557
- x = (t->diff_cminflt < diff_minflt)?t->diff_cminflt:diff_minflt;
1558
- diff_minflt -= x;
1559
- t->diff_cminflt -= x;
1560
- t->fix_cminflt += x;
1561
- if(debug) fprintf(stderr, "apps.plugin: \t cminflt %llu from %d %s %s\n", x, t->pid, t->comm, t->target->name);
1562
- }
1563
- if(diff_majflt && t->diff_cmajflt) {
1564
- x = (t->diff_cmajflt < diff_majflt)?t->diff_cmajflt:diff_majflt;
1565
- diff_majflt -= x;
1566
- t->diff_cmajflt -= x;
1567
- t->fix_cmajflt += x;
1568
- if(debug) fprintf(stderr, "apps.plugin: \t cmajflt %llu from %d %s %s\n", x, t->pid, t->comm, t->target->name);
1347
+ // find the first parent that
1348
+ // has been updated
1349
+ while(pp && !pp->updated)
1350
+ pp = pp->parent;
1351
+
1352
+ if(likely(pp)) {
1353
+ // this is an exited child with a parent
1354
+ // remove the known time from the parent's data
1355
+ pp->fix_cminflt += p->minflt + p->cminflt + p->fix_cminflt;
1356
+ pp->fix_cmajflt += p->majflt + p->cmajflt + p->fix_cmajflt;
1357
+ pp->fix_cutime += p->utime + p->cutime + p->fix_cutime;
1358
+ pp->fix_cstime += p->stime + p->cstime + p->fix_cstime;
1359
+
1360
+ if(unlikely(debug))
1361
+ fprintf(stderr, "apps.plugin: \tfixing child counters of %d (%s) to %d (%s). Fixes: cutime=%llu, cstime=%llu, cminflt=%llu, cmajflt=%llu\n", p->pid, p->comm, pp->pid, pp->comm, pp->fix_cutime, pp->fix_cstime, pp->fix_cminflt, pp->fix_cmajflt);
1362
+ }
1363
}
1364
}
1571
-
1572
- if(diff_utime) error("Cannot fix up utime %llu", diff_utime);
1573
- if(diff_stime) error("Cannot fix up stime %llu", diff_stime);
1574
- if(diff_minflt) error("Cannot fix up minflt %llu", diff_minflt);
1575
- if(diff_majflt) error("Cannot fix up majflt %llu", diff_majflt);
1365
+ else if(unlikely(p->ppid != 0))
1366
+ error("pid %d %s states parent %d, but the later does not exist.", p->pid, p->comm, p->ppid);
1367
}
1368
}
1578
-#endif /* AGGREGATE_CHILDREN_TO_PARENTS */
1369
+
1370
1371
void cleanup_non_existing_pids(void) {
1372
int c;
@@ -1603,8 +1394,9 @@ void apply_apps_groups_targets_inheritance(void) {
1394
1395
// children that do not have a target
1396
// inherit their target from their parent
1606
- int found = 1;
1397
+ int found = 1, loops = 0;
1398
while(found) {
1399
+ if(unlikely(debug)) loops++;
1400
found = 0;
1401
for(p = root_of_pids; p ; p = p->next) {
1402
// if this process does not have a target
@@ -1626,6 +1418,7 @@ void apply_apps_groups_targets_inheritance(void) {
1418
// repeat, until nothing more can be done.
1419
found = 1;
1420
while(found) {
1421
+ if(unlikely(debug)) loops++;
1422
found = 0;
1423
for(p = root_of_pids; p ; p = p->next) {
1424
// if this process does not have any children
@@ -1658,7 +1451,7 @@ void apply_apps_groups_targets_inheritance(void) {
1451
}
1452
}
1453
1661
- if(debug)
1454
+ if(unlikely(debug))
1455
fprintf(stderr, "apps.plugin: merged %d processes\n", found);
1456
}
1457
@@ -1667,25 +1460,18 @@ void apply_apps_groups_targets_inheritance(void) {
1460
all_pids[1]->target = apps_groups_default_target;
1461
1462
// give a default target on all top level processes
1463
+ if(unlikely(debug)) loops++;
1464
for(p = root_of_pids; p ; p = p->next) {
1465
// if the process is not merged itself
1466
// then is is a top level process
1467
if(!p->merged && !p->target)
1468
p->target = apps_groups_default_target;
1675
-
1676
-#ifdef AGGREGATE_CHILDREN_TO_PARENTS
1677
- // by the way, update the diffs
1678
- // will be used later for subtracting killed process times
1679
- p->diff_cutime = p->utime - p->cutime;
1680
- p->diff_cstime = p->stime - p->cstime;
1681
- p->diff_cminflt = p->minflt - p->cminflt;
1682
- p->diff_cmajflt = p->majflt - p->cmajflt;
1683
-#endif /* AGGREGATE_CHILDREN_TO_PARENTS */
1469
}
1470
1471
// give a target to all merged child processes
1472
found = 1;
1473
while(found) {
1474
+ if(unlikely(debug)) loops++;
1475
found = 0;
1476
for(p = root_of_pids; p ; p = p->next) {
1477
if(unlikely(!p->target && p->merged && p->parent && p->parent->target)) {
@@ -1697,6 +1483,9 @@ void apply_apps_groups_targets_inheritance(void) {
1483
}
1484
}
1485
}
1486
+
1487
+ if(unlikely(debug))
1488
+ fprintf(stderr, "apps.plugin: apply_apps_groups_targets_inheritance() made %d loops on the process tree\n", loops);
1489
}
1490
1491
long zero_all_targets(struct target *root) {
@@ -1749,10 +1538,13 @@ void aggregate_pid_on_target(struct target *w, struct pid_stat *p, struct target
1538
}
1539
1540
if(likely(p->updated)) {
1752
- w->cutime += p->cutime; // - p->fix_cutime;
1753
- w->cstime += p->cstime; // - p->fix_cstime;
1754
- w->cminflt += p->cminflt; // - p->fix_cminflt;
1755
- w->cmajflt += p->cmajflt; // - p->fix_cmajflt;
1541
+ if(unlikely(debug && (p->fix_cutime || p->fix_cstime || p->fix_cminflt || p->fix_cmajflt)))
1542
+ fprintf(stderr, "apps.plugin: \tadding child counters of %d (%s) to target %s. Currents: cutime=%llu, cstime=%llu, cminflt=%llu, cmajflt=%llu, Fixes: cutime=%llu, cstime=%llu, cminflt=%llu, cmajflt=%llu\n", p->pid, p->comm, w->name, p->cutime, p->cstime, p->cminflt, p->cmajflt, p->fix_cutime, p->fix_cstime, p->fix_cminflt, p->fix_cmajflt);
1543
+
1544
+ w->cutime += p->cutime - p->fix_cutime;
1545
+ w->cstime += p->cstime - p->fix_cstime;
1546
+ w->cminflt += p->cminflt - p->fix_cminflt;
1547
+ w->cmajflt += p->cmajflt - p->fix_cmajflt;
1548
1549
w->utime += p->utime; //+ (p->pid != 1)?(p->cutime - p->fix_cutime):0;
1550
w->stime += p->stime; //+ (p->pid != 1)?(p->cstime - p->fix_cstime):0;
@@ -1800,7 +1592,7 @@ void aggregate_pid_on_target(struct target *w, struct pid_stat *p, struct target
1592
}
1593
1594
if(unlikely(debug || w->debug))
1803
- fprintf(stderr, "apps.plugin: \tAggregating %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, w->name, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);
1595
+ fprintf(stderr, "apps.plugin: \tAggregating %s pid %d on %s utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu, fix_cutime=%llu, fix_cstime=%llu, fix_cminflt=%llu, fix_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, p->fix_cutime, p->fix_cstime, p->fix_cminflt, p->fix_cmajflt);
1596
1597
/* 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);
1598
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);
@@ -1811,16 +1603,6 @@ void aggregate_pid_on_target(struct target *w, struct pid_stat *p, struct target
1603
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);
1604
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);
1605
*/
1814
-#ifdef AGGREGATE_CHILDREN_TO_PARENTS
1815
- p->old_utime = p->utime;
1816
- p->old_cutime = p->cutime;
1817
- p->old_stime = p->stime;
1818
- p->old_cstime = p->cstime;
1819
- p->old_minflt = p->minflt;
1820
- p->old_majflt = p->majflt;
1821
- p->old_cminflt = p->cminflt;
1822
- p->old_cmajflt = p->cmajflt;
1823
-#endif /* AGGREGATE_CHILDREN_TO_PARENTS */
1606
1607
if(o) {
1608
// since the process switched target
@@ -1831,17 +1613,16 @@ void aggregate_pid_on_target(struct target *w, struct pid_stat *p, struct target
1613
// IMPORTANT
1614
// We add/subtract the last/OLD values we added to the target
1615
1834
- w->fix_cutime -= p->last_cutime;
1835
- w->fix_cstime -= p->last_cstime;
1836
- w->fix_cminflt -= p->last_cminflt;
1837
- w->fix_cmajflt -= p->last_cmajflt;
1616
+ w->fix_cutime -= (p->last_cutime - p->last_fix_cutime);
1617
+ w->fix_cstime -= (p->last_cstime - p->last_fix_cstime);
1618
+ w->fix_cminflt -= (p->last_cminflt - p->last_fix_cminflt);
1619
+ w->fix_cmajflt -= (p->last_cmajflt - p->last_fix_cmajflt);
1620
1621
w->fix_utime -= p->last_utime;
1622
w->fix_stime -= p->last_stime;
1623
w->fix_minflt -= p->last_minflt;
1624
w->fix_majflt -= p->last_majflt;
1625
1844
-
1626
w->fix_io_logical_bytes_read -= p->last_io_logical_bytes_read;
1627
w->fix_io_logical_bytes_written -= p->last_io_logical_bytes_written;
1628
w->fix_io_read_calls -= p->last_io_read_calls;
@@ -1852,10 +1633,10 @@ void aggregate_pid_on_target(struct target *w, struct pid_stat *p, struct target
1633
1634
// ---
1635
1855
- o->fix_cutime += p->last_cutime;
1856
- o->fix_cstime += p->last_cstime;
1857
- o->fix_cminflt += p->last_cminflt;
1858
- o->fix_cmajflt += p->last_cmajflt;
1636
+ o->fix_cutime += (p->last_cutime - p->last_fix_cutime);
1637
+ o->fix_cstime += (p->last_cstime - p->last_fix_cstime);
1638
+ o->fix_cminflt += (p->last_cminflt - p->last_fix_cminflt);
1639
+ o->fix_cmajflt += (p->last_cmajflt - p->last_fix_cmajflt);
1640
1641
o->fix_utime += p->last_utime;
1642
o->fix_stime += p->last_stime;
@@ -1884,10 +1665,11 @@ void aggregate_pid_on_target(struct target *w, struct pid_stat *p, struct target
1665
w->fix_majflt += p->majflt;
1666
w->fix_utime += p->utime;
1667
w->fix_stime += p->stime;
1887
- w->fix_cminflt += p->cminflt;
1888
- w->fix_cmajflt += p->cmajflt;
1889
- w->fix_cutime += p->cutime;
1890
- w->fix_cstime += p->cstime;
1668
+
1669
+ w->fix_cminflt += (p->cminflt - p->fix_cminflt);
1670
+ w->fix_cmajflt += (p->cmajflt - p->fix_cmajflt);
1671
+ w->fix_cutime += (p->cutime - p->fix_cutime);
1672
+ w->fix_cstime += (p->cstime - p->fix_cstime);
1673
1674
w->fix_io_logical_bytes_read += p->io_logical_bytes_read;
1675
w->fix_io_logical_bytes_written += p->io_logical_bytes_written;
@@ -1967,19 +1749,10 @@ void calculate_netdata_statistics(void)
1749
link_all_processes_to_their_parents();
1750
apply_apps_groups_targets_inheritance();
1751
1970
-#ifdef AGGREGATE_CHILDREN_TO_PARENTS
1971
- aggregate_children_to_parents();
1972
-#endif /* AGGREGATE_CHILDREN_TO_PARENTS */
1973
-
1752
zero_all_targets(users_root_target);
1753
zero_all_targets(groups_root_target);
1754
apps_groups_targets = zero_all_targets(apps_groups_root_target);
1755
1978
-#ifdef AGGREGATE_CHILDREN_TO_PARENTS
1979
- if(debug)
1980
- debug_childrens_aggregations(0, 1);
1981
-#endif /* AGGREGATE_CHILDREN_TO_PARENTS */
1982
-
1756
// this has to be done, before the cleanup
1757
struct pid_stat *p = NULL;
1758
struct target *w = NULL, *o = NULL;
@@ -2099,7 +1872,7 @@ void send_collected_data_to_netdata(struct target *root, const char *type, unsig
1872
for (w = root; w ; w = w->next) {
1873
if(w->target || (!w->processes && !w->exposed)) continue;
1874
2102
- fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + w->stime + w->fix_utime + w->fix_stime);
1875
+ fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + w->stime + w->fix_utime + w->fix_stime + w->cutime + w->cstime + w->fix_cutime + w->fix_cstime);
1876
}
1877
fprintf(stdout, "END\n");
1878
@@ -2107,7 +1880,7 @@ void send_collected_data_to_netdata(struct target *root, const char *type, unsig
1880
for (w = root; w ; w = w->next) {
1881
if(w->target || (!w->processes && !w->exposed)) continue;
1882
2110
- fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + w->fix_utime);
1883
+ fprintf(stdout, "SET %s = %llu\n", w->name, w->utime + w->fix_utime + w->cutime + w->fix_cutime);
1884
}
1885
fprintf(stdout, "END\n");
1886
@@ -2115,7 +1888,7 @@ void send_collected_data_to_netdata(struct target *root, const char *type, unsig
1888
for (w = root; w ; w = w->next) {
1889
if(w->target || (!w->processes && !w->exposed)) continue;
1890
2118
- fprintf(stdout, "SET %s = %llu\n", w->name, w->stime + w->fix_stime);
1891
+ fprintf(stdout, "SET %s = %llu\n", w->name, w->stime + w->fix_stime + w->cstime + w->fix_cstime);
1892
}
1893
fprintf(stdout, "END\n");
1894
@@ -2147,7 +1920,7 @@ void send_collected_data_to_netdata(struct target *root, const char *type, unsig
1920
for (w = root; w ; w = w->next) {
1921
if(w->target || (!w->processes && !w->exposed)) continue;
1922
2150
- fprintf(stdout, "SET %s = %llu\n", w->name, w->minflt + w->fix_minflt);
1923
+ fprintf(stdout, "SET %s = %llu\n", w->name, w->minflt + w->fix_minflt + w->cminflt + w->fix_cminflt);
1924
}
1925
fprintf(stdout, "END\n");
1926
@@ -2155,7 +1928,7 @@ void send_collected_data_to_netdata(struct target *root, const char *type, unsig
1928
for (w = root; w ; w = w->next) {
1929
if(w->target || (!w->processes && !w->exposed)) continue;
1930
2158
- fprintf(stdout, "SET %s = %llu\n", w->name, w->majflt + w->fix_majflt);
1931
+ fprintf(stdout, "SET %s = %llu\n", w->name, w->majflt + w->fix_majflt + w->cmajflt + w->fix_cmajflt);
1932
}
1933
fprintf(stdout, "END\n");
1934
@@ -2239,7 +2012,7 @@ void send_charts_updates_to_netdata(struct target *root, const char *type, const
2012
2013
// we have something new to show
2014
// update the charts
2242
- fprintf(stdout, "CHART %s.cpu '' '%s CPU Time (%ld%% = %ld core%s)' 'cpu time %%' cpu %s.cpu stacked 20001 %d\n", type, title, (processors * 100), processors, (processors>1)?"s":"", type, update_every);
2015
+ fprintf(stdout, "CHART %s.cpu '' '%s CPU Time (%d%% = %d core%s)' 'cpu time %%' cpu %s.cpu stacked 20001 %d\n", type, title, (processors * 100), processors, (processors>1)?"s":"", type, update_every);
2016
for (w = root; w ; w = w->next) {
2017
if(w->target || (!w->processes && !w->exposed)) continue;
2018
@@ -2267,18 +2040,18 @@ void send_charts_updates_to_netdata(struct target *root, const char *type, const
2040
fprintf(stdout, "DIMENSION %s '' absolute 1 1 noreset\n", w->name);
2041
}
2042
2270
- fprintf(stdout, "CHART %s.cpu_user '' '%s CPU User Time (%ld%% = %ld core%s)' 'cpu time %%' cpu %s.cpu_user stacked 20020 %d\n", type, title, (processors * 100), processors, (processors>1)?"s":"", type, update_every);
2043
+ fprintf(stdout, "CHART %s.cpu_user '' '%s CPU User Time (%d%% = %d core%s)' 'cpu time %%' cpu %s.cpu_user stacked 20020 %d\n", type, title, (processors * 100), processors, (processors>1)?"s":"", type, update_every);
2044
for (w = root; w ; w = w->next) {
2045
if(w->target || (!w->processes && !w->exposed)) continue;
2046
2274
- fprintf(stdout, "DIMENSION %s '' incremental 100 %ld noreset\n", w->name, hz * processors);
2047
+ fprintf(stdout, "DIMENSION %s '' incremental 100 %d noreset\n", w->name, hz);
2048
}
2049
2277
- fprintf(stdout, "CHART %s.cpu_system '' '%s CPU System Time (%ld%% = %ld core%s)' 'cpu time %%' cpu %s.cpu_system stacked 20021 %d\n", type, title, (processors * 100), processors, (processors>1)?"s":"", type, update_every);
2050
+ fprintf(stdout, "CHART %s.cpu_system '' '%s CPU System Time (%d%% = %d core%s)' 'cpu time %%' cpu %s.cpu_system stacked 20021 %d\n", type, title, (processors * 100), processors, (processors>1)?"s":"", type, update_every);
2051
for (w = root; w ; w = w->next) {
2052
if(w->target || (!w->processes && !w->exposed)) continue;
2053
2281
- fprintf(stdout, "DIMENSION %s '' incremental 100 %ld noreset\n", w->name, hz * processors);
2054
+ fprintf(stdout, "DIMENSION %s '' incremental 100 %d noreset\n", w->name, hz);
2055
}
2056
2057
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);
@@ -2488,7 +2261,8 @@ int main(int argc, char **argv)
2261
send_collected_data_to_netdata(users_root_target, "users", dt);
2262
send_collected_data_to_netdata(groups_root_target, "groups", dt);
2263
2491
- if(debug) fprintf(stderr, "apps.plugin: done Loop No %llu\n", counter);
2264
+ if(unlikely(debug))
2265
+ fprintf(stderr, "apps.plugin: done Loop No %llu\n", counter);
2266
2267
current_t = time(NULL);
2268
web/index.html
+3
-3
@@ -1325,19 +1325,19 @@ var menuData = {
1325
1326
'apps': {
1327
title: 'Applications',
1328
- info: 'Per application statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics for applications of interest, defined in <code>/etc/netdata/apps_groups.conf</code> (the default is <a href="https://github.com/firehol/netdata/blob/master/conf.d/apps_groups.conf" target="_blank">here</a>). The plugin internally builds a process tree (much like <code>ps fax</code> does), and groups processes together (evaluating both child and parent processes) so that the result is always a chart with a predefined set of dimensions (of course, only application groups found running are reported).<br/><b>IMPORTANT</b>: The values shown here are not 100% accurate. They only include values for the processes running. If an application is spawning children continuously, which are terminated in just a few milliseconds (like shell scripts do), the values reported will be inaccurate. Linux does report the values for the exited children of a process. However, these values are reported to the parent process <b>only when the child exits</b>. If these values, of the exited child processes, were also aggregated in the charts below, the charts would have been full of spikes, presenting unrealistic utilization for each process group. So, we decided to ignore these values and present only the utilization of <b>the currently running processes</b>.',
1328
+ info: 'Per application statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics for applications of interest, defined in <code>/etc/netdata/apps_groups.conf</code> (the default is <a href="https://github.com/firehol/netdata/blob/master/conf.d/apps_groups.conf" target="_blank">here</a>). The plugin internally builds a process tree (much like <code>ps fax</code> does), and groups processes together (evaluating both child and parent processes) so that the result is always a chart with a predefined set of dimensions (of course, only application groups found running are reported).',
1329
height: 1.5
1330
},
1331
1332
'users': {
1333
title: 'Users',
1334
- info: 'Per user statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics per user.<br/><b>IMPORTANT</b>: The values shown here are not 100% accurate. They only include values for the processes running. If an application is spawning children continuously, which are terminated in just a few milliseconds (like shell scripts do), the values reported will be inaccurate. Linux does report the values for the exited children of a process. However, these values are reported to the parent process <b>only when the child exits</b>. If these values, of the exited child processes, were also aggregated in the charts below, the charts would have been full of spikes, presenting unrealistic utilization for each process group. So, we decided to ignore these values and present only the utilization of <b>the currently running processes</b>.',
1334
+ info: 'Per user statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics per user.',
1335
height: 1.5
1336
},
1337
1338
'groups': {
1339
title: 'User Groups',
1340
- info: 'Per user group statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics per user group.<br/><b>IMPORTANT</b>: The values shown here are not 100% accurate. They only include values for the processes running. If an application is spawning children continuously, which are terminated in just a few milliseconds (like shell scripts do), the values reported will be inaccurate. Linux does report the values for the exited children of a process. However, these values are reported to the parent process <b>only when the child exits</b>. If these values, of the exited child processes, were also aggregated in the charts below, the charts would have been full of spikes, presenting unrealistic utilization for each process group. So, we decided to ignore these values and present only the utilization of <b>the currently running processes</b>.',
1340
+ info: 'Per user group statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics per user group.',
1341
height: 1.5
1342
},
1343