Flavio Stanchina <flavio at stanchina.net>
- mbmon plugin.
+Franck Lombardi
+ - UNIX socket code for the memcached plugin.
+
Jason Pepas <cell at ices.utexas.edu>
- nfs plugin.
Scott Garrett <sgarrett at technomancer.com>
- tape plugin.
+Simon Kuhnle <simon at blarzwurst.de>
+ - OpenBSD code for the cpu and memory plugins.
+
Sjoerd van der Berg <harekiet at gmail.com>
- iptables plugin.
Stefan Hacker <stefan.hacker at web.de>
- teamspeak2 plugin.
+Tomasz Pala <gotar at pld-linux.org>
+ - conntrack plugin.
+
Tommie Gannert <d00-tga at d.kth.se>
- PID-file patch.
Name server and resolver statistics from the `statistics-channel'
interface of BIND 9.5, 9,6 and later.
+ - conntrack
+ Number of nf_conntrack entries.
+
- cpu
CPU utilization: Time spent in the system, user, nice, idle, and related
states.
plugin_ascent="no"
plugin_battery="no"
plugin_bind="no"
+plugin_conntrack="no"
plugin_cpu="no"
plugin_cpufreq="no"
plugin_df="no"
if test "x$ac_system" = "xLinux"
then
plugin_battery="yes"
+ plugin_conntrack="yes"
plugin_cpu="yes"
plugin_cpufreq="yes"
plugin_disk="yes"
if test "x$have_sysctl" = "xyes"
then
plugin_cpu="yes"
+ plugin_memory="yes"
plugin_swap="yes"
plugin_uptime="yes"
fi
AC_PLUGIN([ascent], [$plugin_ascent], [AscentEmu player statistics])
AC_PLUGIN([battery], [$plugin_battery], [Battery statistics])
AC_PLUGIN([bind], [$plugin_bind], [ISC Bind nameserver statistics])
+AC_PLUGIN([conntrack], [$plugin_conntrack], [nf_conntrack statistics])
AC_PLUGIN([cpufreq], [$plugin_cpufreq], [CPU frequency statistics])
AC_PLUGIN([cpu], [$plugin_cpu], [CPU usage statistics])
AC_PLUGIN([csv], [yes], [CSV output plugin])
ascent . . . . . . . $enable_ascent
battery . . . . . . . $enable_battery
bind . . . . . . . . $enable_bind
+ conntrack . . . . . . $enable_conntrack
cpu . . . . . . . . . $enable_cpu
cpufreq . . . . . . . $enable_cpufreq
csv . . . . . . . . . $enable_csv
'GPRINT:max:MAX:%4.1lf Max,',
'GPRINT:avg:LAST:%4.1lf Last\l'
],
+ conntrack => ['-v', 'Entries',
+ 'DEF:avg={file}:entropy:AVERAGE',
+ 'DEF:min={file}:entropy:MIN',
+ 'DEF:max={file}:entropy:MAX',
+ "AREA:max#$HalfBlue",
+ "AREA:min#$Canvas",
+ "LINE1:avg#$FullBlue:Count",
+ 'GPRINT:min:MIN:%4.0lf Min,',
+ 'GPRINT:avg:AVERAGE:%4.0lf Avg,',
+ 'GPRINT:max:MAX:%4.0lf Max,',
+ 'GPRINT:avg:LAST:%4.0lf Last\l'
+ ],
entropy => ['-v', 'Bits',
'DEF:avg={file}:entropy:AVERAGE',
'DEF:min={file}:entropy:MIN',
RRDVerticalLabel "Queries/s"
RRDFormat "%6.1lf"
</Type>
+<Type conntrack>
+ DataSources conntrack
+ DSName conntrack Conntrack count
+ RRDTitle "nf_conntrack connections on {hostname}"
+ RRDVerticalLabel "Count"
+ RRDFormat "%4.0lf"
+</Type>
<Type entropy>
DataSources entropy
DSName entropy Entropy bits
%attr(0644,root,root) %{_libdir}/%{name}/battery.so*
%attr(0644,root,root) %{_libdir}/%{name}/battery.la
+%attr(0644,root,root) %{_libdir}/%{name}/conntrack.so*
+%attr(0644,root,root) %{_libdir}/%{name}/conntrack.la
+
%attr(0644,root,root) %{_libdir}/%{name}/cpufreq.so*
%attr(0644,root,root) %{_libdir}/%{name}/cpufreq.la
'GPRINT:avg:AVERAGE:%4.1lf Avg,',
'GPRINT:max:MAX:%4.1lf Max,',
'GPRINT:avg:LAST:%4.1lf Last\l');
+ $GraphDefs['conntrack'] = array(
+ '-v', 'Entries',
+ 'DEF:avg={file}:entropy:AVERAGE',
+ 'DEF:min={file}:entropy:MIN',
+ 'DEF:max={file}:entropy:MAX',
+ "AREA:max#$HalfBlue",
+ "AREA:min#$Canvas",
+ "LINE1:avg#$FullBlue:Count",
+ 'GPRINT:min:MIN:%4.0lf Min,',
+ 'GPRINT:avg:AVERAGE:%4.0lf Avg,',
+ 'GPRINT:max:MAX:%4.0lf Max,',
+ 'GPRINT:avg:LAST:%4.0lf Last\l');
$GraphDefs['entropy'] = array(
'-v', 'Bits',
'DEF:avg={file}:entropy:AVERAGE',
LoadPlugin apcups
#LoadPlugin apple_sensors
LoadPlugin battery
+LoadPlugin conntrack
LoadPlugin cpu
LoadPlugin cpufreq
LoadPlugin csv
%attr(0644,root,root) %{_libdir}/%{name}/battery.so*
%attr(0644,root,root) %{_libdir}/%{name}/battery.la
+%attr(0644,root,root) %{_libdir}/%{name}/conntrack.so*
+%attr(0644,root,root) %{_libdir}/%{name}/conntrack.la
+
%attr(0644,root,root) %{_libdir}/%{name}/cpufreq.so*
%attr(0644,root,root) %{_libdir}/%{name}/cpufreq.la
collectd_DEPENDENCIES += bind.la
endif
+if BUILD_PLUGIN_CONNTRACK
+pkglib_LTLIBRARIES += conntrack.la
+conntrack_la_SOURCES = conntrack.c
+conntrack_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" conntrack.la
+collectd_DEPENDENCIES += conntrack.la
+endif
+
if BUILD_PLUGIN_CPU
pkglib_LTLIBRARIES += cpu.la
cpu_la_SOURCES = cpu.c
/**
* collectd - src/apache.c
- * Copyright (C) 2006-2008 Florian octo Forster
- * Copyright (C) 2007 Florent EppO Monbillard
- * Copyright (C) 2009 Amit Gupta
+ * Copyright (C) 2006-2009 Florian octo Forster
+ * Copyright (C) 2007 Florent EppO Monbillard
+ * Copyright (C) 2009 Amit Gupta
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
char *url;
char *user;
char *pass;
- char *verify_peer;
- char *verify_host;
+ int verify_peer;
+ int verify_host;
char *cacert;
char *apache_buffer;
char apache_curl_error[CURL_ERROR_SIZE];
typedef struct apache_s apache_t;
-static apache_t **apache = NULL;
-static size_t apache_num = 0;
+/* TODO: Remove this prototype */
+static int apache_read_host (user_data_t *user_data);
static void apache_free (apache_t *st)
{
sfree (st->url);
sfree (st->user);
sfree (st->pass);
- sfree (st->verify_peer);
- sfree (st->verify_host);
sfree (st->cacert);
sfree (st->apache_buffer);
if (st->curl) {
} /* apache_free */
static size_t apache_curl_callback (void *buf, size_t size, size_t nmemb,
- apache_t *st)
+ void *user_data)
{
size_t len = size * nmemb;
+ apache_t *st;
+
+ st = user_data;
+ if (st == NULL)
+ {
+ ERROR ("apache plugin: apache_curl_callback: "
+ "user_data pointer is NULL.");
+ return (0);
+ }
if (len <= 0)
return (len);
* URL ...
* </Plugin>
*/
-static int config_set_string (char **ret_string,
+static int config_set_string (char **ret_string, /* {{{ */
oconfig_item_t *ci)
{
char *string;
*ret_string = string;
return (0);
-} /* int config_set_string */
+} /* }}} int config_set_string */
+
+static int config_set_boolean (int *ret_boolean, /* {{{ */
+ oconfig_item_t *ci)
+{
+ if ((ci->values_num != 1)
+ || ((ci->values[0].type != OCONFIG_TYPE_BOOLEAN)
+ && (ci->values[0].type != OCONFIG_TYPE_STRING)))
+ {
+ WARNING ("apache plugin: The `%s' config option "
+ "needs exactly one boolean argument.", ci->key);
+ return (-1);
+ }
+
+ if (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)
+ {
+ if (ci->values[0].value.boolean)
+ *ret_boolean = 1;
+ else
+ *ret_boolean = 0;
+ }
+ else /* if (ci->values[0].type != OCONFIG_TYPE_STRING) */
+ {
+ char *string = ci->values[0].value.string;
+ if ((strcasecmp ("true", string) == 0)
+ || (strcasecmp ("yes", string) == 0)
+ || (strcasecmp ("on", string) == 0))
+ *ret_boolean = 1;
+ else if ((strcasecmp ("false", string) == 0)
+ || (strcasecmp ("no", string) == 0)
+ || (strcasecmp ("off", string) == 0))
+ *ret_boolean = 0;
+ else
+ {
+ ERROR ("apache plugin: Cannot parse string "
+ "as boolean value: %s", string);
+ return (-1);
+ }
+ }
+
+ return (0);
+} /* }}} int config_set_boolean */
static int config_add (oconfig_item_t *ci)
{
sfree (st);
return (status);
}
+ assert (st->name != NULL);
for (i = 0; i < ci->children_num; i++)
{
else if (strcasecmp ("Password", child->key) == 0)
status = config_set_string (&st->pass, child);
else if (strcasecmp ("VerifyPeer", child->key) == 0)
- status = config_set_string (&st->verify_peer, child);
+ status = config_set_boolean (&st->verify_peer, child);
else if (strcasecmp ("VerifyHost", child->key) == 0)
- status = config_set_string (&st->verify_host, child);
+ status = config_set_boolean (&st->verify_host, child);
else if (strcasecmp ("CACert", child->key) == 0)
status = config_set_string (&st->cacert, child);
else
{
- WARNING ("apache plugin: Option `%s' not allowed here.", child->key);
+ WARNING ("apache plugin: Option `%s' not allowed here.",
+ child->key);
status = -1;
}
break;
}
+ /* Check if struct is complete.. */
+ if ((status == 0) && (st->url == NULL))
+ {
+ ERROR ("apache plugin: Instance `%s': "
+ "No URL has been configured.",
+ st->name);
+ status = -1;
+ }
+
if (status == 0)
{
- apache_t **temp;
- temp = (apache_t **) realloc (apache, sizeof (*apache) * (apache_num + 1));
- if (temp == NULL)
- {
- ERROR ("apache plugin: realloc failed");
- status = -1;
- }
- else
- {
- apache = temp;
- apache[apache_num] = st;
- apache_num++;
- }
+ user_data_t ud;
+ char callback_name[3*DATA_MAX_NAME_LEN];
+
+ memset (&ud, 0, sizeof (ud));
+ ud.data = st;
+ ud.free_func = (void *) apache_free;
+
+ memset (callback_name, 0, sizeof (callback_name));
+ ssnprintf (callback_name, sizeof (callback_name),
+ "apache/%s/%s",
+ (st->host != NULL) ? st->host : hostname_g,
+ (st->name != NULL) ? st->name : "default"),
+
+ status = plugin_register_complex_read (callback_name,
+ /* callback = */ apache_read_host,
+ /* interval = */ NULL,
+ /* user_data = */ &ud);
}
if (status != 0)
return status;
} /* int config */
-
/* initialize curl for each host */
static int init_host (apache_t *st) /* {{{ */
{
static char credentials[1024];
- if (st->url == NULL)
- {
- WARNING ("apache plugin: init: No URL configured, returning "
- "an error.");
- return (-1);
- }
+ assert (st->url != NULL);
+ /* (Assured by `config_add') */
if (st->curl != NULL)
{
curl_easy_cleanup (st->curl);
+ st->curl = NULL;
}
if ((st->curl = curl_easy_init ()) == NULL)
{
- ERROR ("apache plugin: init: `curl_easy_init' failed.");
+ ERROR ("apache plugin: init_host: `curl_easy_init' failed.");
return (-1);
}
st->user, (st->pass == NULL) ? "" : st->pass);
if ((status < 0) || ((size_t) status >= sizeof (credentials)))
{
- ERROR ("apache plugin: init: Returning an error "
+ ERROR ("apache plugin: init_host: Returning an error "
"because the credentials have been "
"truncated.");
+ curl_easy_cleanup (st->curl);
+ st->curl = NULL;
return (-1);
}
curl_easy_setopt (st->curl, CURLOPT_URL, st->url);
- if ((st->verify_peer == NULL) || (strcmp (st->verify_peer, "true") == 0))
+ if (st->verify_peer != 0)
{
curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYPEER, 1);
}
curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYPEER, 0);
}
- if ((st->verify_host == NULL) || (strcmp (st->verify_host, "true") == 0))
+ if (st->verify_host != 0)
{
curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYHOST, 2);
}
}
return (0);
-} /* int init_host */
+} /* }}} int init_host */
-static int init (void)
+static void submit_value (const char *type, const char *type_instance,
+ value_t value, apache_t *st)
{
- size_t i;
- int success = 0;
- int status;
-
- for (i = 0; i < apache_num; i++)
- {
- status = init_host (apache[i]);
- if (status == 0)
- success++;
- }
-
- if (success == 0)
- {
- ERROR ("apache plugin init: No host could be initialized. Will return an error so "
- "the plugin will be delayed.");
- return (-1);
- }
-
- return (0);
-} /* int init */
-
-static void set_plugin_instance (apache_t *st, value_list_t *vl)
-{
- /* if there is no instance name, don't set plugin_instance */
- if ( (st->name != NULL)
- && (apache_num > 0) )
- {
- sstrncpy (vl->plugin_instance, st->name, sizeof (vl->plugin_instance));
- }
-} /* void set_plugin */
-
-static void submit_counter (const char *type, const char *type_instance,
- counter_t value, apache_t *st)
-{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].counter = value;
-
- vl.values = values;
+ vl.values = &value;
vl.values_len = 1;
- sstrncpy (vl.host, st->host, sizeof (vl.host));
+
+ sstrncpy (vl.host, (st->host != NULL) ? st->host : hostname_g,
+ sizeof (vl.host));
+
sstrncpy (vl.plugin, "apache", sizeof (vl.plugin));
- sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance));
- sstrncpy (vl.type, type, sizeof (vl.type));
+ if (st->name != NULL)
+ sstrncpy (vl.plugin_instance, st->name,
+ sizeof (vl.plugin_instance));
+ sstrncpy (vl.type, type, sizeof (vl.type));
if (type_instance != NULL)
sstrncpy (vl.type_instance, type_instance,
sizeof (vl.type_instance));
- set_plugin_instance (st, &vl);
-
plugin_dispatch_values (&vl);
+} /* void submit_value */
+
+static void submit_counter (const char *type, const char *type_instance,
+ counter_t c, apache_t *st)
+{
+ value_t v;
+ v.counter = c;
+ submit_value (type, type_instance, v, st);
} /* void submit_counter */
static void submit_gauge (const char *type, const char *type_instance,
- gauge_t value, apache_t *st)
+ gauge_t g, apache_t *st)
{
- value_t values[1];
- value_list_t vl = VALUE_LIST_INIT;
-
- values[0].gauge = value;
-
- vl.values = values;
- vl.values_len = 1;
- sstrncpy (vl.host, st->host, sizeof (vl.host));
- sstrncpy (vl.plugin, "apache", sizeof (vl.plugin));
- sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance));
- sstrncpy (vl.type, type, sizeof (vl.type));
-
- if (type_instance != NULL)
- sstrncpy (vl.type_instance, type_instance,
- sizeof (vl.type_instance));
-
- set_plugin_instance (st, &vl);
-
- plugin_dispatch_values (&vl);
-} /* void submit_counter */
+ value_t v;
+ v.gauge = g;
+ submit_value (type, type_instance, v, st);
+} /* void submit_gauge */
static void submit_scoreboard (char *buf, int server, apache_t *st)
{
}
}
-static int apache_read_host (apache_t *st)
+static int apache_read_host (user_data_t *user_data) /* {{{ */
{
int i;
int fields_num;
int server = LIGHTTPD; /* default is lighttpd */
+ apache_t *st;
+
+ st = user_data->data;
+
+ assert (st->url != NULL);
+ /* (Assured by `config_add') */
+
if (st->curl == NULL)
- return (-1);
- if (st->url == NULL)
- return (-1);
+ {
+ int status;
+
+ status = init_host (st);
+ if (status != 0)
+ return (-1);
+ }
+ assert (st->curl != NULL);
st->apache_buffer_fill = 0;
if (curl_easy_perform (st->curl) != 0)
break;
}
- /* set the host to localhost if st->host is not specified */
- if ( (st->host == NULL)
- || (0 == strcmp(st->host, "")) ) {
- st->host = hostname_g;
- }
-
for (i = 0; i < lines_num; i++)
{
fields_num = strsplit (lines[i], fields, 4);
st->apache_buffer_fill = 0;
return (0);
-} /* int apache_read_host */
-
-static int apache_read (void)
-{
- size_t i;
- int success = 0;
- int status;
-
- for (i = 0; i < apache_num; i++)
- {
- status = apache_read_host (apache[i]);
- if (status == 0)
- success++;
- }
-
- if (success == 0)
- {
- ERROR ("apache plugin: No host could be read. Will return an error so "
- "the plugin will be delayed.");
- return (-1);
- }
-
- return (0);
-} /* int apache_read */
+} /* }}} int apache_read_host */
void module_register (void)
{
plugin_register_complex_config ("apache", config);
- plugin_register_init ("apache", init);
- plugin_register_read ("apache", apache_read);
} /* void module_register */
+
+/* vim: set sw=8 noet fdm=marker : */
#include "common.h"
#include "plugin.h"
+#include "utils_complain.h"
+
#if HAVE_MACH_MACH_TYPES_H
# include <mach/mach_types.h>
#endif
/* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */
#elif KERNEL_LINUX
+ static c_complain_t acpi_dir_complaint = C_COMPLAIN_INIT_STATIC;
+
FILE *fh;
char buffer[1024];
char filename[256];
battery_submit ("0", "voltage", voltage);
}
- walk_directory (battery_acpi_dir, battery_read_acpi,
- /* user_data = */ NULL);
+ if (0 == access (battery_acpi_dir, R_OK))
+ walk_directory (battery_acpi_dir, battery_read_acpi,
+ /* user_data = */ NULL);
+ else
+ {
+ char errbuf[1024];
+ c_complain_once (LOG_WARNING, &acpi_dir_complaint,
+ "battery plugin: Failed to access `%s': %s",
+ battery_acpi_dir,
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ }
#endif /* KERNEL_LINUX */
#@BUILD_PLUGIN_ASCENT_TRUE@LoadPlugin ascent
#@BUILD_PLUGIN_BATTERY_TRUE@LoadPlugin battery
#@BUILD_PLUGIN_BIND_TRUE@LoadPlugin bind
+#@BUILD_PLUGIN_CONNTRACK_TRUE@LoadPlugin conntrack
@BUILD_PLUGIN_CPU_TRUE@@BUILD_PLUGIN_CPU_TRUE@LoadPlugin cpu
#@BUILD_PLUGIN_CPUFREQ_TRUE@LoadPlugin cpufreq
@LOAD_PLUGIN_CSV@LoadPlugin csv
--- /dev/null
+/**
+ * collectd - src/conntrack.c
+ * Copyright (C) 2009 Tomasz Pala
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Tomasz Pala <gotar at pld-linux.org>
+ * based on entropy.c by:
+ * Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+#if !KERNEL_LINUX
+# error "No applicable input method."
+#endif
+
+#define CONNTRACK_FILE "/proc/sys/net/netfilter/nf_conntrack_count"
+
+static void conntrack_submit (double conntrack)
+{
+ value_t values[1];
+ value_list_t vl = VALUE_LIST_INIT;
+
+ values[0].gauge = conntrack;
+
+ vl.values = values;
+ vl.values_len = 1;
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "conntrack", sizeof (vl.plugin));
+ sstrncpy (vl.type, "conntrack", sizeof (vl.type));
+
+ plugin_dispatch_values (&vl);
+} /* static void conntrack_submit */
+
+static int conntrack_read (void)
+{
+ double conntrack;
+ FILE *fh;
+ char buffer[64];
+
+ fh = fopen (CONNTRACK_FILE, "r");
+ if (fh == NULL)
+ return (-1);
+
+ if (fgets (buffer, sizeof (buffer), fh) == NULL)
+ {
+ fclose (fh);
+ return (-1);
+ }
+ fclose (fh);
+
+ conntrack = atof (buffer);
+
+ if (conntrack > 0.0)
+ conntrack_submit (conntrack);
+
+ return (0);
+} /* static int conntrack_read */
+
+void module_register (void)
+{
+ plugin_register_read ("conntrack", conntrack_read);
+} /* void module_register */
/**
* collectd - src/cpu.c
* Copyright (C) 2005-2009 Florian octo Forster
- * Copyright (C) 2009 Simon Kuhnle
+ * Copyright (C) 2008 Oleg King
+ * Copyright (C) 2009 Simon Kuhnle
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
*
* Authors:
* Florian octo Forster <octo at verplant.org>
+ * Oleg King <king2 at kaluga.ru>
* Simon Kuhnle <simon at blarzwurst.de>
**/
/**
* collectd - src/gmond.c
- * Copyright (C) 2005-2009 Florian octo Forster
+ * Copyright (C) 2009 Florian octo Forster
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
/**
* collectd - src/interface.c
- * Copyright (C) 2005-2007 Florian octo Forster
+ * Copyright (C) 2005-2008 Florian octo Forster
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
# define NI_MAXHOST 1025
#endif
+/* OpenBSD doesn't have EPROTO, FreeBSD doesn't have EILSEQ. Oh what joy! */
+#ifndef EILSEQ
+# ifdef EPROTO
+# define EILSEQ EPROTO
+# else
+# define EILSEQ EINVAL
+# endif
+#endif
+
/* Secure/static macros. They work like `strcpy' and `strcat', but assure null
* termination. They work for static buffers only, because they use `sizeof'.
* The `SSTRCATF' combines the functionality of `snprintf' and `strcat' which
* collectd - src/memcached.c, based on src/hddtemp.c
* Copyright (C) 2007 Antony Dovgal
* Copyright (C) 2005,2006 Vincent Stehlé
+ * Copyright (C) 2009 Franck Lombardi
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Antony Dovgal <tony at daylessday dot org>
* Vincent Stehlé <vincent.stehle at free.fr>
* Florian octo Forster <octo at verplant.org>
+ * Franck Lombardi
**/
#include "collectd.h"
# include <poll.h>
# include <netdb.h>
# include <sys/socket.h>
+# include <sys/un.h>
# include <netinet/in.h>
# include <netinet/tcp.h>
static const char *config_keys[] =
{
+ "Socket",
"Host",
"Port"
};
static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
+static char *memcached_socket = NULL;
static char *memcached_host = NULL;
static char memcached_port[16];
int fd;
ssize_t status;
int buffer_fill;
+ int i = 0;
- const char *host;
- const char *port;
+ if (memcached_socket != NULL) {
+ struct sockaddr_un serv_addr;
- struct addrinfo ai_hints;
- struct addrinfo *ai_list, *ai_ptr;
- int ai_return, i = 0;
+ memset (&serv_addr, 0, sizeof (serv_addr));
+ serv_addr.sun_family = AF_UNIX;
+ sstrncpy (serv_addr.sun_path, memcached_socket, sizeof (serv_addr.sun_path));
- memset (&ai_hints, '\0', sizeof (ai_hints));
- ai_hints.ai_flags = 0;
-#ifdef AI_ADDRCONFIG
-/* ai_hints.ai_flags |= AI_ADDRCONFIG; */
-#endif
- ai_hints.ai_family = AF_INET;
- ai_hints.ai_socktype = SOCK_STREAM;
- ai_hints.ai_protocol = 0;
+ /* create our socket descriptor */
+ fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0) {
+ char errbuf[1024];
+ ERROR ("memcached: unix socket: %s", sstrerror (errno, errbuf,
+ sizeof (errbuf)));
+ return -1;
+ }
- host = memcached_host;
- if (host == NULL) {
- host = MEMCACHED_DEF_HOST;
+ /* connect to the memcached daemon */
+ status = (ssize_t) connect (fd, (struct sockaddr *) &serv_addr,
+ SUN_LEN (&serv_addr));
+ if (status != 0) {
+ shutdown (fd, SHUT_RDWR);
+ close (fd);
+ fd = -1;
+ }
}
+ else { /* if (memcached_socket == NULL) */
+ const char *host;
+ const char *port;
- port = memcached_port;
- if (strlen (port) == 0) {
- port = MEMCACHED_DEF_PORT;
- }
+ struct addrinfo ai_hints;
+ struct addrinfo *ai_list, *ai_ptr;
+ int ai_return = 0;
- if ((ai_return = getaddrinfo (host, port, NULL, &ai_list)) != 0) {
- char errbuf[1024];
- ERROR ("memcached: getaddrinfo (%s, %s): %s",
- host, port,
- (ai_return == EAI_SYSTEM)
- ? sstrerror (errno, errbuf, sizeof (errbuf))
- : gai_strerror (ai_return));
- return -1;
- }
+ memset (&ai_hints, '\0', sizeof (ai_hints));
+ ai_hints.ai_flags = 0;
+#ifdef AI_ADDRCONFIG
+ /* ai_hints.ai_flags |= AI_ADDRCONFIG; */
+#endif
+ ai_hints.ai_family = AF_INET;
+ ai_hints.ai_socktype = SOCK_STREAM;
+ ai_hints.ai_protocol = 0;
- fd = -1;
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) {
- /* create our socket descriptor */
- if ((fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol)) < 0) {
+ host = memcached_host;
+ if (host == NULL) {
+ host = MEMCACHED_DEF_HOST;
+ }
+
+ port = memcached_port;
+ if (strlen (port) == 0) {
+ port = MEMCACHED_DEF_PORT;
+ }
+
+ if ((ai_return = getaddrinfo (host, port, NULL, &ai_list)) != 0) {
char errbuf[1024];
- ERROR ("memcached: socket: %s", sstrerror (errno, errbuf, sizeof (errbuf)));
- continue;
+ ERROR ("memcached: getaddrinfo (%s, %s): %s",
+ host, port,
+ (ai_return == EAI_SYSTEM)
+ ? sstrerror (errno, errbuf, sizeof (errbuf))
+ : gai_strerror (ai_return));
+ return -1;
}
- /* connect to the memcached daemon */
- if (connect (fd, (struct sockaddr *) ai_ptr->ai_addr, ai_ptr->ai_addrlen)) {
- shutdown(fd, SHUT_RDWR);
- close(fd);
- fd = -1;
- continue;
+ fd = -1;
+ for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) {
+ /* create our socket descriptor */
+ fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
+ if (fd < 0) {
+ char errbuf[1024];
+ ERROR ("memcached: socket: %s", sstrerror (errno, errbuf, sizeof (errbuf)));
+ continue;
+ }
+
+ /* connect to the memcached daemon */
+ status = (ssize_t) connect (fd, (struct sockaddr *) ai_ptr->ai_addr, ai_ptr->ai_addrlen);
+ if (status != 0) {
+ shutdown (fd, SHUT_RDWR);
+ close (fd);
+ fd = -1;
+ continue;
+ }
+
+ /* A socket could be opened and connecting succeeded. We're
+ * done. */
+ break;
}
- /* A socket could be opened and connecting succeeded. We're
- * done. */
- break;
+ freeaddrinfo (ai_list);
}
- freeaddrinfo (ai_list);
-
if (fd < 0) {
ERROR ("memcached: Could not connect to daemon.");
return -1;
static int memcached_config (const char *key, const char *value) /* {{{ */
{
- if (strcasecmp (key, "Host") == 0) {
+ if (strcasecmp (key, "Socket") == 0) {
+ if (memcached_socket != NULL) {
+ free (memcached_socket);
+ }
+ memcached_socket = strdup (value);
+ } else if (strcasecmp (key, "Host") == 0) {
if (memcached_host != NULL) {
free (memcached_host);
}
#define FIELD_IS(cnst) \
(((sizeof(cnst) - 1) == name_len) && (strcmp (cnst, fields[1]) == 0))
- ptr = buf;
- saveptr = NULL;
- while ((line = strtok_r (ptr, "\n\r", &saveptr)) != NULL)
+ ptr = buf;
+ saveptr = NULL;
+ while ((line = strtok_r (ptr, "\n\r", &saveptr)) != NULL)
{
int name_len;
- ptr = NULL;
+ ptr = NULL;
fields_num = strsplit(line, fields, 3);
if (fields_num != 3)
{
rusage_syst = atoll(fields[2]);
}
-
+
/*
* Number of threads of this instance
*/
{
submit_gauge ("memcached_items", "current", atof (fields[2]));
}
-/*
- else if (FIELD_IS ("total_items"))
- {
- total_items = atoll(fields[2]);
- }
- */
/*
* Number of bytes used and available (total - used)
{
submit_gauge ("memcached_connections", "current", atof (fields[2]));
}
-/*
- else if (FIELD_IS("total_connections"))
- {
- total_connections = atoll(fields[2]);
- }
-*/
-
-/*
- * ``Number of connection structures allocated by the server''
- else if (FIELD_IS ("connection_structures"))
- {
- connection_structures = atof(fields[2]);
- }
- */
/*
* Commands
if (!isnan (bytes_used) && !isnan (bytes_total) && (bytes_used <= bytes_total))
submit_gauge2 ("df", "cache", bytes_used, bytes_total - bytes_used);
-
+
if ((rusage_user != 0) || (rusage_syst != 0))
submit_counter2 ("ps_cputime", NULL, rusage_user, rusage_syst);
if ((octets_rx != 0) || (octets_tx != 0))
submit_counter2 ("memcached_octets", NULL, octets_rx, octets_tx);
-
+
if (!isnan (gets) && !isnan (hits))
{
gauge_t rate = NAN;
* tab-width: 4
* c-basic-offset: 4
* End:
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
+ * vim600: sw=4 ts=4 fdm=marker noexpandtab
+ * vim<600: sw=4 ts=4 noexpandtab
*/
/**
* collectd - src/memory.c
- * Copyright (C) 2005-2007 Florian octo Forster
+ * Copyright (C) 2005-2008 Florian octo Forster
+ * Copyright (C) 2009 Simon Kuhnle
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
*
* Authors:
* Florian octo Forster <octo at verplant.org>
+ * Simon Kuhnle <simon at blarzwurst.de>
**/
#include "collectd.h"
static kstat_t *ksp;
/* #endif HAVE_LIBKSTAT */
+#elif HAVE_SYSCTL
+static int pagesize;
+/* #endif HAVE_SYSCTL */
+
#elif HAVE_LIBSTATGRAB
/* no global variables */
/* endif HAVE_LIBSTATGRAB */
ksp = NULL;
return (-1);
}
-#endif /* HAVE_LIBKSTAT */
+/* #endif HAVE_LIBKSTAT */
+
+#elif HAVE_SYSCTL
+ pagesize = getpagesize ();
+ if (pagesize <= 0)
+ {
+ ERROR ("memory plugin: Invalid pagesize: %i", pagesize);
+ return (-1);
+ }
+/* #endif HAVE_SYSCTL */
+
+#elif HAVE_LIBSTATGRAB
+/* no init stuff */
+#endif /* HAVE_LIBSTATGRAB */
return (0);
} /* int memory_init */
memory_submit ("locked", mem_lock);
/* #endif HAVE_LIBKSTAT */
+#elif HAVE_SYSCTL
+ int mib[] = {CTL_VM, VM_METER};
+ struct vmtotal vmtotal;
+ size_t size;
+
+ memset (&vmtotal, 0, sizeof (vmtotal));
+ size = sizeof (vmtotal);
+
+ if (sysctl (mib, 2, &vmtotal, &size, NULL, 0) < 0) {
+ char errbuf[1024];
+ WARNING ("memory plugin: sysctl failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ return (-1);
+ }
+
+ assert (pagesize > 0);
+ memory_submit ("active", vmtotal.t_arm * pagesize);
+ memory_submit ("inactive", (vmtotal.t_rm - vmtotal.t_arm) * pagesize);
+ memory_submit ("free", vmtotal.t_free * pagesize);
+/* #endif HAVE_SYSCTL */
+
#elif HAVE_LIBSTATGRAB
sg_mem_stats *ios;
/**
* collectd - src/mysql.c
* Copyright (C) 2006-2009 Florian octo Forster
- * Copyright (C) 2009 Doug MacEachern
- * Copyright (C) 2009 Sebastian tokkee Harl
+ * Copyright (C) 2008 Mirko Buffoni
+ * Copyright (C) 2009 Doug MacEachern
+ * Copyright (C) 2009 Sebastian tokkee Harl
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* ! Hash (Bits 224 - 255) !
* +---------------------------------------------------------------+
*/
+#define PART_SIGNATURE_SHA256_SIZE 36
struct part_signature_sha256_s
{
part_header_t head;
static int parse_packet (sockent_t *se,
void *buffer, size_t buffer_size, int flags);
+#define BUFFER_READ(p,s) do { \
+ memcpy ((p), buffer + buffer_offset, (s)); \
+ buffer_offset += (s); \
+} while (0)
+
#if HAVE_GCRYPT_H
static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */
- void **ret_buffer, size_t *ret_buffer_len)
+ void **ret_buffer, size_t *ret_buffer_len, int flags)
{
- char *buffer = *ret_buffer;
- size_t buffer_len = *ret_buffer_len;
+ char *buffer;
+ size_t buffer_len;
+ size_t buffer_offset;
- part_signature_sha256_t ps_received;
- char hash[sizeof (ps_received.hash)];
+ part_signature_sha256_t pss;
+ char hash[sizeof (pss.hash)];
gcry_md_hd_t hd;
gcry_error_t err;
unsigned char *hash_ptr;
+ buffer = *ret_buffer;
+ buffer_len = *ret_buffer_len;
+ buffer_offset = 0;
+
if (se->shared_secret == NULL)
{
NOTICE ("network plugin: Received signed network packet but can't verify "
return (0);
}
- if (buffer_len < sizeof (ps_received))
+ if (buffer_len < PART_SIGNATURE_SHA256_SIZE)
return (-ENOMEM);
+ BUFFER_READ (&pss.head.type, sizeof (pss.head.type));
+ BUFFER_READ (&pss.head.length, sizeof (pss.head.length));
+ BUFFER_READ (pss.hash, sizeof (pss.hash));
+
+ assert (buffer_offset == PART_SIGNATURE_SHA256_SIZE);
+
+ if (ntohs (pss.head.length) != PART_SIGNATURE_SHA256_SIZE)
+ {
+ ERROR ("network plugin: HMAC-SHA-256 with invalid length received.");
+ return (-1);
+ }
+
hd = NULL;
err = gcry_md_open (&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
if (err != 0)
return (-1);
}
- memcpy (&ps_received, buffer, sizeof (ps_received));
- /* TODO: Check ps_received.head.length! */
-
- buffer += sizeof (ps_received);
- buffer_len -= sizeof (ps_received);
-
- gcry_md_write (hd, buffer, buffer_len);
+ gcry_md_write (hd, buffer + buffer_offset, buffer_len - buffer_offset);
hash_ptr = gcry_md_read (hd, GCRY_MD_SHA256);
if (hash_ptr == NULL)
{
gcry_md_close (hd);
hd = NULL;
- *ret_buffer += sizeof (ps_received);
- *ret_buffer_len -= sizeof (ps_received);
+ if (memcmp (pss.hash, hash, sizeof (pss.hash)) != 0)
+ {
+ WARNING ("network plugin: Verifying HMAC-SHA-256 signature failed: "
+ "Hash mismatch.");
+ }
+ else
+ {
+ parse_packet (se, buffer + buffer_offset, buffer_len - buffer_offset,
+ flags | PP_SIGNED);
+ }
+
+ *ret_buffer = buffer + buffer_len;
+ *ret_buffer_len = 0;
- if (memcmp (ps_received.hash, hash,
- sizeof (ps_received.hash)) == 0)
- return (0);
- else /* hashes do not match. */
- return (1);
+ return (0);
} /* }}} int parse_part_sign_sha256 */
/* #endif HAVE_GCRYPT_H */
#else /* if !HAVE_GCRYPT_H */
static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */
- void **ret_buffer, size_t *ret_buffer_len)
+ void **ret_buffer, size_t *ret_buffer_size, int flags)
{
- INFO ("network plugin: Received signed packet, but the network "
- "plugin was not linked with libgcrypt, so I cannot "
- "verify the signature. The packet will be accepted.");
+ static int warning_has_been_printed = 0;
+
+ char *buffer;
+ size_t buffer_size;
+ size_t buffer_offset;
+
+ part_signature_sha256_t pss;
+
+ buffer = *ret_buffer;
+ buffer_size = *ret_buffer_size;
+ buffer_offset = 0;
+
+ if (buffer_size < PART_SIGNATURE_SHA256_SIZE)
+ return (-ENOMEM);
+
+ BUFFER_READ (&pss.head.type, sizeof (pss.head.type));
+ BUFFER_READ (&pss.head.length, sizeof (pss.head.length));
+ BUFFER_READ (pss.hash, sizeof (pss.hash));
+
+ assert (buffer_offset == PART_SIGNATURE_SHA256_SIZE);
+
+ if (ntohs (pss.head.length) != PART_SIGNATURE_SHA256_SIZE)
+ {
+ ERROR ("network plugin: HMAC-SHA-256 with invalid length received.");
+ return (-1);
+ }
+
+ if (warning_has_been_printed == 0)
+ {
+ WARNING ("network plugin: Received signed packet, but the network "
+ "plugin was not linked with libgcrypt, so I cannot "
+ "verify the signature. The packet will be accepted.");
+ warning_has_been_printed = 1;
+ }
+
+ parse_packet (se, buffer + buffer_offset, buffer_size - buffer_offset,
+ flags);
+
+ *ret_buffer = buffer + buffer_size;
+ *ret_buffer_size = 0;
+
return (0);
} /* }}} int parse_part_sign_sha256 */
#endif /* !HAVE_GCRYPT_H */
buffer_offset = 0;
-#define BUFFER_READ(p,s) do { \
- memcpy ((p), buffer + buffer_offset, (s)); \
- buffer_offset += (s); \
-} while (0)
-
/* Copy the unencrypted information into `pea'. */
BUFFER_READ (&pea.head.type, sizeof (pea.head.type));
BUFFER_READ (&pea.head.length, sizeof (pea.head.length));
*ret_buffer_len = buffer_len - part_size;
return (0);
-#undef BUFFER_READ
} /* }}} int parse_part_encr_aes256 */
/* #endif HAVE_GCRYPT_H */
#else /* if !HAVE_GCRYPT_H */
static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
- void **ret_buffer, size_t *ret_buffer_len)
+ void **ret_buffer, size_t *ret_buffer_size, int flags)
{
- INFO ("network plugin: Received encrypted packet, but the network "
- "plugin was not linked with libgcrypt, so I cannot "
- "decrypt it. The packet will be discarded.");
- return (-1);
+ static int warning_has_been_printed = 0;
+
+ char *buffer;
+ size_t buffer_size;
+ size_t buffer_offset;
+
+ part_header_t ph;
+ size_t ph_length;
+
+ buffer = *ret_buffer;
+ buffer_size = *ret_buffer_size;
+ buffer_offset = 0;
+
+ /* parse_packet assures this minimum size. */
+ assert (buffer_size >= (sizeof (ph.type) + sizeof (ph.length)));
+
+ BUFFER_READ (&ph.type, sizeof (ph.type));
+ BUFFER_READ (&ph.length, sizeof (ph.length));
+ ph_length = ntohs (ph.length);
+
+ if ((ph_length < PART_ENCRYPTION_AES256_SIZE)
+ || (ph_length > buffer_size))
+ {
+ ERROR ("network plugin: AES-256 encrypted part "
+ "with invalid length received.");
+ return (-1);
+ }
+
+ if (warning_has_been_printed == 0)
+ {
+ WARNING ("network plugin: Received encrypted packet, but the network "
+ "plugin was not linked with libgcrypt, so I cannot "
+ "decrypt it. The part will be discarded.");
+ warning_has_been_printed = 1;
+ }
+
+ *ret_buffer += ph_length;
+ *ret_buffer_size -= ph_length;
+
+ return (0);
} /* }}} int parse_part_encr_aes256 */
#endif /* !HAVE_GCRYPT_H */
+#undef BUFFER_READ
+
static int parse_packet (sockent_t *se, /* {{{ */
void *buffer, size_t buffer_size, int flags)
{
value_list_t vl = VALUE_LIST_INIT;
notification_t n;
- int packet_was_signed = (flags & PP_SIGNED);
- int packet_was_encrypted = (flags & PP_ENCRYPTED);
#if HAVE_GCRYPT_H
+ int packet_was_signed = (flags & PP_SIGNED);
+ int packet_was_encrypted = (flags & PP_ENCRYPTED);
int printed_ignore_warning = 0;
#endif /* HAVE_GCRYPT_H */
if (pkg_type == TYPE_ENCR_AES256)
{
status = parse_part_encr_aes256 (se,
- &buffer, &buffer_size,
- flags);
+ &buffer, &buffer_size, flags);
if (status != 0)
{
ERROR ("network plugin: Decrypting AES256 "
#endif /* HAVE_GCRYPT_H */
else if (pkg_type == TYPE_SIGN_SHA256)
{
- status = parse_part_sign_sha256 (se, &buffer, &buffer_size);
- if (status < 0)
+ status = parse_part_sign_sha256 (se,
+ &buffer, &buffer_size, flags);
+ if (status != 0)
{
ERROR ("network plugin: Verifying HMAC-SHA-256 "
"signature failed "
"with status %i.", status);
break;
}
- else if (status > 0)
- {
- ERROR ("network plugin: Ignoring packet with "
- "invalid HMAC-SHA-256 signature.");
- break;
- }
- else
- {
- packet_was_signed = 1;
- }
}
#if HAVE_GCRYPT_H
else if ((se->security_level == SECURITY_LEVEL_SIGN)
pea.orig_length = htons ((uint16_t) in_buffer_size);
/* Chose a random initialization vector. */
- gcry_randomize (&pea.iv, sizeof (pea.iv), GCRY_STRONG_RANDOM);
+ gcry_randomize ((void *) &pea.iv, sizeof (pea.iv), GCRY_STRONG_RANDOM);
/* Create hash of the payload */
gcry_md_hash_buffer (GCRY_MD_SHA1, pea.hash, in_buffer, in_buffer_size);
/* Fill the extra field with random values. Some entropy in the encrypted
* data is usually not a bad thing, I hope. */
if (padding_size > 0)
- gcry_randomize (&pea.padding, padding_size, GCRY_STRONG_RANDOM);
+ gcry_randomize ((void *) &pea.padding, padding_size, GCRY_STRONG_RANDOM);
/* Initialize the buffer */
buffer_offset = 0;
/**
* collectd - src/openvpn.c
* Copyright (C) 2008 Doug MacEachern
- * Copyright (C) 2008 Florian octo Forster
+ * Copyright (C) 2009 Florian octo Forster
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
pse.num_proc = 1;
pse.num_lwp = procs[i].ki_numthreads;
+ pse.vmem_size = procs[i].ki_size;
pse.vmem_rss = procs[i].ki_rssize * getpagesize();
+ pse.stack_size = procs[i].ki_ssize * getpagesize();
pse.vmem_minflt = 0;
pse.vmem_minflt_counter = procs[i].ki_rusage.ru_minflt;
pse.vmem_majflt = 0;
charge value:GAUGE:0:U
compression_ratio value:GAUGE:0:2
connections value:COUNTER:0:U
+conntrack entropy:GAUGE:0:4294967295
counter value:COUNTER:U:U
cpufreq value:GAUGE:0:U
cpu value:COUNTER:0:4294967295
#include "plugin.h"
#if KERNEL_LINUX
-# define UPTIME_FILE "/proc/uptime"
-/* No need for includes, using /proc filesystem, Linux only. */
+# define STAT_FILE "/proc/stat"
+/* Using /proc filesystem to retrieve the boot time, Linux only. */
/* #endif KERNEL_LINUX */
#elif HAVE_LIBKSTAT
-/* Using kstats chain to retrieve the boot time, this applies to:
- * - Solaris / OpenSolaris
- */
+/* Using kstats chain to retrieve the boot time on Solaris / OpenSolaris systems */
/* #endif HAVE_LIBKSTAT */
#elif HAVE_SYS_SYSCTL_H
# include <sys/sysctl.h>
-/* Using sysctl interface to retrieve the boot time, this applies to:
- * - *BSD
- * - Darwin / OS X
- */
+/* Using sysctl interface to retrieve the boot time on *BSD / Darwin / OS X systems */
/* #endif HAVE_SYS_SYSCTL_H */
#else
# error "No applicable input method."
#endif
-/*
+/*
* Global variables
*/
-#if KERNEL_LINUX
-/* global variables not needed */
-/* #endif KERNEL_LINUX */
-
-#elif HAVE_LIBKSTAT
+/* boottime always used, no OS distinction */
static time_t boottime;
-extern kstat_ctl_t *kc;
-/* #endif HAVE_LIBKSTAT */
-#elif HAVE_SYS_SYSCTL_H
-static time_t boottime;
-#endif
+#if HAVE_LIBKSTAT
+extern kstat_ctl_t *kc;
+#endif /* #endif HAVE_LIBKSTAT */
static void uptime_submit (gauge_t uptime)
{
plugin_dispatch_values (&vl);
}
-#if !defined(KERNEL_LINUX) || !KERNEL_LINUX
-static int uptime_init (void)
+static int uptime_init (void) /* {{{ */
{
-/* NOTE
-
- On unix systems other than Linux there is no /proc filesystem which
- calculates the uptime every time we call a read for the /proc/uptime
- file, the only information available is the boot time (in unix time,
- since epoch). Hence there is no need to read, every time the
- plugin_read is called, a value that won't change: this is a right
- task for the uptime_init function. However, since uptime_init is run
- only once, if the function fails in retrieving the boot time, the
- plugin is unregistered and there is no chance to try again later.
- Nevertheless, this is very unlikely to happen.
- */
+ /*
+ * On most unix systems the uptime is calculated by looking at the boot
+ * time (stored in unix time, since epoch) and the current one. We are
+ * going to do the same, reading the boot time value while executing
+ * the uptime_init function (there is no need to read, every time the
+ * plugin_read is called, a value that won't change). However, since
+ * uptime_init is run only once, if the function fails in retrieving
+ * the boot time, the plugin is unregistered and there is no chance to
+ * try again later. Nevertheless, this is very unlikely to happen.
+ */
+
+#if KERNEL_LINUX
+ unsigned long starttime;
+ char buffer[1024];
+ int ret;
+ FILE *fh;
+
+ ret = 0;
+
+ fh = fopen (STAT_FILE, "r");
+
+ if (fh == NULL)
+ {
+ char errbuf[1024];
+ ERROR ("uptime plugin: Cannot open "STAT_FILE": %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ return (-1);
+ }
+
+ while (fgets (buffer, 1024, fh) != NULL)
+ {
+ /* look for the btime string and read the value */
+ ret = sscanf (buffer, "btime %lu", &starttime);
+ /* avoid further loops if btime has been found and read
+ * correctly (hopefully) */
+ if (ret == 1)
+ break;
+ }
+
+ fclose (fh);
+
+ /* loop done, check if no value has been found/read */
+ if (ret != 1)
+ {
+ ERROR ("uptime plugin: No value read from "STAT_FILE"");
+ return (-1);
+ }
+
+ boottime = (time_t) starttime;
+
+ if (boottime == 0)
+ {
+ ERROR ("uptime plugin: btime read from "STAT_FILE", "
+ "but `boottime' is zero!");
+ return (-1);
+ }
+/* #endif KERNEL_LINUX */
-# if HAVE_LIBKSTAT
+#elif HAVE_LIBKSTAT
kstat_t *ksp;
kstat_named_t *knp;
ksp = NULL;
knp = NULL;
- /* kstats chain already opened by update_kstat (using *kc), let's verify everything went fine. */
+ /* kstats chain already opened by update_kstat (using *kc), verify everything went fine. */
if (kc == NULL)
{
ERROR ("uptime plugin: kstat chain control structure not available.");
}
boottime = (time_t) knp->value.ui32;
+
+ if (boottime == 0)
+ {
+ ERROR ("uptime plugin: kstat_data_lookup returned success, "
+ "but `boottime' is zero!");
+ return (-1);
+ }
/* #endif HAVE_LIBKSTAT */
# elif HAVE_SYS_SYSCTL_H
size_t boottv_len;
int status;
- int mib[2];
+ int mib[2];
- mib[0] = CTL_KERN;
- mib[1] = KERN_BOOTTIME;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_BOOTTIME;
- memset (&boottv, 0, sizeof (boottv));
- boottv_len = sizeof (boottv);
+ boottv_len = sizeof (boottv);
+ memset (&boottv, 0, boottv_len);
status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &boottv, &boottv_len,
/* new_value = */ NULL, /* new_length = */ 0);
if (status != 0)
- {
- char errbuf[1024];
- ERROR ("uptime plugin: No value read from sysctl interface: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return (-1);
- }
+ {
+ char errbuf[1024];
+ ERROR ("uptime plugin: No value read from sysctl interface: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ return (-1);
+ }
boottime = boottv.tv_sec;
+
if (boottime == 0)
{
ERROR ("uptime plugin: sysctl(3) returned success, "
#endif /* HAVE_SYS_SYSCTL_H */
return (0);
-
-}
-#endif /* !KERNEL_LINUX */
+} /* }}} int uptime_init */
static int uptime_read (void)
{
gauge_t uptime;
-
-#if KERNEL_LINUX
- FILE *fh;
-
- fh = fopen (UPTIME_FILE, "r");
-
- if (fh == NULL)
- {
- char errbuf[1024];
- ERROR ("uptime plugin: Cannot open "UPTIME_FILE": %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return (-1);
- }
-
- if ( fscanf (fh, "%lf", &uptime) < 1 )
- {
- WARNING ("uptime plugin: No value read from "UPTIME_FILE);
- fclose (fh);
- return (-1);
- }
-
- fclose (fh);
-/* #endif KERNEL_LINUX */
-
-#elif HAVE_LIBKSTAT || HAVE_SYS_SYSCTL_H
time_t elapsed;
+ /* calculate the ammount of time elapsed since boot, AKA uptime */
elapsed = time (NULL) - boottime;
uptime = (gauge_t) elapsed;
-#endif /* HAVE_LIBKSTAT || HAVE_SYS_SYSCTL_H */
uptime_submit (uptime);
void module_register (void)
{
-#if !defined(KERNEL_LINUX) || !KERNEL_LINUX
plugin_register_init ("uptime", uptime_init);
-#endif
plugin_register_read ("uptime", uptime_read);
} /* void module_register */