]> arthur.barton.de Git - netdata.git/commitdiff
cgroups CPU usage is per core; fixes #906
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Wed, 7 Sep 2016 07:04:05 +0000 (10:04 +0300)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Wed, 7 Sep 2016 07:04:05 +0000 (10:04 +0300)
src/apps_plugin.c
src/common.c
src/common.h
src/main.c
src/sys_fs_cgroup.c

index ee400b72e1dc670c6197fb0fb8d1205230a0a9f6..59c27e6208034e8d826013b8e97e13290b15084c 100644 (file)
@@ -13,8 +13,6 @@
 // etc.
 #define RATES_DETAIL 10000ULL
 
-int processors = 1;
-pid_t pid_max = 32768;
 int debug = 0;
 
 int update_every = 1;
@@ -22,7 +20,6 @@ unsigned long long global_iterations_counter = 1;
 unsigned long long file_counter = 0;
 int proc_pid_cmdline_is_needed = 0;
 int include_exited_childs = 1;
-char *host_prefix = "";
 char *config_dir = CONFIG_DIR;
 
 pid_t *all_pids_sortlist = NULL;
@@ -41,58 +38,6 @@ void netdata_cleanup_and_exit(int ret) {
 }
 
 
-// ----------------------------------------------------------------------------
-// system functions
-// to retrieve settings of the system
-
-long get_system_cpus(void) {
-    procfile *ff = NULL;
-
-    int processors = 0;
-
-    char filename[FILENAME_MAX + 1];
-    snprintfz(filename, FILENAME_MAX, "%s/proc/stat", host_prefix);
-
-    ff = procfile_open(filename, NULL, PROCFILE_FLAG_DEFAULT);
-    if(!ff) return 1;
-
-    ff = procfile_readall(ff);
-    if(!ff)
-        return 1;
-
-    unsigned int i;
-    for(i = 0; i < procfile_lines(ff); i++) {
-        if(!procfile_linewords(ff, i)) continue;
-
-        if(strncmp(procfile_lineword(ff, i, 0), "cpu", 3) == 0) processors++;
-    }
-    processors--;
-    if(processors < 1) processors = 1;
-
-    procfile_close(ff);
-    return processors;
-}
-
-pid_t get_system_pid_max(void) {
-    procfile *ff = NULL;
-    pid_t mpid = 32768;
-
-    char filename[FILENAME_MAX + 1];
-    snprintfz(filename, FILENAME_MAX, "%s/proc/sys/kernel/pid_max", host_prefix);
-    ff = procfile_open(filename, NULL, PROCFILE_FLAG_DEFAULT);
-    if(!ff) return mpid;
-
-    ff = procfile_readall(ff);
-    if(!ff)
-        return mpid;
-
-    mpid = (pid_t)atoi(procfile_lineword(ff, 0, 0));
-    if(!mpid) mpid = 32768;
-
-    procfile_close(ff);
-    return mpid;
-}
-
 // ----------------------------------------------------------------------------
 // target
 // target is the structure that process data are aggregated
