Changed modules `cpu' through `sensors' to compile in `read-only' mode if dependencie...
[collectd.git] / src / sensors.c
1 /**
2  * collectd - src/sensors.c
3  * Copyright (C) 2005  Florian octo Forster
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  *   Florian octo Forster <octo at verplant.org>
21  **/
22
23 #include "collectd.h"
24 #include "common.h"
25 #include "plugin.h"
26
27 #define MODULE_NAME "sensors"
28
29 #if defined(HAVE_SENSORS_SENSORS_H)
30 # include <sensors/sensors.h>
31 #else
32 # undef HAVE_LIBSENSORS
33 #endif
34
35 #if defined(HAVE_LIBSENSORS)
36 # define SENSORS_HAVE_READ 1
37 #else
38 # define SENSORS_HAVE_READ 0
39 #endif
40
41 static char *filename_format = "sensors-%s.rrd";
42
43 static char *ds_def[] =
44 {
45         "DS:value:GAUGE:25:U:U",
46         NULL
47 };
48 static int ds_num = 1;
49
50 #ifdef HAVE_LIBSENSORS
51 typedef struct featurelist
52 {
53         const sensors_chip_name    *chip;
54         const sensors_feature_data *data;
55         struct featurelist         *next;
56 } featurelist_t;
57
58 featurelist_t *first_feature = NULL;
59 #endif /* defined (HAVE_LIBSENSORS) */
60
61 static void collectd_sensors_init (void)
62 {
63 #ifdef HAVE_LIBSENSORS
64         FILE *fh;
65         featurelist_t *last_feature = NULL;
66         featurelist_t *new_feature;
67         
68         const sensors_chip_name *chip;
69         int chip_num;
70
71         const sensors_feature_data *data;
72         int data_num0, data_num1;
73         
74         new_feature = first_feature;
75         while (new_feature != NULL)
76         {
77                 last_feature = new_feature->next;
78                 free (new_feature);
79                 new_feature = last_feature;
80         }
81
82 #ifdef assert
83         assert (new_feature == NULL);
84         assert (last_feature == NULL);
85 #endif
86
87         if ((fh = fopen ("/etc/sensors.conf", "r")) == NULL)
88                 return;
89
90         if (sensors_init (fh))
91         {
92                 fclose (fh);
93                 syslog (LOG_ERR, "sensors: Cannot initialize sensors. Data will not be collected.");
94                 return;
95         }
96
97         fclose (fh);
98
99         chip_num = 0;
100         while ((chip = sensors_get_detected_chips (&chip_num)) != NULL)
101         {
102                 data = NULL;
103                 data_num0 = data_num1 = 0;
104
105                 while ((data = sensors_get_all_features (*chip, &data_num0, &data_num1)) != NULL)
106                 {
107                         /* "master features" only */
108                         if (data->mapping != SENSORS_NO_MAPPING)
109                                 continue;
110
111                         /* Only temperature for now.. */
112                         if (strncmp (data->name, "temp", 4)
113                                         && strncmp (data->name, "fan", 3))
114                                 continue;
115
116                         if ((new_feature = (featurelist_t *) malloc (sizeof (featurelist_t))) == NULL)
117                         {
118                                 perror ("malloc");
119                                 continue;
120                         }
121
122                         /*
123                         syslog (LOG_INFO, "sensors: Adding feature: %s/%s", chip->prefix, data->name);
124                         */
125
126                         new_feature->chip = chip;
127                         new_feature->data = data;
128                         new_feature->next = NULL;
129
130                         if (first_feature == NULL)
131                         {
132                                 first_feature = new_feature;
133                                 last_feature  = new_feature;
134                         }
135                         else
136                         {
137                                 last_feature->next = new_feature;
138                                 last_feature = new_feature;
139                         }
140                 }
141         }
142
143         if (first_feature == NULL)
144                 sensors_cleanup ();
145 #endif /* defined(HAVE_LIBSENSORS) */
146
147         return;
148 }
149
150 #define BUFSIZE 512
151 static void sensors_write (char *host, char *inst, char *val)
152 {
153         char file[BUFSIZE];
154         int status;
155
156         status = snprintf (file, BUFSIZE, filename_format, inst);
157         if (status < 1)
158                 return;
159         else if (status >= BUFSIZE)
160                 return;
161
162         rrd_update_file (host, file, val, ds_def, ds_num);
163 }
164
165 static void sensors_submit (const char *feat_name, const char *chip_prefix, double value)
166 {
167         char buf[BUFSIZE];
168         char inst[BUFSIZE];
169
170         if (snprintf (buf, BUFSIZE, "%u:%.3f", (unsigned int) curtime, value) >= BUFSIZE)
171                 return;
172
173         if (snprintf (inst, BUFSIZE, "%s-%s", chip_prefix, feat_name) >= BUFSIZE)
174                 return;
175
176         plugin_submit (MODULE_NAME, inst, buf);
177 }
178 #undef BUFSIZE
179
180 #if SENSORS_HAVE_READ
181 static void sensors_read (void)
182 {
183         featurelist_t *feature;
184         double value;
185
186         for (feature = first_feature; feature != NULL; feature = feature->next)
187         {
188                 if (sensors_get_feature (*feature->chip, feature->data->number, &value) < 0)
189                         continue;
190
191                 sensors_submit (feature->data->name, feature->chip->prefix, value);
192         }
193 }
194 #endif /* SENSORS_HAVE_READ */
195
196 void module_register (void)
197 {
198         plugin_register (MODULE_NAME, collectd_sensors_init,
199 #if SENSORS_HAVE_READ
200                         sensors_read,
201 #else
202                         NULL,
203 #endif
204                         sensors_write);
205 }
206
207 #undef MODULE_NAME