Added copyright/GPL header to all .c and .h files in trunk
[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 "processes.h"
25
26 #if COLLECT_PROCESSES
27 #define MODULE_NAME "processes"
28
29 #include "common.h"
30 #include "plugin.h"
31
32 static char *ps_file = "processes.rrd";
33
34 static char *ds_def[] =
35 {
36         "DS:running:GAUGE:25:0:65535",
37         "DS:sleeping:GAUGE:25:0:65535",
38         "DS:zombies:GAUGE:25:0:65535",
39         "DS:stopped:GAUGE:25:0:65535",
40         "DS:paging:GAUGE:25:0:65535",
41         "DS:blocked:GAUGE:25:0:65535",
42         NULL
43 };
44 static int ds_num = 6;
45
46 extern time_t curtime;
47
48 void ps_init (void)
49 {
50 }
51
52 void ps_write (char *host, char *inst, char *val)
53 {
54         rrd_update_file (host, ps_file, val, ds_def, ds_num);
55 }
56
57 #define BUFSIZE 256
58 void ps_submit (unsigned int running,
59                 unsigned int sleeping,
60                 unsigned int zombies,
61                 unsigned int stopped,
62                 unsigned int paging,
63                 unsigned int blocked)
64 {
65         char buf[BUFSIZE];
66
67         if (snprintf (buf, BUFSIZE, "%u:%u:%u:%u:%u:%u:%u",
68                                 (unsigned int) curtime,
69                                 running, sleeping, zombies, stopped, paging,
70                                 blocked) >= BUFSIZE)
71                 return;
72
73         plugin_submit (MODULE_NAME, "-", buf);
74 }
75
76 void ps_read (void)
77 {
78 #ifdef KERNEL_LINUX
79         unsigned int running, sleeping, zombies, stopped, paging, blocked;
80
81         char buf[BUFSIZE];
82         char filename[20]; /* need 17 bytes */
83         char *fields[256];
84
85         struct dirent *ent;
86         DIR *proc;
87         FILE *fh;
88
89         running = sleeping = zombies = stopped = paging = blocked = 0;
90
91         if ((proc = opendir ("/proc")) == NULL)
92         {
93                 syslog (LOG_ERR, "Cannot open `/proc': %s", strerror (errno));
94                 return;
95         }
96
97         int strsplit (char *string, char **fields, size_t size);
98
99         while ((ent = readdir (proc)) != NULL)
100         {
101                 if (!isdigit (ent->d_name[0]))
102                         continue;
103
104                 if (snprintf (filename, 20, "/proc/%s/stat", ent->d_name) >= 20)
105                         continue;
106
107                 if ((fh = fopen (filename, "r")) == NULL)
108                 {
109                         syslog (LOG_ERR, "Cannot open `%s': %s", filename, strerror (errno));
110                         continue;
111                 }
112
113                 if (fgets (buf, BUFSIZE, fh) == NULL)
114                 {
115                         fclose (fh);
116                         continue;
117                 }
118
119                 fclose (fh);
120
121                 if (strsplit (buf, fields, 256) < 3)
122                         continue;
123
124                 switch (fields[2][0])
125                 {
126                         case 'R': running++;  break;
127                         case 'S': sleeping++; break;
128                         case 'D': blocked++;  break;
129                         case 'Z': zombies++;  break;
130                         case 'T': stopped++;  break;
131                         case 'W': paging++;   break;
132                 }
133         }
134
135         closedir(proc);
136
137         ps_submit (running, sleeping, zombies, stopped, paging, blocked);
138 #endif /* defined(KERNEL_LINUX) */
139 }
140 #undef BUFSIZE
141
142 void module_register (void)
143 {
144         plugin_register (MODULE_NAME, ps_init, ps_read, ps_write);
145 }
146
147 #undef MODULE_NAME
148 #endif /* COLLECT_PROCESSES */