a1df6ca2ee98e09374323406d3fe80dad503cd80
[collectd.git] / src / processes.c
1 /**
2  * collectd - src/processes.c
3  * Copyright (C) 2005  Lyonel Vincent
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18  *
19  * Authors:
20  *   Lyonel Vincent <lyonel at ezix.org>
21  *   Florian octo Forster <octo at verplant.org>
22  **/
23
24 #include "collectd.h"
25 #include "common.h"
26 #include "plugin.h"
27
28 #define MODULE_NAME "processes"
29
30 #ifdef KERNEL_LINUX
31 # define PROCESSES_HAVE_READ 1
32 #else
33 # define PROCESSES_HAVE_READ 0
34 #endif
35
36 #define BUFSIZE 256
37
38 static char *ps_file = "processes.rrd";
39
40 static char *ds_def[] =
41 {
42         "DS:running:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
43         "DS:sleeping:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
44         "DS:zombies:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
45         "DS:stopped:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
46         "DS:paging:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
47         "DS:blocked:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
48         NULL
49 };
50 static int ds_num = 6;
51
52 static void ps_init (void)
53 {
54 }
55
56 static void ps_write (char *host, char *inst, char *val)
57 {
58         rrd_update_file (host, ps_file, val, ds_def, ds_num);
59 }
60
61 #if PROCESSES_HAVE_READ
62 static void ps_submit (unsigned int running,
63                 unsigned int sleeping,
64                 unsigned int zombies,
65                 unsigned int stopped,
66                 unsigned int paging,
67                 unsigned int blocked)
68 {
69         char buf[BUFSIZE];
70
71         if (snprintf (buf, BUFSIZE, "%u:%u:%u:%u:%u:%u:%u",
72                                 (unsigned int) curtime,
73                                 running, sleeping, zombies, stopped, paging,
74                                 blocked) >= BUFSIZE)
75                 return;
76
77         plugin_submit (MODULE_NAME, "-", buf);
78 }
79
80 static void ps_read (void)
81 {
82 #ifdef KERNEL_LINUX
83         unsigned int running, sleeping, zombies, stopped, paging, blocked;
84
85         char buf[BUFSIZE];
86         char filename[20]; /* need 17 bytes */
87         char *fields[BUFSIZE];
88
89         struct dirent *ent;
90         DIR *proc;
91         FILE *fh;
92
93         running = sleeping = zombies = stopped = paging = blocked = 0;
94
95         if ((proc = opendir ("/proc")) == NULL)
96         {
97                 syslog (LOG_ERR, "Cannot open `/proc': %s", strerror (errno));
98                 return;
99         }
100
101         while ((ent = readdir (proc)) != NULL)
102         {
103                 if (!isdigit (ent->d_name[0]))
104                         continue;
105
106                 if (snprintf (filename, 20, "/proc/%s/stat", ent->d_name) >= 20)
107                         continue;
108
109                 if ((fh = fopen (filename, "r")) == NULL)
110                 {
111                         syslog (LOG_ERR, "Cannot open `%s': %s", filename, strerror (errno));
112                         continue;
113                 }
114
115                 if (fgets (buf, BUFSIZE, fh) == NULL)
116                 {
117                         fclose (fh);
118                         continue;
119                 }
120
121                 fclose (fh);
122
123                 if (strsplit (buf, fields, BUFSIZE) < 3)
124                         continue;
125
126                 switch (fields[2][0])
127                 {
128                         case 'R': running++;  break;
129                         case 'S': sleeping++; break;
130                         case 'D': blocked++;  break;
131                         case 'Z': zombies++;  break;
132                         case 'T': stopped++;  break;
133                         case 'W': paging++;   break;
134                 }
135         }
136
137         closedir(proc);
138
139         ps_submit (running, sleeping, zombies, stopped, paging, blocked);
140 #endif /* defined(KERNEL_LINUX) */
141 }
142 #else
143 # define ps_read NULL
144 #endif /* PROCESSES_HAVE_READ */
145
146 void module_register (void)
147 {
148         plugin_register (MODULE_NAME, ps_init, ps_read, ps_write);
149 }
150
151 #undef BUFSIZE
152 #undef MODULE_NAME