cgroups CPU usage is per core; fixes #906
Costa Tsaousis (ktsaou) committed
Sep 7, 2016 at 10:04 UTC
7b7b03d9aa337d65728dea613b20e00df873af17
5 files changed
+120
-101
src/apps_plugin.c
+20
-75
@@ -13,8 +13,6 @@
13
// etc.
14
#define RATES_DETAIL 10000ULL
15
16
-int processors = 1;
17
-pid_t pid_max = 32768;
16
int debug = 0;
17
18
int update_every = 1;
@@ -22,7 +20,6 @@ unsigned long long global_iterations_counter = 1;
20
unsigned long long file_counter = 0;
21
int proc_pid_cmdline_is_needed = 0;
22
int include_exited_childs = 1;
25
-char *host_prefix = "";
23
char *config_dir = CONFIG_DIR;
24
25
pid_t *all_pids_sortlist = NULL;
@@ -41,58 +38,6 @@ void netdata_cleanup_and_exit(int ret) {
38
}
39
40
44
-// ----------------------------------------------------------------------------
45
-// system functions
46
-// to retrieve settings of the system
47
-
48
-long get_system_cpus(void) {
49
- procfile *ff = NULL;
50
-
51
- int processors = 0;
52
-
53
- char filename[FILENAME_MAX + 1];
54
- snprintfz(filename, FILENAME_MAX, "%s/proc/stat", host_prefix);
55
-
56
- ff = procfile_open(filename, NULL, PROCFILE_FLAG_DEFAULT);
57
- if(!ff) return 1;
58
-
59
- ff = procfile_readall(ff);
60
- if(!ff)
61
- return 1;
62
-
63
- unsigned int i;
64
- for(i = 0; i < procfile_lines(ff); i++) {
65
- if(!procfile_linewords(ff, i)) continue;
66
-
67
- if(strncmp(procfile_lineword(ff, i, 0), "cpu", 3) == 0) processors++;
68
- }
69
- processors--;
70
- if(processors < 1) processors = 1;
71
-
72
- procfile_close(ff);
73
- return processors;
74
-}
75
-
76
-pid_t get_system_pid_max(void) {
77
- procfile *ff = NULL;
78
- pid_t mpid = 32768;
79
-
80
- char filename[FILENAME_MAX + 1];
81
- snprintfz(filename, FILENAME_MAX, "%s/proc/sys/kernel/pid_max", host_prefix);
82
- ff = procfile_open(filename, NULL, PROCFILE_FLAG_DEFAULT);
83
- if(!ff) return mpid;
84
-
85
- ff = procfile_readall(ff);
86
- if(!ff)
87
- return mpid;
88
-
89
- mpid = (pid_t)atoi(procfile_lineword(ff, 0, 0));
90
- if(!mpid) mpid = 32768;
91
-
92
- procfile_close(ff);
93
- return mpid;
94
-}
95
-
41
// ----------------------------------------------------------------------------
42
// target
43
// target is the structure that process data are aggregated
@@ -576,7 +521,7 @@ int read_proc_pid_cmdline(struct pid_stat *p) {
521
522
if(unlikely(!p->cmdline_filename)) {
523
char filename[FILENAME_MAX + 1];
579
- snprintfz(filename, FILENAME_MAX, "%s/proc/%d/cmdline", host_prefix, p->pid);
524
+ snprintfz(filename, FILENAME_MAX, "%s/proc/%d/cmdline", global_host_prefix, p->pid);
525
p->cmdline_filename = strdupz(filename);
526
}
527
@@ -629,7 +574,7 @@ int read_proc_pid_stat(struct pid_stat *p) {
574
575
if(unlikely(!p->stat_filename)) {
576
char filename[FILENAME_MAX + 1];
632
- snprintfz(filename, FILENAME_MAX, "%s/proc/%d/stat", host_prefix, p->pid);
577
+ snprintfz(filename, FILENAME_MAX, "%s/proc/%d/stat", global_host_prefix, p->pid);
578
p->stat_filename = strdupz(filename);
579
}
580
@@ -737,7 +682,7 @@ int read_proc_pid_stat(struct pid_stat *p) {
682
}
683
684
if(unlikely(debug || (p->target && p->target->debug)))
740
- 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);
685
+ 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", global_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);
686
687
if(unlikely(global_iterations_counter == 1)) {
688
p->minflt = 0;
@@ -775,7 +720,7 @@ int read_proc_pid_statm(struct pid_stat *p) {
720
721
if(unlikely(!p->statm_filename)) {
722
char filename[FILENAME_MAX + 1];
778
- snprintfz(filename, FILENAME_MAX, "%s/proc/%d/statm", host_prefix, p->pid);
723
+ snprintfz(filename, FILENAME_MAX, "%s/proc/%d/statm", global_host_prefix, p->pid);
724
p->statm_filename = strdupz(filename);
725
}
726
@@ -813,7 +758,7 @@ int read_proc_pid_io(struct pid_stat *p) {
758
759
if(unlikely(!p->io_filename)) {
760
char filename[FILENAME_MAX + 1];
816
- snprintfz(filename, FILENAME_MAX, "%s/proc/%d/io", host_prefix, p->pid);
761
+ snprintfz(filename, FILENAME_MAX, "%s/proc/%d/io", global_host_prefix, p->pid);
762
p->io_filename = strdupz(filename);
763
}
764
@@ -892,7 +837,7 @@ int read_proc_stat() {
837
static unsigned long long utime_raw = 0, stime_raw = 0, gtime_raw = 0, gntime_raw = 0, ntime_raw = 0, collected_usec = 0, last_collected_usec = 0;
838
839
if(unlikely(!ff)) {
895
- snprintfz(filename, FILENAME_MAX, "%s/proc/stat", host_prefix);
840
+ snprintfz(filename, FILENAME_MAX, "%s/proc/stat", global_host_prefix);
841
ff = procfile_open(filename, " \t:", PROCFILE_FLAG_DEFAULT);
842
if(unlikely(!ff)) goto cleanup;
843
}
@@ -1194,7 +1139,7 @@ int file_descriptor_find_or_add(const char *name)
1139
int read_pid_file_descriptors(struct pid_stat *p) {
1140
char dirname[FILENAME_MAX+1];
1141
1197
- snprintfz(dirname, FILENAME_MAX, "%s/proc/%d/fd", host_prefix, p->pid);
1142
+ snprintfz(dirname, FILENAME_MAX, "%s/proc/%d/fd", global_host_prefix, p->pid);
1143
DIR *fds = opendir(dirname);
1144
if(fds) {
1145
int c;
@@ -1232,7 +1177,7 @@ int read_pid_file_descriptors(struct pid_stat *p) {
1177
if(p->fds[fdid] == 0) {
1178
// we don't know this fd, get it
1179
1235
- sprintf(fdname, "%s/proc/%d/fd/%s", host_prefix, p->pid, de->d_name);
1180
+ sprintf(fdname, "%s/proc/%d/fd/%s", global_host_prefix, p->pid, de->d_name);
1181
ssize_t l = readlink(fdname, linkname, FILENAME_MAX);
1182
if(l == -1) {
1183
if(debug || (p->target && p->target->debug)) {
@@ -1583,19 +1528,19 @@ static inline int managed_log(struct pid_stat *p, uint32_t log, int status) {
1528
p->log_thrown |= log;
1529
switch(log) {
1530
case PID_LOG_IO:
1586
- error("Cannot process %s/proc/%d/io (command '%s')", host_prefix, p->pid, p->comm);
1531
+ error("Cannot process %s/proc/%d/io (command '%s')", global_host_prefix, p->pid, p->comm);
1532
break;
1533
1534
case PID_LOG_STATM:
1590
- error("Cannot process %s/proc/%d/statm (command '%s')", host_prefix, p->pid, p->comm);
1535
+ error("Cannot process %s/proc/%d/statm (command '%s')", global_host_prefix, p->pid, p->comm);
1536
break;
1537
1538
case PID_LOG_CMDLINE:
1594
- error("Cannot process %s/proc/%d/cmdline (command '%s')", host_prefix, p->pid, p->comm);
1539
+ error("Cannot process %s/proc/%d/cmdline (command '%s')", global_host_prefix, p->pid, p->comm);
1540
break;
1541
1542
case PID_LOG_FDS:
1598
- error("Cannot process entries in %s/proc/%d/fd (command '%s')", host_prefix, p->pid, p->comm);
1543
+ error("Cannot process entries in %s/proc/%d/fd (command '%s')", global_host_prefix, p->pid, p->comm);
1544
break;
1545
1546
case PID_LOG_STAT:
@@ -1751,7 +1696,7 @@ int collect_data_for_all_processes_from_proc(void) {
1696
1697
char dirname[FILENAME_MAX + 1];
1698
1754
- snprintfz(dirname, FILENAME_MAX, "%s/proc", host_prefix);
1699
+ snprintfz(dirname, FILENAME_MAX, "%s/proc", global_host_prefix);
1700
DIR *dir = opendir(dirname);
1701
if(!dir) return 0;
1702
@@ -2803,12 +2748,12 @@ int main(int argc, char **argv)
2748
error_log_errors_per_period = 100;
2749
error_log_throttle_period = 3600;
2750
2806
- host_prefix = getenv("NETDATA_HOST_PREFIX");
2807
- if(host_prefix == NULL) {
2751
+ global_host_prefix = getenv("NETDATA_HOST_PREFIX");
2752
+ if(global_host_prefix == NULL) {
2753
// info("NETDATA_HOST_PREFIX is not passed from netdata");
2809
- host_prefix = "";
2754
+ global_host_prefix = "";
2755
}
2811
- // else info("Found NETDATA_HOST_PREFIX='%s'", host_prefix);
2756
+ // else info("Found NETDATA_HOST_PREFIX='%s'", global_host_prefix);
2757
2758
config_dir = getenv("NETDATA_CONFIG_DIR");
2759
if(config_dir == NULL) {
@@ -2830,9 +2775,9 @@ int main(int argc, char **argv)
2775
2776
time_t started_t = time(NULL);
2777
time_t current_t;
2833
- get_HZ();
2834
- pid_max = get_system_pid_max();
2835
- processors = get_system_cpus();
2778
+ get_system_HZ();
2779
+ get_system_pid_max();
2780
+ get_system_cpus();
2781
2782
parse_args(argc, argv);
2783
src/common.c
+83
-17
@@ -860,23 +860,6 @@ int fd_is_valid(int fd) {
860
return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
861
}
862
863
-/*
864
- ***************************************************************************
865
- * Get number of clock ticks per second.
866
- ***************************************************************************
867
- */
868
-unsigned int hz;
869
-
870
-void get_HZ(void) {
871
- long ticks;
872
-
873
- if ((ticks = sysconf(_SC_CLK_TCK)) == -1) {
874
- perror("sysconf");
875
- }
876
-
877
- hz = (unsigned int) ticks;
878
-}
879
-
863
pid_t gettid(void) {
864
return (pid_t)syscall(SYS_gettid);
865
}
@@ -933,3 +916,86 @@ int snprintfz(char *dst, size_t n, const char *fmt, ...) {
916
917
return ret;
918
}
919
+
920
+// ----------------------------------------------------------------------------
921
+// system functions
922
+// to retrieve settings of the system
923
+
924
+int processors = 1;
925
+long get_system_cpus(void) {
926
+ procfile *ff = NULL;
927
+
928
+ processors = 1;
929
+
930
+ char filename[FILENAME_MAX + 1];
931
+ snprintfz(filename, FILENAME_MAX, "%s/proc/stat", global_host_prefix);
932
+
933
+ ff = procfile_open(filename, NULL, PROCFILE_FLAG_DEFAULT);
934
+ if(!ff) {
935
+ error("Cannot open file '%s'. Assuming system has %d processors.", filename, processors);
936
+ return processors;
937
+ }
938
+
939
+ ff = procfile_readall(ff);
940
+ if(!ff) {
941
+ error("Cannot open file '%s'. Assuming system has %d processors.", filename, processors);
942
+ return processors;
943
+ }
944
+
945
+ processors = 0;
946
+ unsigned int i;
947
+ for(i = 0; i < procfile_lines(ff); i++) {
948
+ if(!procfile_linewords(ff, i)) continue;
949
+
950
+ if(strncmp(procfile_lineword(ff, i, 0), "cpu", 3) == 0) processors++;
951
+ }
952
+ processors--;
953
+ if(processors < 1) processors = 1;
954
+
955
+ procfile_close(ff);
956
+
957
+ info("System has %d processors.", processors);
958
+ return processors;
959
+}
960
+
961
+pid_t pid_max = 32768;
962
+pid_t get_system_pid_max(void) {
963
+ procfile *ff = NULL;
964
+
965
+ char filename[FILENAME_MAX + 1];
966
+ snprintfz(filename, FILENAME_MAX, "%s/proc/sys/kernel/pid_max", global_host_prefix);
967
+ ff = procfile_open(filename, NULL, PROCFILE_FLAG_DEFAULT);
968
+ if(!ff) {
969
+ error("Cannot open file '%s'. Assuming system supports %d pids.", filename, pid_max);
970
+ return pid_max;
971
+ }
972
+
973
+ ff = procfile_readall(ff);
974
+ if(!ff) {
975
+ error("Cannot read file '%s'. Assuming system supports %d pids.", filename, pid_max);
976
+ return pid_max;
977
+ }
978
+
979
+ pid_max = (pid_t)atoi(procfile_lineword(ff, 0, 0));
980
+ if(!pid_max) {
981
+ procfile_close(ff);
982
+ pid_max = 32768;
983
+ error("Cannot parse file '%s'. Assuming system supports %d pids.", filename, pid_max);
984
+ return pid_max;
985
+ }
986
+
987
+ procfile_close(ff);
988
+ info("System supports %d pids.", pid_max);
989
+ return pid_max;
990
+}
991
+
992
+unsigned int hz;
993
+void get_system_HZ(void) {
994
+ long ticks;
995
+
996
+ if ((ticks = sysconf(_SC_CLK_TCK)) == -1) {
997
+ perror("sysconf");
998
+ }
999
+
1000
+ hz = (unsigned int) ticks;
1001
+}
src/common.h
+11
-4
@@ -153,10 +153,6 @@ extern int fd_is_valid(int fd);
153
extern char *global_host_prefix;
154
extern int enable_ksm;
155
156
-/* Number of ticks per second */
157
-extern unsigned int hz;
158
-extern void get_HZ(void);
159
-
156
extern pid_t gettid(void);
157
158
extern unsigned long long time_usec(void);
@@ -164,6 +160,17 @@ extern int sleep_usec(unsigned long long usec);
160
161
extern char *fgets_trim_len(char *buf, size_t buf_size, FILE *fp, size_t *len);
162
163
+extern int processors;
164
+extern long get_system_cpus(void);
165
+
166
+extern pid_t pid_max;
167
+extern pid_t get_system_pid_max(void);
168
+
169
+/* Number of ticks per second */
170
+extern unsigned int hz;
171
+extern void get_system_HZ(void);
172
+
173
+
174
/* fix for alpine linux */
175
#ifndef RUSAGE_THREAD
176
#ifdef RUSAGE_CHILDREN
src/main.c
+4
-3
@@ -283,9 +283,6 @@ int main(int argc, char **argv)
283
size_t wanted_stacksize = 0, stacksize = 0;
284
pthread_attr_t attr;
285
286
- // global initialization
287
- get_HZ();
288
-
286
// set the name for logging
287
program_name = "netdata";
288
@@ -472,6 +469,10 @@ int main(int argc, char **argv)
469
global_host_prefix = config_get("global", "host access prefix", "");
470
setenv("NETDATA_HOST_PREFIX", global_host_prefix, 1);
471
472
+ get_system_HZ();
473
+ get_system_cpus();
474
+ get_system_pid_max();
475
+
476
// --------------------------------------------------------------------
477
478
stdout_filename = config_get("global", "debug log", LOG_DIR "/debug.log");
src/sys_fs_cgroup.c
+2
-2
@@ -1077,7 +1077,7 @@ void update_cgroup_charts(int update_every) {
1077
if(cg->cpuacct_stat.updated) {
1078
st = rrdset_find_bytype(type, "cpu");
1079
if(!st) {
1080
- snprintfz(title, CHART_TITLE_MAX, "CPU Usage for cgroup %s", cg->chart_title);
1080
+ snprintfz(title, CHART_TITLE_MAX, "CPU Usage (%d%% = %d core%s) for cgroup %s", (processors * 100), processors, (processors>1)?"s":"", cg->chart_title);
1081
st = rrdset_create(type, "cpu", NULL, "cpu", "cgroup.cpu", title, "%", 40000, update_every, RRDSET_TYPE_STACKED);
1082
1083
rrddim_add(st, "user", NULL, 100, hz, RRDDIM_INCREMENTAL);
@@ -1096,7 +1096,7 @@ void update_cgroup_charts(int update_every) {
1096
1097
st = rrdset_find_bytype(type, "cpu_per_core");
1098
if(!st) {
1099
- snprintfz(title, CHART_TITLE_MAX, "CPU Usage Per Core for cgroup %s", cg->chart_title);
1099
+ snprintfz(title, CHART_TITLE_MAX, "CPU Usage (%d%% = %d core%s) Per Core for cgroup %s", (processors * 100), processors, (processors>1)?"s":"", cg->chart_title);
1100
st = rrdset_create(type, "cpu_per_core", NULL, "cpu", "cgroup.cpu_per_core", title, "%", 40100, update_every, RRDSET_TYPE_STACKED);
1101
1102
for(i = 0; i < cg->cpuacct_usage.cpus ;i++) {