Varnish plugin: Add a new plugin for reading values from Varnish, a web proxy server.
authorJérôme Renard <jerome.renard@gmail.com>
Fri, 4 Jun 2010 14:17:33 +0000 (16:17 +0200)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Fri, 4 Jun 2010 14:17:33 +0000 (16:17 +0200)
Hi list,

I created a new plugin to monitor a Varnish [1] instance.

So far the plugin monitor statistics about cache (hit/misses) and
connections but could monitor more in the future.

The patch is attached to this message, it has been generated against
the master branch of my local collectd copy.

Any feedback welcome

Have a nice day :)

Best Regards

1. http://varnish-software.com/

--
Jérôme

Signed-off-by: Florian Forster <octo@leeloo.lan.home.verplant.org>
README
configure.in
src/Makefile.am
src/collectd.conf.in
src/types.db
src/varnish.c [new file with mode: 0644]

diff --git a/README b/README
index ade430c..17b62d8 100644 (file)
--- a/README
+++ b/README
@@ -650,6 +650,10 @@ Prerequisites
     Parse JSON data. This is needed for the `curl_json' plugin.
     <http://github.com/lloyd/yajl>
 
+  * libvarnish (optional)
+     Fetches statistics from a Varnish instance. This is needed for the Varnish plugin
+     <http://varnish-cache.org>
+
 Configuring / Compiling / Installing
 ------------------------------------
 
index dbb4c32..79dd6f8 100644 (file)
@@ -3686,6 +3686,61 @@ fi
 AM_CONDITIONAL(BUILD_WITH_LIBYAJL, test "x$with_libyajl" = "xyes")
 # }}}
 
+# --with-libvarnish {{{
+with_libvarnish_cppflags=""
+with_libvarnish_ldflags=""
+with_libvarnish_cflags="-lvarnish -lvarnishcompat -lvarnishapi"
+AC_ARG_WITH(libvarnish, [AS_HELP_STRING([--with-libvarnish@<:@=PREFIX@:>@], [Path to libvarnish.])],
+[
+       if test "x$withval" != "xno" && test "x$withval" != "xyes"
+       then
+               with_libvarnish_cppflags="-I$withval/include"
+               with_libvarnish_ldflags="-L$withval/lib"
+               with_libvarnish="yes"
+       else
+               with_libvarnish="$withval"
+       fi
+],
+[
+       with_libvarnish="yes"
+])
+if test "x$with_libvarnish" = "xyes"
+then
+       SAVE_CPPFLAGS="$CPPFLAGS"
+       CPPFLAGS="$CPPFLAGS $with_libvarnish_cppflags"
+
+       AC_CHECK_HEADERS(varnish/varnishapi.h, [with_libvarnish="yes"], [with_libvarnish="no (varnish/varnishapi.h not found)"])
+
+       CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libvarnish" = "xyes"
+then
+       SAVE_CPPFLAGS="$CPPFLAGS"
+       SAVE_LDFLAGS="$LDFLAGS"
+       SAVE_CFLAGS="$CFLAGS"
+       CPPFLAGS="$CPPFLAGS $with_libvarnish_cppflags"
+       LDFLAGS="$LDFLAGS $with_libvarnish_ldflags"
+       CFLAGS="$CFLAGS $with_libvarnish_cflags"
+
+       AC_CHECK_LIB(varnishapi, VSL_OpenStats, [with_libvarnish="yes"], [with_libvarnish="no (Symbol 'VSL_OpenStats' not found)"])
+
+       CPPFLAGS="$SAVE_CPPFLAGS"
+       LDFLAGS="$SAVE_LDFLAGS"
+       CFLAGS="$SAVE_CFLAGS"
+fi
+if test "x$with_libvarnish" = "xyes"
+then
+       BUILD_WITH_LIBVARNISH_CPPFLAGS="$with_libvarnish_cppflags"
+       BUILD_WITH_LIBVARNISH_LDFLAGS="$with_libvarnish_ldflags"
+       BUILD_WITH_LIBVARNISH_LIBS="-lvarnishcompat -lvarnish -lvarnishapi"
+       AC_SUBST(BUILD_WITH_LIBVARNISH_CPPFLAGS)
+       AC_SUBST(BUILD_WITH_LIBVARNISH_LDFLAGS)
+       AC_SUBST(BUILD_WITH_LIBVARNISH_LIBS)
+       AC_DEFINE(HAVE_LIBVARNISH, 1, [Define if libvarnish is present and usable.])
+fi
+AM_CONDITIONAL(BUILD_WITH_LIBVARNISH, test "x$with_libvarnish" = "xyes")
+# }}}
+
 # pkg-config --exists 'libxml-2.0'; pkg-config --exists libvirt {{{
 with_libxml2="no (pkg-config isn't available)"
 with_libxml2_cflags=""
@@ -4401,6 +4456,7 @@ AC_PLUGIN([unixsock],    [yes],                [Unixsock communication plugin])
 AC_PLUGIN([uptime],      [$plugin_uptime],     [Uptime statistics])
 AC_PLUGIN([users],       [$plugin_users],      [User statistics])
 AC_PLUGIN([uuid],        [yes],                [UUID as hostname plugin])
+AC_PLUGIN([varnish],     [$with_libvarnish],   [Varnish cache statistics])
 AC_PLUGIN([vmem],        [$plugin_vmem],       [Virtual memory statistics])
 AC_PLUGIN([vserver],     [$plugin_vserver],    [Linux VServer statistics])
 AC_PLUGIN([wireless],    [$plugin_wireless],   [Wireless statistics])
@@ -4608,6 +4664,7 @@ Configuration:
     libstatgrab . . . . . $with_libstatgrab
     libtokyotyrant  . . . $with_libtokyotyrant
     libupsclient  . . . . $with_libupsclient
+    libvarnish  . . . . . $with_libvarnish
     libvirt . . . . . . . $with_libvirt
     libxml2 . . . . . . . $with_libxml2
     libxmms . . . . . . . $with_libxmms
@@ -4718,6 +4775,7 @@ Configuration:
     uptime  . . . . . . . $enable_uptime
     users . . . . . . . . $enable_users
     uuid  . . . . . . . . $enable_uuid
+    varnish . . . . . . . $enable_varnish
     vmem  . . . . . . . . $enable_vmem
     vserver . . . . . . . $enable_vserver
     wireless  . . . . . . $enable_wireless
index 0c0e6fc..a343679 100644 (file)
@@ -1151,6 +1151,20 @@ collectd_LDADD += "-dlopen" uuid.la
 collectd_DEPENDENCIES += uuid.la
 endif
 
+if BUILD_PLUGIN_VARNISH
+pkglib_LTLIBRARIES += varnish.la
+varnish_la_SOURCES = varnish.c
+varnish_la_LDFLAGS = -module -avoid-version
+varnish_la_CFLAGS = $(AM_CFLAGS)
+varnish_la_LIBADD =
+collectd_LDADD += "-dlopen" varnish.la
+if BUILD_WITH_LIBVARNISH
+varnish_la_CFLAGS += $(BUILD_WITH_LIBVARNISH_CFLAGS)
+varnish_la_LIBADD += $(BUILD_WITH_LIBVARNISH_LIBS)
+endif
+collectd_DEPENDENCIES += varnish.la
+endif
+
 if BUILD_PLUGIN_VMEM
 pkglib_LTLIBRARIES += vmem.la
 vmem_la_SOURCES = vmem.c
index 3c94a6f..92de897 100644 (file)
 #@BUILD_PLUGIN_UPTIME_TRUE@LoadPlugin uptime
 #@BUILD_PLUGIN_USERS_TRUE@LoadPlugin users
 #@BUILD_PLUGIN_UUID_TRUE@LoadPlugin uuid
+#@BUILD_PLUGIN_VARNISH_TRUE@LoadPlugin varnish
 #@BUILD_PLUGIN_VMEM_TRUE@LoadPlugin vmem
 #@BUILD_PLUGIN_VSERVER_TRUE@LoadPlugin vserver
 #@BUILD_PLUGIN_WIRELESS_TRUE@LoadPlugin wireless
 #      UUIDFile "/etc/uuid"
 #</Plugin>
 
+#<Plugin varnish>
+#  MonitorCache yes
+#  MonitorConnections yes
+#  MonitorESI yes
+#</Plugin>
+
 #<Plugin vmem>
 #      Verbose false
 #</Plugin>
index 69301b2..495de96 100644 (file)
@@ -160,6 +160,9 @@ total_time_in_ms    value:DERIVE:0:U
 total_values           value:DERIVE:0:U
 uptime                 value:GAUGE:0:4294967295
 users                  users:GAUGE:0:65535
+varnish_cache_ratio    value:GAUGE:0:U
+varnish_connections    value:GAUGE:0:U
+varnish_esi            value:GAUGE:0:U
 virt_cpu_total         ns:COUNTER:0:256000000000
 virt_vcpu              ns:COUNTER:0:1000000000
 vmpage_action          value:COUNTER:0:4294967295
diff --git a/src/varnish.c b/src/varnish.c
new file mode 100644 (file)
index 0000000..4329687
--- /dev/null
@@ -0,0 +1,124 @@
+/**
+ * collectd - src/varnish.c
+ * Copyright (C) 2010 Jerome Renard
+ *
+ * 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:
+ *   Jerome Renard <jerome.renard@gmail.com>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+#include <varnish/varnishapi.h>
+
+#define USER_CONFIG_INIT {0, 0, 0}
+#define SET_MONITOR_FLAG(name, flag, value) if((strcasecmp(name, key) == 0) && IS_TRUE(value)) user_config.flag = 1
+
+/* {{{ user_config_s */
+struct user_config_s {
+       int monitor_cache;
+       int monitor_connections;
+       int monitor_esi;
+};
+
+typedef struct user_config_s user_config_t; /* }}} */
+
+/* {{{ Configuration directives */
+static user_config_t user_config = USER_CONFIG_INIT;
+
+static const char *config_keys[] =
+{
+  "MonitorCache",
+  "MonitorConnections",
+  "MonitorESI"
+};
+
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); /* }}} */
+
+static int varnish_config(const char *key, const char *value) /* {{{ */
+{
+       SET_MONITOR_FLAG("MonitorCache", monitor_cache, value);
+       SET_MONITOR_FLAG("MonitorConnections", monitor_connections, value);
+       SET_MONITOR_FLAG("MonitorESI", monitor_esi, value);
+
+       return (0);
+} /* }}} */
+
+static void varnish_submit(const char *type, const char *type_instance, gauge_t value) /* {{{ */
+{
+       value_t values[1];
+       value_list_t vl = VALUE_LIST_INIT;
+
+       values[0].gauge = value;
+       vl.values_len = 1;
+       vl.values = values;
+
+       sstrncpy(vl.host         , hostname_g   , sizeof(vl.host));
+       sstrncpy(vl.plugin       , "varnish"    , sizeof(vl.plugin));
+       sstrncpy(vl.type         , type         , sizeof(vl.type));
+       sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
+
+       plugin_dispatch_values(&vl);
+} /* }}} */
+
+static void varnish_monitor(struct varnish_stats *VSL_stats) /* {{{ */
+{
+       if(user_config.monitor_cache == 1)
+       {
+               varnish_submit("varnish_cache_ratio", "cache_hit"    , VSL_stats->cache_hit);
+               varnish_submit("varnish_cache_ratio", "cache_miss"   , VSL_stats->cache_miss);
+               varnish_submit("varnish_cache_ratio", "cache_hitpass", VSL_stats->cache_hitpass);
+       }
+
+       if(user_config.monitor_connections == 1)
+       {
+               varnish_submit("varnish_connections", "client_connections-accepted", VSL_stats->client_conn);
+               varnish_submit("varnish_connections", "client_connections-dropped" , VSL_stats->client_drop);
+               varnish_submit("varnish_connections", "client_connections-received", VSL_stats->client_req);
+       }
+
+       if(user_config.monitor_esi == 1)
+       {
+               varnish_submit("varnish_esi", "esi_parsed", VSL_stats->esi_parse);
+               varnish_submit("varnish_esi", "esi_errors", VSL_stats->esi_errors);
+       }
+} /* }}} */
+
+static int varnish_read(void) /* {{{ */
+{
+       struct varnish_stats *VSL_stats;
+       const char *varnish_instance_name = NULL;
+
+       if ((VSL_stats = VSL_OpenStats(varnish_instance_name)) == NULL)
+       {
+               ERROR("Varnish plugin : unable to load statistics");
+
+               return (-1);
+       }
+
+       varnish_monitor(VSL_stats);
+
+    return (0);
+} /* }}} */
+
+void module_register (void) /* {{{ */
+{
+       plugin_register_config("varnish", varnish_config, config_keys, config_keys_num);
+       plugin_register_read("varnish", varnish_read);
+} /* }}} */
+
+/* vim: set sw=8 noet fdm=marker : */