collectd.conf(5): Add documentation for the "netcmd" plugin.
[collectd.git] / src / processes.c
index 7306edb..a6c5096 100644 (file)
@@ -362,7 +362,7 @@ static int ps_list_match (const char *name, const char *cmdline, procstat_t *ps)
 static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t *entry)
 {
        procstat_t *ps;
-        procstat_entry_t *pse;
+       procstat_entry_t *pse;
 
        if (entry->id == 0)
                return;
@@ -498,7 +498,6 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t
 
                ps->cpu_user_counter   += pse->cpu_user;
                ps->cpu_system_counter += pse->cpu_system;
-
        }
 }
 
@@ -610,14 +609,7 @@ static int ps_config (oconfig_item_t *ci)
                }
                else if (strcasecmp (c->key, "CollectContextSwitch") == 0)
                {
-                       if ((c->values_num != 1) 
-                                       || (c->values[0].type != OCONFIG_TYPE_BOOLEAN))
-                       {
-                               ERROR ("processes plugin: `CollectContextSwitch' needs exactly "
-                                               "one boolean argument.");
-                               continue;
-                       }
-                       report_ctx_switch = c->values[0].value.boolean ? 1 : 0;
+                       cf_util_get_boolean (c, &report_ctx_switch);
                }
                else
                {
@@ -770,12 +762,14 @@ static void ps_submit_proc_list (procstat_t *ps)
 
        if ( report_ctx_switch )
        {
-               sstrncpy (vl.type, "ps_cswitch_vol", sizeof (vl.type));
+               sstrncpy (vl.type, "contextswitch", sizeof (vl.type));
+               sstrncpy (vl.type_instance, "voluntary", sizeof (vl.type_instance));
                vl.values[0].derive = ps->cswitch_vol;
                vl.values_len = 1;
                plugin_dispatch_values (&vl);
 
-               sstrncpy (vl.type, "ps_cswitch_invol", sizeof (vl.type));
+               sstrncpy (vl.type, "contextswitch", sizeof (vl.type));
+               sstrncpy (vl.type_instance, "involuntary", sizeof (vl.type_instance));
                vl.values[0].derive = ps->cswitch_invol;
                vl.values_len = 1;
                plugin_dispatch_values (&vl);
@@ -827,8 +821,8 @@ static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps)
        char           filename[64];
        FILE          *fh;
        struct dirent *ent;
-       unsigned long long cswitch_vol = 0;
-       unsigned long long cswitch_invol = 0;
+       derive_t cswitch_vol = 0;
+       derive_t cswitch_invol = 0;
        char buffer[1024];
        char *fields[8];
        int numfields;
@@ -859,7 +853,7 @@ static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps)
 
                while (fgets (buffer, sizeof(buffer), fh) != NULL)
                {
-                       long long tmp;
+                       derive_t tmp;
                        char *endptr;
 
                        if (strncmp (buffer, "voluntary_ctxt_switches", 23) != 0
@@ -874,7 +868,7 @@ static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps)
 
                        errno = 0;
                        endptr = NULL;
-                       tmp = strtoll (fields[1], &endptr, /* base = */ 10);
+                       tmp = (derive_t) strtoll (fields[1], &endptr, /* base = */ 10);
                        if ((errno == 0) && (endptr != fields[1]))
                        {
                                if (strncmp (buffer, "voluntary_ctxt_switches", 23) == 0)
@@ -903,42 +897,16 @@ static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps)
        return (ps);
 } /* int *ps_read_tasks_status */
 
