Merge branch 'dm/t_option'
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Sat, 17 Jan 2009 10:04:24 +0000 (11:04 +0100)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Sat, 17 Jan 2009 10:04:24 +0000 (11:04 +0100)
.gitignore
configure.in
src/common.c
src/common.h
src/libcollectdclient/Makefile.am
src/libcollectdclient/client.c
src/libcollectdclient/client.h
src/libcollectdclient/lcc_features.h.in [new file with mode: 0644]
src/openvpn.c
src/processes.c
src/types.db

index 03bd0c4..05c0aca 100644 (file)
@@ -50,6 +50,10 @@ src/collectd*.1
 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
index 55ce936..a220c2a 100644 (file)
@@ -3075,6 +3075,23 @@ fi
 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" \
index ae89c44..aeea28d 100644 (file)
@@ -925,4 +925,22 @@ int read_file_contents (const char *filename, char *buf, int bufsize)
        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 */
index f463b77..aefc2cc 100644 (file)
@@ -209,4 +209,6 @@ int walk_directory (const char *dir, dirwalk_callback_f callback,
                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 */
index ca50560..b8a8cbe 100644 (file)
@@ -4,8 +4,10 @@ if COMPILER_IS_GCC
 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
index b2f2daf..c5be3b9 100644 (file)
@@ -52,6 +52,8 @@
 # include "config.h"
 #endif
 
+#include "lcc_features.h"
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -533,6 +535,21 @@ static int lcc_open_socket (lcc_connection_t *c, const char *addr) /* {{{ */
 /*
  * 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;
index a0ab94c..d5371fb 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef LIBCOLLECTD_COLLECTDCLIENT_H
 #define LIBCOLLECTD_COLLECTDCLIENT_H 1
 
+#include "lcc_features.h"
+
 /*
  * Includes (for data types)
  */
@@ -32,7 +34,6 @@
 /*
  * Defines
  */
-#define LCC_VERSION 0
 #define LCC_NAME_LEN 64
 #define LCC_DEFAULT_PORT "25826"
 
@@ -42,6 +43,8 @@
 #define LCC_TYPE_COUNTER 0
 #define LCC_TYPE_GAUGE   1
 
+LCC_BEGIN_DECLS
+
 typedef uint64_t counter_t;
 typedef double gauge_t;
 
@@ -105,5 +108,7 @@ int lcc_identifier_to_string (lcc_connection_t *c,
 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 */
diff --git a/src/libcollectdclient/lcc_features.h.in b/src/libcollectdclient/lcc_features.h.in
new file mode 100644 (file)
index 0000000..3916a17
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+ * 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 : */
+
index c79ccb7..a2f4823 100644 (file)
 
 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"
@@ -77,16 +84,41 @@ static void openvpn_submit (char *name, counter_t rx, counter_t tx)
        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");
@@ -99,23 +131,87 @@ static int openvpn_read (void)
          */
        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 */
 
index f4ffef8..0d670f5 100644 (file)
@@ -118,7 +118,9 @@ typedef struct procstat_entry_s
 
        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;
@@ -143,7 +145,9 @@ typedef struct procstat
 
        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;
@@ -315,13 +319,17 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t
                }
 
                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))
@@ -410,7 +418,9 @@ static void ps_list_reset (void)
        {
                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;
@@ -562,11 +572,21 @@ static void ps_submit_proc_list (procstat_t *ps)
        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;
@@ -672,7 +692,9 @@ int ps_read_process (int pid, procstat_t *ps, char *state)
 
        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));
 
@@ -739,10 +761,20 @@ int ps_read_process (int pid, procstat_t *ps, char *state)
 
        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;
@@ -750,7 +782,9 @@ int ps_read_process (int pid, procstat_t *ps, char *state)
 
        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);
@@ -1198,9 +1232,11 @@ static int ps_read (void)
                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;
index 67d8f0d..48ac6c3 100644 (file)
@@ -7,6 +7,7 @@ bytes                   value:GAUGE:0:U
 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
@@ -80,7 +81,9 @@ ps_count              processes:GAUGE:0:1000000, threads:GAUGE:0:1000000
 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