From e9a9482ab6d6ce752fff934625be962d0f88251b Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Renard?= Date: Fri, 4 Jun 2010 16:17:33 +0200 Subject: [PATCH] Varnish plugin: Add a new plugin for reading values from Varnish, a web proxy server. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- README | 4 ++ configure.in | 58 ++++++++++++++++++++++++ src/Makefile.am | 14 ++++++ src/collectd.conf.in | 7 +++ src/types.db | 3 ++ src/varnish.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 210 insertions(+) create mode 100644 src/varnish.c diff --git a/README b/README index ade430cc..17b62d89 100644 --- a/README +++ b/README @@ -650,6 +650,10 @@ Prerequisites Parse JSON data. This is needed for the `curl_json' plugin. + * libvarnish (optional) + Fetches statistics from a Varnish instance. This is needed for the Varnish plugin + + Configuring / Compiling / Installing ------------------------------------ diff --git a/configure.in b/configure.in index dbb4c32a..79dd6f8a 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/src/Makefile.am b/src/Makefile.am index 0c0e6fcd..a343679c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/collectd.conf.in b/src/collectd.conf.in index 3c94a6f9..92de8976 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -130,6 +130,7 @@ #@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 @@ -842,6 +843,12 @@ # UUIDFile "/etc/uuid" # +# +# MonitorCache yes +# MonitorConnections yes +# MonitorESI yes +# + # # Verbose false # diff --git a/src/types.db b/src/types.db index 69301b27..495de961 100644 --- a/src/types.db +++ b/src/types.db @@ -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 index 00000000..4329687e --- /dev/null +++ b/src/varnish.c @@ -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 + **/ + +#include "collectd.h" +#include "common.h" +#include "plugin.h" + +#include + +#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 : */ -- 2.11.0