summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e096f0f)
raw | patch | inline | side by side (parent: e096f0f)
author | Florian Forster <octo@noris.net> | |
Thu, 27 Mar 2008 14:42:40 +0000 (15:42 +0100) | ||
committer | Florian Forster <octo@noris.net> | |
Thu, 27 Mar 2008 14:42:40 +0000 (15:42 +0100) |
README | patch | blob | history | |
configure.in | patch | blob | history | |
src/Makefile.am | patch | blob | history | |
src/collectd.conf.in | patch | blob | history | |
src/types.db | patch | blob | history | |
src/vmem.c | [new file with mode: 0644] | patch | blob |
index 9dba7cde7e5cf52da88e96aafdd08ac9462b9a29..f298bd3aa8142d0dc91c0e486f52d47d6ea32827 100644 (file)
--- a/README
+++ b/README
- users
Users currently logged in.
+ - vmem
+ Virtual memory statistics, e. g. the number of page-ins/-outs or the
+ number of pagefaults.
+
- vserver
System resources used by Linux VServers.
See <http://linux-vserver.org/>.
diff --git a/configure.in b/configure.in
index d53706dfbb87807975e57b234548c3eb291e8299..8175746dcb2596f2288e68f50d531b44fac98207 100644 (file)
--- a/configure.in
+++ b/configure.in
plugin_tape="no"
plugin_tcpconns="no"
plugin_users="no"
+plugin_vmem="no"
plugin_vserver="no"
plugin_wireless="no"
plugin_serial="yes"
plugin_swap="yes"
plugin_tcpconns="yes"
+ plugin_vmem="yes"
plugin_vserver="yes"
plugin_wireless="yes"
AC_PLUGIN([unixsock], [yes], [Unixsock communication plugin])
AC_PLUGIN([users], [$plugin_users], [User statistics])
AC_PLUGIN([uuid], [yes], [UUID as hostname plugin])
+AC_PLUGIN([vmem], [$plugin_vmem], [Virtual memory statistics])
AC_PLUGIN([vserver], [$plugin_vserver], [Linux VServer statistics])
AC_PLUGIN([wireless], [$plugin_wireless], [Wireless statistics])
AC_PLUGIN([xmms], [$with_libxmms], [XMMS statistics])
unixsock . . . . . $enable_unixsock
users . . . . . . . $enable_users
uuid . . . . . . . $enable_uuid
+ vmem . . . . . . . $enable_vmem
vserver . . . . . . $enable_vserver
wireless . . . . . $enable_wireless
xmms . . . . . . . $enable_xmms
diff --git a/src/Makefile.am b/src/Makefile.am
index 618ef0a208f86acaebde423b7f7813e2549c6498..594c4bbcbd17fdfca5e391c3ec9e9b1accb9b154 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
collectd_DEPENDENCIES += uuid.la
endif
+if BUILD_PLUGIN_VMEM
+pkglib_LTLIBRARIES += vmem.la
+vmem_la_SOURCES = vmem.c
+vmem_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" vmem.la
+collectd_DEPENDENCIES += vmem.la
+endif
+
if BUILD_PLUGIN_VSERVER
pkglib_LTLIBRARIES += vserver.la
vserver_la_SOURCES = vserver.c
diff --git a/src/collectd.conf.in b/src/collectd.conf.in
index e125bb63173ee7585e71902feee3dacfa79cc071..c5102cd51fc182eb8cb948ffbbf5633fee966b86 100644 (file)
--- a/src/collectd.conf.in
+++ b/src/collectd.conf.in
@BUILD_PLUGIN_UNIXSOCK_TRUE@LoadPlugin unixsock
@BUILD_PLUGIN_USERS_TRUE@LoadPlugin users
@BUILD_PLUGIN_UUID_TRUE@LoadPlugin uuid
+@BUILD_PLUGIN_VMEM_TRUE@LoadPlugin vmem
@BUILD_PLUGIN_VSERVER_TRUE@LoadPlugin vserver
@BUILD_PLUGIN_WIRELESS_TRUE@LoadPlugin wireless
@BUILD_PLUGIN_XMMS_TRUE@LoadPlugin xmms
diff --git a/src/types.db b/src/types.db
index a19f26dc997a9d2513f8dc3d5221307384ebfa9f..6449aacefafbd78ec2bdd834594304f196c1ae1b 100644 (file)
--- a/src/types.db
+++ b/src/types.db
users users:GAUGE:0:65535
virt_cpu_total ns:COUNTER:0:256000000000
virt_vcpu ns:COUNTER:0:1000000000
+vmpage_action value:COUNTER:0:4294967295
+vmpage_number value:GAUGE:0:4294967295
+vmpage_faults minflt:COUNTER:0:9223372036854775807, majflt:COUNTER:0:9223372036854775807
+vmpage_io in:COUNTER:0:4294967295, out:COUNTER:0:4294967295
voltage_threshold value:GAUGE:U:U, threshold:GAUGE:U:U
voltage value:GAUGE:U:U
vs_memory value:GAUGE:0:9223372036854775807
diff --git a/src/vmem.c b/src/vmem.c
--- /dev/null
+++ b/src/vmem.c
@@ -0,0 +1,251 @@
+/**
+ * collectd - src/vmem.c
+ * Copyright (C) 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
+ * 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:
+ * Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+#if KERNEL_LINUX
+/* No global variables */
+/* #endif KERNEL_LINUX */
+
+#else
+# error "No applicable input method."
+#endif /* HAVE_LIBSTATGRAB */
+
+static void submit (const char *plugin_instance, const char *type,
+ const char *type_instance, value_t *values, int values_len)
+{
+ value_list_t vl = VALUE_LIST_INIT;
+
+ vl.values = values;
+ vl.values_len = values_len;
+
+ vl.time = time (NULL);
+ strcpy (vl.host, hostname_g);
+ strcpy (vl.plugin, "vmem");
+ if (plugin_instance != NULL)
+ sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
+ if (type_instance != NULL)
+ sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
+
+ plugin_dispatch_values (type, &vl);
+} /* void vmem_submit */
+
+static void submit_two (const char *plugin_instance, const char *type,
+ const char *type_instance, counter_t c0, counter_t c1)
+{
+ value_t values[2];
+
+ values[0].counter = c0;
+ values[1].counter = c1;
+
+ submit (plugin_instance, type, type_instance, values, 2);
+} /* void submit_one */
+
+static void submit_one (const char *plugin_instance, const char *type,
+ const char *type_instance, value_t value)
+{
+ submit (plugin_instance, type, type_instance, &value, 1);
+} /* void submit_one */
+
+static int vmem_read (void)
+{
+#if KERNEL_LINUX
+ counter_t pgpgin = 0;
+ counter_t pgpgout = 0;
+ int pgpgvalid = 0;
+
+ counter_t pswpin = 0;
+ counter_t pswpout = 0;
+ int pswpvalid = 0;
+
+ counter_t pgfault = 0;
+ counter_t pgmajfault = 0;
+ int pgfaultvalid = 0;
+
+ FILE *fh;
+ char buffer[1024];
+
+ fh = fopen ("/proc/vmstat", "r");
+ if (fh == NULL)
+ {
+ char errbuf[1024];
+ ERROR ("vmem plugin: fopen (/proc/vmstat) failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ return (-1);
+ }
+
+ while (fgets (buffer, sizeof (buffer), fh) != NULL)
+ {
+ char *fields[4];
+ int fields_num;
+ char *key;
+ char *endptr;
+ counter_t counter;
+ gauge_t gauge;
+
+ fields_num = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
+ if (fields_num != 2)
+ continue;
+
+ key = fields[0];
+
+ endptr = NULL;
+ counter = strtoll (fields[1], &endptr, 10);
+ if (fields[1] == endptr)
+ continue;
+
+ endptr = NULL;
+ gauge = strtod (fields[1], &endptr);
+ if (fields[1] == endptr)
+ continue;
+
+ /*
+ * Number of pages
+ *
+ * The total number of {inst} pages, e. g dirty pages.
+ */
+ if (strncmp ("nr_", key, strlen ("nr_")) == 0)
+ {
+ char *inst = key + strlen ("nr_");
+ value_t value = { .gauge = gauge };
+ submit_one (NULL, "vmpage_number", inst, value);
+ }
+
+ /*
+ * Number of page allocations, refills, steals and scans. This is collected
+ * ``per zone'', i. e. for DMA, DMA32, normal and possibly highmem.
+ */
+ else if (strncmp ("pgalloc_", key, strlen ("pgalloc_")) == 0)
+ {
+ char *inst = key + strlen ("pgalloc_");
+ value_t value = { .counter = counter };
+ submit_one (inst, "vmpage_action", "alloc", value);
+ }
+ else if (strncmp ("pgrefill_", key, strlen ("pgrefill_")) == 0)
+ {
+ char *inst = key + strlen ("pgrefill_");
+ value_t value = { .counter = counter };
+ submit_one (inst, "vmpage_action", "refill", value);
+ }
+ else if (strncmp ("pgsteal_", key, strlen ("pgsteal_")) == 0)
+ {
+ char *inst = key + strlen ("pgsteal_");
+ value_t value = { .counter = counter };
+ submit_one (inst, "vmpage_action", "steal", value);
+ }
+ else if (strncmp ("pgscan_kswapd_", key, strlen ("pgscan_kswapd_")) == 0)
+ {
+ char *inst = key + strlen ("pgscan_kswapd_");
+ value_t value = { .counter = counter };
+ submit_one (inst, "vmpage_action", "scan_kswapd", value);
+ }
+ else if (strncmp ("pgscan_direct_", key, strlen ("pgscan_direct_")) == 0)
+ {
+ char *inst = key + strlen ("pgscan_direct_");
+ value_t value = { .counter = counter };
+ submit_one (inst, "vmpage_action", "scan_direct", value);
+ }
+
+ /*
+ * Page in and page outs. For memory and swap.
+ */
+ else if (strcmp ("pgpgin", key) == 0)
+ {
+ pgpgin = counter;
+ pgpgvalid |= 0x01;
+ }
+ else if (strcmp ("pgpgout", key) == 0)
+ {
+ pgpgout = counter;
+ pgpgvalid |= 0x02;
+ }
+ else if (strcmp ("pswpin", key) == 0)
+ {
+ pswpin = counter;
+ pswpvalid |= 0x01;
+ }
+ else if (strcmp ("pswpout", key) == 0)
+ {
+ pswpout = counter;
+ pswpvalid |= 0x02;
+ }
+
+ /*
+ * Pagefaults
+ */
+ else if (strcmp ("pgfault", key) == 0)
+ {
+ pgfault = counter;
+ pgfaultvalid |= 0x01;
+ }
+ else if (strcmp ("pgmajfault", key) == 0)
+ {
+ pgmajfault = counter;
+ pgfaultvalid |= 0x02;
+ }
+
+ /*
+ * Page action
+ *
+ * number of pages moved to the active or inactive lists and freed, i. e.
+ * removed from either list.
+ */
+ else if (strcmp ("pgfree", key) == 0)
+ {
+ value_t value = { .counter = counter };
+ submit_one (NULL, "vmpage_action", "free", value);
+ }
+ else if (strcmp ("pgactivate", key) == 0)
+ {
+ value_t value = { .counter = counter };
+ submit_one (NULL, "vmpage_action", "activate", value);
+ }
+ else if (strcmp ("pgdeactivate", key) == 0)
+ {
+ value_t value = { .counter = counter };
+ submit_one (NULL, "vmpage_action", "deactivate", value);
+ }
+ } /* while (fgets) */
+
+ fclose (fh);
+ fh = NULL;
+
+ if (pgfaultvalid == 0x03)
+ submit_two (NULL, "vmpage_faults", NULL, pgfault, pgmajfault);
+
+ if (pgpgvalid == 0x03)
+ submit_two (NULL, "vmpage_io", "memory", pgpgin, pgpgout);
+
+ if (pswpvalid == 0x03)
+ submit_two (NULL, "vmpage_io", "swap", pswpin, pswpout);
+#endif /* KERNEL_LINUX */
+
+ return (0);
+} /* int vmem_read */
+
+void module_register (void)
+{
+ plugin_register_read ("vmem", vmem_read);
+} /* void module_register */
+
+/* vim: set sw=2 sts=2 ts=8 : */