-static int ps_read_tasks (int pid)
-{
-       char           dirname[64];
-       DIR           *dh;
-       struct dirent *ent;
-       int count = 0;
-
-       ssnprintf (dirname, sizeof (dirname), "/proc/%i/task", pid);
-
-       if ((dh = opendir (dirname)) == NULL)
-       {
-               DEBUG ("Failed to open directory `%s'", dirname);
-               return (-1);
-       }
-
-       while ((ent = readdir (dh)) != NULL)
-       {
-               if (!isdigit ((int) ent->d_name[0]))
-                       continue;
-               else
-                       count++;
-       }
-       closedir (dh);
-
-       return ((count >= 1) ? count : 1);
-} /* int *ps_read_tasks */
-
-/* Read advanced virtual memory data from /proc/pid/status */
-static procstat_t *ps_read_vmem (int pid, procstat_t *ps)
+/* Read data from /proc/pid/status */
+static procstat_t *ps_read_status (int pid, procstat_t *ps)
 {
        FILE *fh;
        char buffer[1024];
        char filename[64];
-       unsigned long long lib = 0;
-       unsigned long long exe = 0;
-       unsigned long long data = 0;
+       unsigned long lib = 0;
+       unsigned long exe = 0;
+       unsigned long data = 0;
+       unsigned long threads = 0;
        char *fields[8];
        int numfields;
 
@@ -948,10 +916,11 @@ static procstat_t *ps_read_vmem (int pid, procstat_t *ps)
 
        while (fgets (buffer, sizeof(buffer), fh) != NULL)
        {
-               long long tmp;
+               unsigned long tmp;
                char *endptr;
 
-               if (strncmp (buffer, "Vm", 2) != 0)
+               if (strncmp (buffer, "Vm", 2) != 0
+                               && strncmp (buffer, "Threads", 7) != 0)
                        continue;
 
                numfields = strsplit (buffer, fields,
@@ -962,7 +931,7 @@ static procstat_t *ps_read_vmem (int pid, procstat_t *ps)
 
                errno = 0;
                endptr = NULL;
-               tmp = strtoll (fields[1], &endptr, /* base = */ 10);
+               tmp = strtoul (fields[1], &endptr, /* base = */ 10);
                if ((errno == 0) && (endptr != fields[1]))
                {
                        if (strncmp (buffer, "VmData", 6) == 0)
@@ -977,6 +946,10 @@ static procstat_t *ps_read_vmem (int pid, procstat_t *ps)
                        {
                                exe = tmp;
                        }
+                       else if  (strncmp(buffer, "Threads", 7) == 0)
+                       {
+                               threads = tmp;
+                       }
                }
        } /* while (fgets) */
 
@@ -989,6 +962,8 @@ static procstat_t *ps_read_vmem (int pid, procstat_t *ps)
 
        ps->vmem_data = data * 1024;
        ps->vmem_code = (exe + lib) * 1024;
+       if (threads != 0)
+               ps->num_lwp = threads;
 
        return (ps);
 } /* procstat_t *ps_read_vmem */
@@ -1131,11 +1106,16 @@ int ps_read_process (int pid, procstat_t *ps, char *state)
        }
        else
        {
-               if ( (ps->num_lwp = ps_read_tasks (pid)) == -1 )
+               ps->num_lwp = strtoul (fields[17], /* endptr = */ NULL, /* base = */ 10);
+               if ((ps_read_status(pid, ps)) == NULL)
                {
-                       /* returns -1 => kernel 2.4 */
-                       ps->num_lwp = 1;
+                       /* No VMem data */
+                       ps->vmem_data = -1;
+                       ps->vmem_code = -1;
+                       DEBUG("ps_read_process: did not get vmem data for pid %i",pid);
                }
+               if (ps->num_lwp <= 0)
+                       ps->num_lwp = 1;
                ps->num_proc = 1;
        }
 
@@ -1168,14 +1148,6 @@ int ps_read_process (int pid, procstat_t *ps, char *state)
        cpu_system_counter = cpu_system_counter * 1000000 / CONFIG_HZ;
        vmem_rss = vmem_rss * pagesize_g;
 
-       if ( (ps_read_vmem(pid, ps)) == NULL)
-       {
-               /* No VMem data */
-               ps->vmem_data = -1;
-               ps->vmem_code = -1;
-               DEBUG("ps_read_process: did not get vmem data for pid %i",pid);
-       }
-
        ps->cpu_user_counter = cpu_user_counter;
        ps->cpu_system_counter = cpu_system_counter;
        ps->vmem_size = (unsigned long) vmem_size;