src/collectd*.5
src/types.db.5
src/config.h.in~
+src/libcollectdclient/.libs
+src/libcollectdclient/*.la
+src/libcollectdclient/*.lo
+src/libcollectdclient/lcc_features.h
src/libiptc/.libs
src/libiptc/*.la
src/libiptc/*.lo
AC_SUBST(PERL_BINDINGS)
AC_SUBST(PERL_BINDINGS_OPTIONS)
+dnl libcollectdclient
+LCC_VERSION_MAJOR=`echo $PACKAGE_VERSION | cut -d'.' -f1`
+LCC_VERSION_MINOR=`echo $PACKAGE_VERSION | cut -d'.' -f2`
+LCC_VERSION_PATCH=`echo $PACKAGE_VERSION | cut -d'.' -f3`
+
+LCC_VERSION_EXTRA=`echo $PACKAGE_VERSION | cut -d'.' -f4-`
+
+LCC_VERSION_STRING="$LCC_VERSION_MAJOR.$LCC_VERSION_MINOR.$LCC_VERSION_PATCH"
+
+AC_SUBST(LCC_VERSION_MAJOR)
+AC_SUBST(LCC_VERSION_MINOR)
+AC_SUBST(LCC_VERSION_PATCH)
+AC_SUBST(LCC_VERSION_EXTRA)
+AC_SUBST(LCC_VERSION_STRING)
+
+AC_CONFIG_FILES(src/libcollectdclient/lcc_features.h)
+
AC_OUTPUT(Makefile src/Makefile src/collectd.conf src/libiptc/Makefile src/libcollectdclient/Makefile src/liboconfig/Makefile src/liboping/Makefile bindings/Makefile)
if test "x$with_librrd" = "xyes" \
return n;
}
+counter_t counter_diff (counter_t old_value, counter_t new_value)
+{
+ counter_t diff;
+
+ if (old_value > new_value)
+ {
+ if (old_value <= 4294967295U)
+ diff = (4294967295U - old_value) + new_value;
+ else
+ diff = (18446744073709551615ULL - old_value)
+ + new_value;
+ }
+ else
+ {
+ diff = new_value - old_value;
+ }
+ return (diff);
+} /* counter_t counter_to_gauge */
void *user_data);
int read_file_contents (const char *filename, char *buf, int bufsize);
+counter_t counter_diff (counter_t old_value, counter_t new_value);
+
#endif /* COMMON_H */
AM_CFLAGS = -Wall -Werror
endif
-pkginclude_HEADERS = client.h
+pkginclude_HEADERS = client.h lcc_features.h
lib_LTLIBRARIES = libcollectdclient.la
+BUILT_SOURCES = lcc_features.h
+
libcollectdclient_la_SOURCES = client.c
libcollectdclient_la_LDFLAGS = -version-info 0:0:0
# include "config.h"
#endif
+#include "lcc_features.h"
+
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
/*
* Public functions
*/
+unsigned int lcc_version (void) /* {{{ */
+{
+ return (LCC_VERSION);
+} /* }}} unsigned int lcc_version */
+
+const char *lcc_version_string (void) /* {{{ */
+{
+ return (LCC_VERSION_STRING);
+} /* }}} const char *lcc_version_string */
+
+const char *lcc_version_extra (void) /* {{{ */
+{
+ return (LCC_VERSION_EXTRA);
+} /* }}} const char *lcc_version_extra */
+
int lcc_connect (const char *address, lcc_connection_t **ret_con) /* {{{ */
{
lcc_connection_t *c;
#ifndef LIBCOLLECTD_COLLECTDCLIENT_H
#define LIBCOLLECTD_COLLECTDCLIENT_H 1
+#include "lcc_features.h"
+
/*
* Includes (for data types)
*/
/*
* Defines
*/
-#define LCC_VERSION 0
#define LCC_NAME_LEN 64
#define LCC_DEFAULT_PORT "25826"
#define LCC_TYPE_COUNTER 0
#define LCC_TYPE_GAUGE 1
+LCC_BEGIN_DECLS
+
typedef uint64_t counter_t;
typedef double gauge_t;
int lcc_string_to_identifier (lcc_connection_t *c,
lcc_identifier_t *ident, const char *string);
+LCC_END_DECLS
+
/* vim: set sw=2 sts=2 et : */
#endif /* LIBCOLLECTD_COLLECTDCLIENT_H */
--- /dev/null
+/**
+ * libcollectdclient - src/libcollectdclient/lcc_features.h
+ * Copyright (C) 2009 Sebastian 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
+ * 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:
+ * Sebastian tokkee Harl <sh at tokkee.org>
+ **/
+
+#ifndef LIBCOLLECTD_LCC_FEATURES_H
+#define LIBCOLLECTD_LCC_FEATURES_H 1
+
+#ifdef __cplusplus
+# define LCC_BEGIN_DECLS extern "C" {
+# define LCC_END_DECLS }
+#else
+# define LCC_BEGIN_DECLS
+# define LCC_END_DECLS
+#endif
+
+#define LCC_API_VERSION 0
+
+#define LCC_VERSION_MAJOR @LCC_VERSION_MAJOR@
+#define LCC_VERSION_MINOR @LCC_VERSION_MINOR@
+#define LCC_VERSION_PATCH @LCC_VERSION_PATCH@
+
+#define LCC_VERSION_EXTRA "@LCC_VERSION_EXTRA@"
+
+#define LCC_VERSION_STRING "@LCC_VERSION_STRING@"
+
+#define LCC_VERSION_ENCODE(major, minor, patch) \
+ ((major) * 10000 + (minor) * 100 + (patch))
+
+#define LCC_VERSION \
+ LCC_VERSION_ENCODE(LCC_VERSION_MAJOR, LCC_VERSION_MINOR, LCC_VERSION_PATCH)
+
+LCC_BEGIN_DECLS
+
+unsigned int lcc_version (void);
+
+const char *lcc_version_string (void);
+
+const char *lcc_version_extra (void);
+
+LCC_END_DECLS
+
+#endif /* ! LIBCOLLECTD_LCC_FEATURES_H */
+
+/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
+
static char *status_file = NULL;
+/* For compression stats we need to convert these counters to a rate. */
+static counter_t pre_compress_old = 0;
+static counter_t post_compress_old = 0;
+static counter_t pre_decompress_old = 0;
+static counter_t post_decompress_old = 0;
+static int compression_counter_valid = 0;
+
static const char *config_keys[] =
{
"StatusFile"
plugin_dispatch_values (&vl);
} /* void openvpn_submit */
+static void compression_submit (char *type_instance, gauge_t ratio)
+{
+ value_t values[1];
+ value_list_t vl = VALUE_LIST_INIT;
+
+ values[0].gauge = ratio;
+
+ vl.values = values;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
+ vl.time = time (NULL);
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "openvpn", sizeof (vl.plugin));
+ sstrncpy (vl.type, "compression_ratio", sizeof (vl.type));
+ sstrncpy (vl.type_instance, type_instance, sizeof (vl.type));
+
+ plugin_dispatch_values (&vl);
+} /* void compression_submit */
+
static int openvpn_read (void)
{
- char *name;
- counter_t rx, tx;
FILE *fh;
char buffer[1024];
char *fields[10];
const int max_fields = STATIC_ARRAY_SIZE (fields);
int fields_num;
+ counter_t pre_compress_new = 0;
+ counter_t post_compress_new = 0;
+ counter_t pre_decompress_new = 0;
+ counter_t post_decompress_new = 0;
+
+ /* Clear the least significant four bits, just to make sure all four
+ * counters above are considered to be invalid. */
+ compression_counter_valid &= ~0x0f;
+
fh = fopen ((status_file != NULL)
? status_file
: DEFAULT_STATUS_FILE, "r");
*/
while (fgets (buffer, sizeof (buffer), fh) != NULL)
{
- if (strncmp (buffer, CLIENT_LIST_PREFIX,
- strlen (CLIENT_LIST_PREFIX)) != 0)
- continue;
-
- /* The line we're expecting has 8 fields. We ignore all lines
- * with more or less fields. */
fields_num = openvpn_strsplit (buffer, fields, max_fields);
- if (fields_num != 8)
+
+ /* Expect at least ``key,value''. */
+ if (fields_num < 2)
continue;
- name = fields[1]; /* "Common Name" */
- rx = atoll (fields[4]); /* "Bytes Received */
- tx = atoll (fields[5]); /* "Bytes Sent" */
- openvpn_submit (name, rx, tx);
+ if (strcmp (fields[0], "CLIENT_LIST") == 0)
+ {
+ char *name;
+ counter_t rx;
+ counter_t tx;
+
+ /* The line we're expecting has 8 fields. We ignore all lines
+ * with more or less fields. */
+ if (fields_num != 8)
+ continue;
+
+ name = fields[1]; /* "Common Name" */
+ rx = atoll (fields[4]); /* "Bytes Received */
+ tx = atoll (fields[5]); /* "Bytes Sent" */
+ openvpn_submit (name, rx, tx);
+ }
+ else if (strcmp (fields[0], "pre-compress") == 0)
+ {
+ pre_compress_new = atoll (fields[1]);
+ compression_counter_valid |= 0x01;
+ }
+ else if (strcmp (fields[0], "post-compress") == 0)
+ {
+ post_compress_new = atoll (fields[1]);
+ compression_counter_valid |= 0x02;
+ }
+ else if (strcmp (fields[0], "pre-decompress") == 0)
+ {
+ pre_decompress_new = atoll (fields[1]);
+ compression_counter_valid |= 0x04;
+ }
+ else if (strcmp (fields[0], "post-decompress") == 0)
+ {
+ post_decompress_new = atoll (fields[1]);
+ compression_counter_valid |= 0x08;
+ }
}
fclose (fh);
+ /* Check that all four counters are valid, {pre,post}_*_{old,new}. */
+ if ((compression_counter_valid & 0x33) == 0x33)
+ {
+ counter_t pre_diff;
+ counter_t post_diff;
+
+ pre_diff = counter_diff (pre_compress_old, pre_compress_new);
+ post_diff = counter_diff (post_compress_old, post_compress_new);
+
+ /* If we compress, we're sending. */
+ compression_submit ("tx",
+ ((gauge_t) post_diff) / ((gauge_t) pre_diff));
+ }
+
+ /* Now check the other found counters. */
+ if ((compression_counter_valid & 0xcc) == 0xcc)
+ {
+ counter_t pre_diff;
+ counter_t post_diff;
+
+ pre_diff = counter_diff (pre_decompress_old, pre_decompress_new);
+ post_diff = counter_diff (post_decompress_old, post_decompress_new);
+
+ /* If we decompress, we're receiving. */
+ compression_submit ("rx",
+ ((gauge_t) pre_diff) / ((gauge_t) post_diff));
+ }
+
+ /* Now copy all the new counters to the old counters and move the flags
+ * up. */
+ pre_compress_old = pre_compress_new;
+ post_compress_old = post_compress_new;
+ pre_decompress_old = pre_decompress_new;
+ post_decompress_old = post_decompress_new;
+ compression_counter_valid = (compression_counter_valid & 0x0f) << 4;
+
return (0);
} /* int openvpn_read */
unsigned long num_proc;
unsigned long num_lwp;
+ unsigned long vmem_size;
unsigned long vmem_rss;
+ unsigned long stack_size;
unsigned long vmem_minflt;
unsigned long vmem_majflt;
unsigned long num_proc;
unsigned long num_lwp;
+ unsigned long vmem_size;
unsigned long vmem_rss;
+ unsigned long stack_size;
unsigned long vmem_minflt_counter;
unsigned long vmem_majflt_counter;
}
pse->age = 0;
- pse->num_proc = entry->num_proc;
- pse->num_lwp = entry->num_lwp;
- pse->vmem_rss = entry->vmem_rss;
-
- ps->num_proc += pse->num_proc;
- ps->num_lwp += pse->num_lwp;
- ps->vmem_rss += pse->vmem_rss;
+ pse->num_proc = entry->num_proc;
+ pse->num_lwp = entry->num_lwp;
+ pse->vmem_size = entry->vmem_size;
+ pse->vmem_rss = entry->vmem_rss;
+ pse->stack_size = entry->stack_size;
+
+ ps->num_proc += pse->num_proc;
+ ps->num_lwp += pse->num_lwp;
+ ps->vmem_size += pse->vmem_size;
+ ps->vmem_rss += pse->vmem_rss;
+ ps->stack_size += pse->stack_size;
if ((entry->vmem_minflt_counter == 0)
&& (entry->vmem_majflt_counter == 0))
{
ps->num_proc = 0;
ps->num_lwp = 0;
+ ps->vmem_size = 0;
ps->vmem_rss = 0;
+ ps->stack_size = 0;
pse_prev = NULL;
pse = ps->instances;
sstrncpy (vl.plugin, "processes", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, ps->name, sizeof (vl.plugin_instance));
+ sstrncpy (vl.type, "ps_vm", sizeof (vl.type));
+ vl.values[0].gauge = ps->vmem_size;
+ vl.values_len = 1;
+ plugin_dispatch_values (&vl);
+
sstrncpy (vl.type, "ps_rss", sizeof (vl.type));
vl.values[0].gauge = ps->vmem_rss;
vl.values_len = 1;
plugin_dispatch_values (&vl);
+ sstrncpy (vl.type, "ps_stacksize", sizeof (vl.type));
+ vl.values[0].gauge = ps->stack_size;
+ vl.values_len = 1;
+ plugin_dispatch_values (&vl);
+
sstrncpy (vl.type, "ps_cputime", sizeof (vl.type));
vl.values[0].counter = ps->cpu_user_counter;
vl.values[1].counter = ps->cpu_system_counter;
long long unsigned cpu_user_counter;
long long unsigned cpu_system_counter;
+ long long unsigned vmem_size;
long long unsigned vmem_rss;
+ long long unsigned stack_size;
memset (ps, 0, sizeof (procstat_t));
cpu_user_counter = atoll (fields[13]);
cpu_system_counter = atoll (fields[14]);
- vmem_rss = atoll (fields[23]);
+ vmem_size = atoll (fields[22]);
+ vmem_rss = atoll (fields[23]);
ps->vmem_minflt_counter = atol (fields[9]);
ps->vmem_majflt_counter = atol (fields[11]);
-
+
+ {
+ unsigned long long stack_start = atoll (fields[27]);
+ unsigned long long stack_ptr = atoll (fields[28]);
+
+ stack_size = (stack_start > stack_ptr)
+ ? stack_start - stack_ptr
+ : stack_ptr - stack_start;
+ }
+
/* Convert jiffies to useconds */
cpu_user_counter = cpu_user_counter * 1000000 / CONFIG_HZ;
cpu_system_counter = cpu_system_counter * 1000000 / CONFIG_HZ;
ps->cpu_user_counter = (unsigned long) cpu_user_counter;
ps->cpu_system_counter = (unsigned long) cpu_system_counter;
+ ps->vmem_size = (unsigned long) vmem_size;
ps->vmem_rss = (unsigned long) vmem_rss;
+ ps->stack_size = (unsigned long) stack_size;
/* success */
return (0);
pse.id = pid;
pse.age = 0;
- pse.num_proc = ps.num_proc;
- pse.num_lwp = ps.num_lwp;
- pse.vmem_rss = ps.vmem_rss;
+ pse.num_proc = ps.num_proc;
+ pse.num_lwp = ps.num_lwp;
+ pse.vmem_size = ps.vmem_size;
+ pse.vmem_rss = ps.vmem_rss;
+ pse.stack_size = ps.stack_size;
pse.vmem_minflt = 0;
pse.vmem_minflt_counter = ps.vmem_minflt_counter;
cache_result value:COUNTER:0:4294967295
cache_size value:GAUGE:0:4294967295
charge value:GAUGE:0:U
+compression_ratio value:GAUGE:0:2
connections value:COUNTER:0:U
counter value:COUNTER:U:U
cpufreq value:GAUGE:0:U
ps_cputime user:COUNTER:0:16000000, syst:COUNTER:0:16000000
ps_pagefaults minflt:COUNTER:0:9223372036854775807, majflt:COUNTER:0:9223372036854775807
ps_rss value:GAUGE:0:9223372036854775807
+ps_stacksize value:GAUGE:0:9223372036854775807
ps_state value:GAUGE:0:65535
+ps_vm value:GAUGE:0:9223372036854775807
queue_length value:GAUGE:0:U
serial_octets rx:COUNTER:0:4294967295, tx:COUNTER:0:4294967295
signal_noise value:GAUGE:U:0