Merged revision 304 (removal of all `extern time_t curtime' in all plugins) to the...
[collectd.git] / src / cpufreq.c
1 /**
2  * collectd - src/cpufreq.c
3  * Copyright (C) 2005  Peter Holik
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  *   Peter Holik <peter at holik.at>
21  **/
22
23 #include "cpufreq.h"
24
25 /*
26  * Originally written by Peter Holik
27  */
28
29 #if COLLECT_CPUFREQ
30 #define MODULE_NAME "cpufreq"
31
32 #include "plugin.h"
33 #include "common.h"
34
35 static int num_cpu = 0;
36
37 static char *cpufreq_file = "cpufreq-%s.rrd";
38
39 static char *ds_def[] =
40 {
41         "DS:value:GAUGE:25:0:U",
42         NULL
43 };
44 static int ds_num = 1;
45
46 #define BUFSIZE 256
47
48 void cpufreq_init (void)
49 {
50         int status;
51         char filename[BUFSIZE];
52
53         num_cpu = 0;
54
55         while (1)
56         {
57                 status = snprintf (filename, BUFSIZE, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", num_cpu);
58                 if (status < 1 || status >= BUFSIZE)
59                         break;
60
61                 if (access(filename, R_OK))
62                         break;
63
64                 num_cpu++;
65         }
66
67         syslog (LOG_INFO, MODULE_NAME" found %d cpu(s)", num_cpu);
68 }
69
70 void cpufreq_write (char *host, char *inst, char *val)
71 {
72         int status;
73         char file[BUFSIZE];
74
75         status = snprintf (file, BUFSIZE, cpufreq_file, inst);
76         if (status < 1 || status >= BUFSIZE)
77                 return;
78
79         rrd_update_file (host, file, val, ds_def, ds_num);
80 }
81
82 void cpufreq_submit (int cpu_num, unsigned long long val)
83 {
84         char buf[BUFSIZE];
85         char cpu[16];
86
87         if (snprintf (buf, BUFSIZE, "%u:%llu", (unsigned int) curtime, val) >= BUFSIZE)
88                 return;
89         snprintf (cpu, 16, "%i", cpu_num);
90
91         plugin_submit (MODULE_NAME, cpu, buf);
92 }
93
94 void cpufreq_read (void)
95 {
96         int status;
97         unsigned long long val;
98         int i = 0;
99         FILE *fp;
100         char filename[BUFSIZE];
101         char buffer[16];
102
103         for (i = 0; i < num_cpu; i++)
104         {
105                 status = snprintf (filename, BUFSIZE, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", i);
106                 if (status < 1 || status >= BUFSIZE)
107                         return;
108
109                 if ((fp = fopen (filename, "r")) == NULL)
110                 {
111                         syslog (LOG_WARNING, "cpufreq: fopen: %s", strerror (errno));
112                         return;
113                 }
114
115                 if (fgets (buffer, 16, fp) == NULL)
116                 {
117                         syslog (LOG_WARNING, "cpufreq: fgets: %s", strerror (errno));
118                         return;
119                 }
120
121                 if (fclose (fp))
122                         syslog (LOG_WARNING, "cpufreq: fclose: %s", strerror (errno));
123
124                 /* You're seeing correctly: The file is reporting kHz values.. */
125                 val = atoll (buffer) * 1000;
126
127                 cpufreq_submit (i, val);
128         }
129 }
130 #undef BUFSIZE
131
132 void module_register (void)
133 {
134         plugin_register (MODULE_NAME, cpufreq_init, cpufreq_read, cpufreq_write);
135 }
136
137 #undef MODULE_NAME
138 #endif /* COLLECT_CPUFREQ */