2 * collectd - src/uptime.c
3 * Copyright (C) 2009 Marco Chiappero
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; only version 2 of the License is applicable.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * Marco Chiappero <marco at absence.it>
27 # define UPTIME_FILE "/proc/uptime"
28 /* No need for includes, using /proc filesystem, Linux only. */
29 /* #endif KERNEL_LINUX */
32 /* Using kstats chain to retrieve the boot time, this applies to:
33 * - Solaris / OpenSolaris
35 /* #endif HAVE_LIBKSTAT */
37 #elif HAVE_SYS_SYSCTL_H
38 # include <sys/sysctl.h>
39 /* Using sysctl interface to retrieve the boot time, this applies to:
43 /* #endif HAVE_SYS_SYSCTL_H */
46 # error "No applicable input method."
53 /* global variables not needed */
54 /* #endif KERNEL_LINUX */
57 static time_t boottime;
58 extern kstat_ctl_t *kc;
59 /* #endif HAVE_LIBKSTAT */
61 #elif HAVE_SYS_SYSCTL_H
62 static time_t boottime;
65 static void uptime_submit (gauge_t uptime)
68 value_list_t vl = VALUE_LIST_INIT;
70 values[0].gauge = uptime;
75 sstrncpy (vl.host, hostname_g, sizeof (vl.host));
76 sstrncpy (vl.plugin, "uptime", sizeof (vl.plugin));
77 sstrncpy (vl.type, "uptime", sizeof (vl.type));
79 plugin_dispatch_values (&vl);
82 #if !defined(KERNEL_LINUX) || !KERNEL_LINUX
83 static int uptime_init (void)
87 On unix systems other than Linux there is no /proc filesystem which
88 calculates the uptime every time we call a read for the /proc/uptime
89 file, the only information available is the boot time (in unix time,
90 since epoch). Hence there is no need to read, every time the
91 plugin_read is called, a value that won't change: this is a right
92 task for the uptime_init function. However, since uptime_init is run
93 only once, if the function fails in retrieving the boot time, the
94 plugin is unregistered and there is no chance to try again later.
95 Nevertheless, this is very unlikely to happen.
105 /* kstats chain already opened by update_kstat (using *kc), let's verify everything went fine. */
108 ERROR ("uptime plugin: kstat chain control structure not available.");
112 ksp = kstat_lookup (kc, "unix", 0, "system_misc");
115 ERROR ("uptime plugin: Cannot find unix:0:system_misc kstat.");
119 if (kstat_read (kc, ksp, NULL) < 0)
121 ERROR ("uptime plugin: kstat_read failed.");
125 knp = (kstat_named_t *) kstat_data_lookup (ksp, "boot_time");
128 ERROR ("uptime plugin: kstat_data_lookup (boot_time) failed.");
132 boottime = (time_t) knp->value.ui32;
133 /* #endif HAVE_LIBKSTAT */
135 # elif HAVE_SYS_SYSCTL_H
136 struct timeval boottv;
143 mib[1] = KERN_BOOTTIME;
145 memset (&boottv, 0, sizeof (boottv));
146 boottv_len = sizeof (boottv);
148 status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &boottv, &boottv_len,
149 /* new_value = */ NULL, /* new_length = */ 0);
153 ERROR ("uptime plugin: No value read from sysctl interface: %s",
154 sstrerror (errno, errbuf, sizeof (errbuf)));
158 boottime = boottv.tv_sec;
161 ERROR ("uptime plugin: sysctl(3) returned success, "
162 "but `boottime' is zero!");
165 #endif /* HAVE_SYS_SYSCTL_H */
170 #endif /* !KERNEL_LINUX */
172 static int uptime_read (void)
179 fh = fopen (UPTIME_FILE, "r");
184 ERROR ("uptime plugin: Cannot open "UPTIME_FILE": %s",
185 sstrerror (errno, errbuf, sizeof (errbuf)));
189 if ( fscanf (fh, "%lf", &uptime) < 1 )
191 WARNING ("uptime plugin: No value read from "UPTIME_FILE);
197 /* #endif KERNEL_LINUX */
199 #elif HAVE_LIBKSTAT || HAVE_SYS_SYSCTL_H
202 elapsed = time (NULL) - boottime;
204 uptime = (gauge_t) elapsed;
205 #endif /* HAVE_LIBKSTAT || HAVE_SYS_SYSCTL_H */
207 uptime_submit (uptime);
212 void module_register (void)
214 #if !defined(KERNEL_LINUX) || !KERNEL_LINUX
215 plugin_register_init ("uptime", uptime_init);
217 plugin_register_read ("uptime", uptime_read);
218 } /* void module_register */