@cryptotaxi247 / netdata-1 / commits / 7b7b03d9a

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++) {