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