@@ -576,7 +521,7 @@ int read_proc_pid_cmdline(struct pid_stat *p) {
     
     if(unlikely(!p->cmdline_filename)) {
         char filename[FILENAME_MAX + 1];
-        snprintfz(filename, FILENAME_MAX, "%s/proc/%d/cmdline", host_prefix, p->pid);
+        snprintfz(filename, FILENAME_MAX, "%s/proc/%d/cmdline", global_host_prefix, p->pid);
         p->cmdline_filename = strdupz(filename);
     }
 
@@ -629,7 +574,7 @@ int read_proc_pid_stat(struct pid_stat *p) {
 
     if(unlikely(!p->stat_filename)) {
         char filename[FILENAME_MAX + 1];
-        snprintfz(filename, FILENAME_MAX, "%s/proc/%d/stat", host_prefix, p->pid);
+        snprintfz(filename, FILENAME_MAX, "%s/proc/%d/stat", global_host_prefix, p->pid);
         p->stat_filename = strdupz(filename);
     }
 
@@ -737,7 +682,7 @@ int read_proc_pid_stat(struct pid_stat *p) {
     }
 
     if(unlikely(debug || (p->target && p->target->debug)))
-        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);
+        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);
 
     if(unlikely(global_iterations_counter == 1)) {
         p->minflt           = 0;
@@ -775,7 +720,7 @@ int read_proc_pid_statm(struct pid_stat *p) {
 
     if(unlikely(!p->statm_filename)) {
         char filename[FILENAME_MAX + 1];
-        snprintfz(filename, FILENAME_MAX, "%s/proc/%d/statm", host_prefix, p->pid);
+        snprintfz(filename, FILENAME_MAX, "%s/proc/%d/statm", global_host_prefix, p->pid);
         p->statm_filename = strdupz(filename);
     }
 
@@ -813,7 +758,7 @@ int read_proc_pid_io(struct pid_stat *p) {
 
     if(unlikely(!p->io_filename)) {
         char filename[FILENAME_MAX + 1];
-        snprintfz(filename, FILENAME_MAX, "%s/proc/%d/io", host_prefix, p->pid);
+        snprintfz(filename, FILENAME_MAX, "%s/proc/%d/io", global_host_prefix, p->pid);
         p->io_filename = strdupz(filename);
     }
 
@@ -892,7 +837,7 @@ int read_proc_stat() {
     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;
 
     if(unlikely(!ff)) {
-        snprintfz(filename, FILENAME_MAX, "%s/proc/stat", host_prefix);
+        snprintfz(filename, FILENAME_MAX, "%s/proc/stat", global_host_prefix);
         ff = procfile_open(filename, " \t:", PROCFILE_FLAG_DEFAULT);
         if(unlikely(!ff)) goto cleanup;
     }
@@ -1194,7 +1139,7 @@ int file_descriptor_find_or_add(const char *name)
 int read_pid_file_descriptors(struct pid_stat *p) {
     char dirname[FILENAME_MAX+1];
 
-    snprintfz(dirname, FILENAME_MAX, "%s/proc/%d/fd", host_prefix, p->pid);
+    snprintfz(dirname, FILENAME_MAX, "%s/proc/%d/fd", global_host_prefix, p->pid);
     DIR *fds = opendir(dirname);
     if(fds) {
         int c;
@@ -1232,7 +1177,7 @@ int read_pid_file_descriptors(struct pid_stat *p) {
             if(p->fds[fdid] == 0) {
                 // we don't know this fd, get it
 
-                sprintf(fdname, "%s/proc/%d/fd/%s", host_prefix, p->pid, de->d_name);
+                sprintf(fdname, "%s/proc/%d/fd/%s", global_host_prefix, p->pid, de->d_name);
                 ssize_t l = readlink(fdname, linkname, FILENAME_MAX);
                 if(l == -1) {
                     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) {
                 p->log_thrown |= log;
                 switch(log) {
                     case PID_LOG_IO:
-                        error("Cannot process %s/proc/%d/io (command '%s')", host_prefix, p->pid, p->comm);
+                        error("Cannot process %s/proc/%d/io (command '%s')", global_host_prefix, p->pid, p->comm);
                         break;
 
                     case PID_LOG_STATM:
-                        error("Cannot process %s/proc/%d/statm (command '%s')", host_prefix, p->pid, p->comm);
+                        error("Cannot process %s/proc/%d/statm (command '%s')", global_host_prefix, p->pid, p->comm);
                         break;
 
                     case PID_LOG_CMDLINE:
-                        error("Cannot process %s/proc/%d/cmdline (command '%s')", host_prefix, p->pid, p->comm);
+                        error("Cannot process %s/proc/%d/cmdline (command '%s')", global_host_prefix, p->pid, p->comm);
                         break;
 
                     case PID_LOG_FDS:
-                        error("Cannot process entries in %s/proc/%d/fd (command '%s')", host_prefix, p->pid, p->comm);
+                        error("Cannot process entries in %s/proc/%d/fd (command '%s')", global_host_prefix, p->pid, p->comm);
                         break;
 
                     case PID_LOG_STAT:
@@ -1751,7 +1696,7 @@ int collect_data_for_all_processes_from_proc(void) {
 
     char dirname[FILENAME_MAX + 1];
 
-    snprintfz(dirname, FILENAME_MAX, "%s/proc", host_prefix);
+    snprintfz(dirname, FILENAME_MAX, "%s/proc", global_host_prefix);
     DIR *dir = opendir(dirname);
     if(!dir) return 0;
 
@@ -2803,12 +2748,12 @@ int main(int argc, char **argv)
     error_log_errors_per_period = 100;
     error_log_throttle_period = 3600;
 
-    host_prefix = getenv("NETDATA_HOST_PREFIX");
-    if(host_prefix == NULL) {
+    global_host_prefix = getenv("NETDATA_HOST_PREFIX");
+    if(global_host_prefix == NULL) {
         // info("NETDATA_HOST_PREFIX is not passed from netdata");
-        host_prefix = "";
+        global_host_prefix = "";
     }
-    // else info("Found NETDATA_HOST_PREFIX='%s'", host_prefix);
+    // else info("Found NETDATA_HOST_PREFIX='%s'", global_host_prefix);
 
     config_dir = getenv("NETDATA_CONFIG_DIR");
     if(config_dir == NULL) {
@@ -2830,9 +2775,9 @@ int main(int argc, char **argv)
 
     time_t started_t = time(NULL);
     time_t current_t;
-    get_HZ();
-    pid_max = get_system_pid_max();
-    processors = get_system_cpus();
+    get_system_HZ();
+    get_system_pid_max();
+    get_system_cpus();
 
     parse_args(argc, argv);
 
index 7d0fac9aacab013d43e3d8e5dba757ddbdf8c389..6c18c380ff48fa746e7675fe69b24248e17bacaf 100644 (file)
@@ -860,23 +860,6 @@ int fd_is_valid(int fd) {
     return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
 }
 
-/*
- ***************************************************************************
- * Get number of clock ticks per second.
- ***************************************************************************
- */
-unsigned int hz;
-
-void get_HZ(void) {
-    long ticks;
-
-    if ((ticks = sysconf(_SC_CLK_TCK)) == -1) {
-        perror("sysconf");
-    }
-
-    hz = (unsigned int) ticks;
-}
-
 pid_t gettid(void) {
     return (pid_t)syscall(SYS_gettid);
 }
@@ -933,3 +916,86 @@ int snprintfz(char *dst, size_t n, const char *fmt, ...) {
 
     return ret;
 }
+
+// ----------------------------------------------------------------------------
+// system functions
+// to retrieve settings of the system
+
+int processors = 1;
+long get_system_cpus(void) {
+    procfile *ff = NULL;
+
+    processors = 1;
+
+    char filename[FILENAME_MAX + 1];
+    snprintfz(filename, FILENAME_MAX, "%s/proc/stat", global_host_prefix);
+
+    ff = procfile_open(filename, NULL, PROCFILE_FLAG_DEFAULT);
+    if(!ff) {
+        error("Cannot open file '%s'. Assuming system has %d processors.", filename, processors);
+        return processors;
+    }
+
+    ff = procfile_readall(ff);
+    if(!ff) {
+        error("Cannot open file '%s'. Assuming system has %d processors.", filename, processors);
+        return processors;
+    }
+
+    processors = 0;
+    unsigned int i;
+    for(i = 0; i < procfile_lines(ff); i++) {
+        if(!procfile_linewords(ff, i)) continue;
+
+        if(strncmp(procfile_lineword(ff, i, 0), "cpu", 3) == 0) processors++;
+    }
+    processors--;
+    if(processors < 1) processors = 1;
+
+    procfile_close(ff);
+
+    info("System has %d processors.", processors);
+    return processors;
+}
+
+pid_t pid_max = 32768;
+pid_t get_system_pid_max(void) {
+    procfile *ff = NULL;
+
+    char filename[FILENAME_MAX + 1];
+    snprintfz(filename, FILENAME_MAX, "%s/proc/sys/kernel/pid_max", global_host_prefix);
+    ff = procfile_open(filename, NULL, PROCFILE_FLAG_DEFAULT);
+    if(!ff) {
+        error("Cannot open file '%s'. Assuming system supports %d pids.", filename, pid_max);
+        return pid_max;
+    }
+
+    ff = procfile_readall(ff);
+    if(!ff) {
+        error("Cannot read file '%s'. Assuming system supports %d pids.", filename, pid_max);
+        return pid_max;
+    }
+
+    pid_max = (pid_t)atoi(procfile_lineword(ff, 0, 0));
+    if(!pid_max) {
+        procfile_close(ff);
+        pid_max = 32768;
+        error("Cannot parse file '%s'. Assuming system supports %d pids.", filename, pid_max);
+        return pid_max;
+    }
+
+    procfile_close(ff);
+    info("System supports %d pids.", pid_max);
+    return pid_max;
+}
+
+unsigned int hz;
+void get_system_HZ(void) {
+    long ticks;
+
+    if ((ticks = sysconf(_SC_CLK_TCK)) == -1) {
+        perror("sysconf");
+    }
+
+    hz = (unsigned int) ticks;
+}
index a6e85034bf80995b6049725039274e6d516087c8..f94565f1b7b9166451df3b852db01cdf2b7a9c5a 100644 (file)
@@ -153,10 +153,6 @@ extern int fd_is_valid(int fd);
 extern char *global_host_prefix;
 extern int enable_ksm;
 
-/* Number of ticks per second */
-extern unsigned int hz;
-extern void get_HZ(void);
-
 extern pid_t gettid(void);
 
 extern unsigned long long time_usec(void);
@@ -164,6 +160,17 @@ extern int sleep_usec(unsigned long long usec);
 
 extern char *fgets_trim_len(char *buf, size_t buf_size, FILE *fp, size_t *len);
 
+extern int processors;
+extern long get_system_cpus(void);
+
+extern pid_t pid_max;
+extern pid_t get_system_pid_max(void);
+
+/* Number of ticks per second */
+extern unsigned int hz;
+extern void get_system_HZ(void);
+
+
 /* fix for alpine linux */
 #ifndef RUSAGE_THREAD
 #ifdef RUSAGE_CHILDREN
index 5dbd575805c870d90891d086528aa02c4f5d7123..79b09237875134ca78c0f24b051265fd3860e6f8 100644 (file)
@@ -283,9 +283,6 @@ int main(int argc, char **argv)
     size_t wanted_stacksize = 0, stacksize = 0;
     pthread_attr_t attr;
 
-    // global initialization
-    get_HZ();
-
     // set the name for logging
     program_name = "netdata";
 
@@ -472,6 +469,10 @@ int main(int argc, char **argv)
         global_host_prefix = config_get("global", "host access prefix", "");
         setenv("NETDATA_HOST_PREFIX", global_host_prefix, 1);
 
+        get_system_HZ();
+        get_system_cpus();
+        get_system_pid_max();
+        
         // --------------------------------------------------------------------
 
         stdout_filename    = config_get("global", "debug log",  LOG_DIR "/debug.log");
index fe9bbc47328147c0413e203eef3c64d7c53b7521..0ffd55e21cef17b14491fd277213d3a771be7830 100644 (file)
@@ -1077,7 +1077,7 @@ void update_cgroup_charts(int update_every) {
         if(cg->cpuacct_stat.updated) {
             st = rrdset_find_bytype(type, "cpu");
             if(!st) {
-                snprintfz(title, CHART_TITLE_MAX, "CPU Usage for cgroup %s", cg->chart_title);
+                snprintfz(title, CHART_TITLE_MAX, "CPU Usage (%d%% = %d core%s) for cgroup %s", (processors * 100), processors, (processors>1)?"s":"", cg->chart_title);
                 st = rrdset_create(type, "cpu", NULL, "cpu", "cgroup.cpu", title, "%", 40000, update_every, RRDSET_TYPE_STACKED);
 
                 rrddim_add(st, "user", NULL, 100, hz, RRDDIM_INCREMENTAL);
@@ -1096,7 +1096,7 @@ void update_cgroup_charts(int update_every) {
 
             st = rrdset_find_bytype(type, "cpu_per_core");
             if(!st) {
-                snprintfz(title, CHART_TITLE_MAX, "CPU Usage Per Core for cgroup %s", cg->chart_title);
+                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);
                 st = rrdset_create(type, "cpu_per_core", NULL, "cpu", "cgroup.cpu_per_core", title, "%", 40100, update_every, RRDSET_TYPE_STACKED);
 
                 for(i = 0; i < cg->cpuacct_usage.cpus ;i++) {