--- /dev/null
+# $Id$
+
+EXTRA_DIST = varnish_munin_plugin.pl
+
+install-exec-local:
+ ${install_sh} -m 0755 -c varnish_munin_plugin.pl \
+ ${DESTDIR}${bindir}/varnish_
+# for aspect in `${DESTDIR}${bindir}/varnish_ aspects` ; do \
+# ln -fs varnish_ ${DESTDIR}${bindir}/varnish_$$aspect ; \
+# done
+++ /dev/null
-The scripts in this directory are munin plugins for monitoring varnish.
-varnish_cachehitratio and varnish_hitrate are written by Anders
-Nordby, while varnish_varnishstat_ is written by Bjørn
-Ruberg. All three scripts uses varnishstat to acquire information.
-
-* varnish_cachehitratio shows the cache hit/miss ratio.
-* varnish_hitrate shows the rate of requests.
-* varnish_varnishstat_ shows the cache usage.
-
-To work with named varnish instances, these scripts will have to be modified
-so they can call varnishstat with the appropriate parameter. As of today,
-the scripts only call 'varnishstat -1', and thus, will only work if varnishd
-was started without the -n parameter. A solution to this problem could be to
-let the scripts read a filename from an environment variable (this must then
-be set in the munin-plugin configuration), and have this file contain the
-name (or names?) to the varnish server(s) to monitor. If the environment
-variable is not set, varnishstat will be called without the -n parameter,
-and work with the default name.
-
-Dependencies:
-* varnish_cachehitration needs the CPAN module Date::Format
-* varnish_varnishstart_ needs the CPAN module Net::Telnet
-(but does it really? It doesn't seem to use it for anything.)
--- /dev/null
+#!/bin/sh
+#
+# $Id$
+#
+
+if [ -d /usr/local/gnu-autotools/bin ] ; then
+ PATH=/usr/local/gnu-autotools/bin:${PATH}
+ export PATH
+ FIX_BROKEN_FREEBSD_PORTS="-I /usr/local/share/aclocal"
+fi
+
+automake_version=$(automake --version | tr ' ' '\n' | egrep '^[0-9]\.[0-9a-z.-]+')
+if [ -z "$automake_version" ] ; then
+ echo "unable to determine automake version"
+ exit 1
+else
+ case $automake_version in
+ 0.*|1.[0-8]|1.[0-8][.-]*)
+ echo "your version of automake ($automake_version) is too old;" \
+ "you need 1.9 or newer."
+ exit 1
+ ;;
+ *)
+ ;;
+ esac
+fi
+
+set -ex
+
+aclocal ${FIX_BROKEN_FREEBSD_PORTS}
+automake --add-missing --copy --foreign
+autoconf
--- /dev/null
+# $Id$
+
+AC_PREREQ(2.59)
+AC_COPYRIGHT([Copyright (c) 2007 Linpro AS / Verdens Gang AS])
+AC_REVISION([$Id$])
+AC_INIT([Varnish Munin plugin], [trunk], [varnish-dev@projects.linpro.no])
+AC_CONFIG_SRCDIR(varnish_munin_plugin.pl)
+
+AC_CANONICAL_SYSTEM
+
+AM_INIT_AUTOMAKE
+
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+AC_CHECK_PROGS(PERL, [perl])
+AC_CHECK_PROGS(VARNISHSTAT, [varnishstat])
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+++ /dev/null
-#! /usr/bin/perl
-# Varnish cache hit ratio logger/plugin
-# anders@aftenposten.no, 2007-05-07
-
-# Log/data file
-# These must be created with write permission to the user the plugin runs as
-# On FreeBSD, that is nobody
-# Comment $mylog out to skip logging
-
-$mydat = "/var/tmp/varnish_cachehitratio.dat";
-#$mylog = "/var/log/varnish_cachehitratio.log";
-
-%stat = ();
-$ENV{PATH} = "/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin";
-
-use Date::Format;
-
-sub popstat {
- foreach $line (`varnishstat -1`) {
- chomp($line);
- if ($line =~ /^\s+(\d+)\s+(.*)$/) {
- $val = $1;
- $key = $2;
- $key =~ s@\s@_@g;
- $key =~ tr@A-Z@a-z@;
-
- $stat{"$key"} = $val;
- }
- }
-}
-
-sub printconfig {
- print "graph_title Cache hit/miss ratio\n";
- print "graph_args --upper-limit 100 -l 0\n";
- print "graph_vlabel % of requests\n";
- print "graph_category varnish\n";
- print "graph_info This graph shows the ratio of requests found in the cache and not\n";
- print "graph_order hitratio missratio unknownratio\n";
- print "graph_scale no\n";
-
- print "hitratio.label hits\n";
- print "hitratio.type GAUGE\n";
- print "hitratio.graph yes\n";
- print "hitratio.min 0\n";
- print "hitratio.max 100\n";
- print "hitratio.draw AREA\n";
-
- print "missratio.label misses\n";
- print "missratio.type GAUGE\n";
- print "missratio.graph yes\n";
- print "missratio.min 0\n";
- print "missratio.max 100\n";
- print "missratio.draw STACK\n";
-
- print "unknownratio.label unknown\n";
- print "unknownratio.type GAUGE\n";
- print "unknownratio.graph yes\n";
- print "unknownratio.min 0\n";
- print "unknownratio.max 100\n";
- print "unknownratio.draw STACK\n";
-}
-
-sub findvalues {
- $nrequests = $stat{"client_requests_received"};
- $nhits = $stat{"cache_hits"};
- $nmisses = $stat{"cache_misses"};
-
- open(OVAL, $mydat);
- $tmpstr = <OVAL>;
- close(OVAL);
- chomp($tmpstr);
-
- ($orequests,$ohits,$omisses) = split(/ /, $tmpstr, 3);
-
- $hits = $nhits - $ohits;
- $requests = $nrequests - $orequests;
- $misses = $nmisses - $omisses;
-}
-
-sub printvalues {
- if ($requests > 0) {
- $hitratio = sprintf("%.2f", $hits / $requests * 100);
- $missratio = sprintf("%.2f", $misses / $requests * 100);
- } else {
- # Assume cache hit ratio = 100% if requests < 0
- $hitratio = sprintf("%.2f", 100);
- $missratio = sprintf("%.2f", 0);
- }
-
- if (($hitratio + $missratio) > 100) {
- # Rounding foo, hit+miss ratio is higher than 100
- $missratio = sprintf("%.2f", 100 - $hitratio);
- $unknownratio = sprintf("%.2f", 0);
- } else {
- # Unknown = rest, hit+miss ratio is upto or 100
- $unknownratio = sprintf("%.2f", 100 - ($hitratio + $missratio));
- }
-
- print "hitratio.value $hitratio\n";
- print "missratio.value $missratio\n";
- print "unknownratio.value $unknownratio\n";
- if ($mylog ne "") {
- open(LOG, ">>$mylog");
- print LOG "hitratio=$hitratio missratio=$missratio unknown=$unknownratio hits=$hits misses=$misses requests=$requests [" . time2str("%Y-%m-%d %H:%M:%S", time) . "]\n";
- close(LOG);
- }
-}
-
-sub writevalues {
- open(OVAL, ">$mydat");
- print OVAL "$nrequests $nhits $nmisses\n";
- close(OVAL);
-}
-
-if ($ARGV[0] eq "autoconf") {
- print "yes\n";
-} elsif ($ARGV[0] eq "config") {
- printconfig;
-} else {
- popstat;
- findvalues;
- printvalues;
- writevalues;
-}
+++ /dev/null
-#! /bin/sh
-# anders@aftenposten.no, 2007-05-07
-# Shows the rate of requests (per second) for Varnish
-
-PATH="$PATH:/usr/local/bin"
-export PATH
-
-pvstat() {
- # $1: vname $2: grabstat
- printf "$1.value "
- varnishstat -1 | egrep "$2" | awk '{print $1}'
-}
-
-case $1 in
-autoconf) echo yes;;
-config)
- echo 'graph_title Hitrate'
- echo 'graph_vlabel hits per second'
- echo 'graph_category varnish'
- echo 'graph_info This graph shows the rate of requests, hits per second'
-
- echo 'requests.label requests'
- echo 'requests.type COUNTER'
- echo 'requests.graph yes'
- ;;
-*)
- pvstat requests 'Client requests received$'
- ;;
-esac
--- /dev/null
+#!/usr/bin/perl -w
+#-
+# Copyright (c) 2007 Linpro AS
+# All rights reserved.
+#
+# Author: Dag-Erling Smørgrav <des@linpro.no>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+use strict;
+
+our %varnishstat;
+
+our %ASPECTS = (
+ 'ratio' => {
+ 'title' => 'Hit / miss ratio',
+ 'type' => 'percent',
+ 'values' => {
+ 'hit' => {
+ 'label' => 'hits',
+ 'numerator' => 'cache_hit',
+ 'denominator' => 'client_req',
+ },
+ 'miss' => {
+ 'label' => 'misses',
+ 'numerator' => 'cache_miss',
+ 'denominator' => 'client_req',
+ },
+ },
+ },
+);
+
+sub varnishstat($) {
+ my $field = shift;
+
+ die "no such field: $field\n"
+ unless defined($varnishstat{$field});
+ return $varnishstat{$field};
+}
+
+sub value($$) {
+ my $value = shift;
+ my $type = shift;
+
+ defined($value) || die "oops";
+ if ($type eq 'count') {
+ return varnishstat($value->{'field'});
+ } elsif ($type eq 'gauge') {
+ return varnishstat($value->{'field'});
+ } elsif ($type eq 'percent') {
+ return sprintf("%.1f", varnishstat($value->{'numerator'}) * 100.0 /
+ varnishstat($value->{'denominator'}));
+ } elsif ($type eq 'ratio') {
+ return sprintf("%.3f", varnishstat($value->{'numerator'}) /
+ varnishstat($value->{'denominator'}));
+ } else {
+ die "oops";
+ }
+}
+
+sub measure($) {
+ my $aspect = shift;
+
+ defined($aspect) || die "oops";
+ my @order = $aspect->{'order'} || sort(keys(%{$aspect->{'values'}}));
+ foreach (@order) {
+ print "$_.value ",
+ value($aspect->{'values'}->{$_}, $aspect->{'type'}),
+ "\n";
+ }
+}
+
+sub config($) {
+ my $aspect = shift;
+
+ defined($aspect) || die "oops";
+ print "graph_category Varnish\n";
+ print "graph_title $aspect->{'title'}\n";
+ if ($aspect->{'type'} eq 'percent') {
+ print "graph_scale no\n";
+ }
+ my @order = $aspect->{'order'} || sort(keys(%{$aspect->{'values'}}));
+ print "graph_order ", join(' ', @order), "\n";
+ foreach (@order) {
+ my $value = $aspect->{'values'}->{$_};
+ print "$_.label $value->{'label'}\n";
+ print "$_.graph yes\n";
+ if ($aspect->{'type'} eq 'count') {
+ print "$_.type COUNTER\n";
+ } elsif ($aspect->{'type'} eq 'gauge') {
+ print "$_.type GAUGE\n";
+ } elsif ($aspect->{'type'} eq 'percent') {
+ print "$_.type GAUGE\n";
+ print "$_.min 0\n";
+ print "$_.max 100\n";
+ if ($_ eq $order[0]) {
+ print "$_.draw AREA\n";
+ } else {
+ print "$_.draw STACK\n";
+ }
+ }
+ }
+}
+
+sub read_varnishstat($) {
+ my $name = shift;
+ my ($rh, $wh);
+ my $pid;
+
+ pipe($rh, $wh)
+ or die "pipe(): $!\n";
+ defined($pid = fork())
+ or die "fork(): $!\n";
+ if ($pid == 0) {
+ close($rh);
+ open(STDOUT, ">&", $wh);
+ exec "varnishstat", "-1", $name ? ("-n", $name) : ()
+ or die "exec(): $!\n";
+ die "not reachable\n";
+ }
+ close($wh);
+ while (<$rh>) {
+ if (m/^(\w+)\s+(\d+)\s+(\d*\.\d*)\s+(\w.*)$/) {
+ $varnishstat{$1} = $2;
+ $ASPECTS{$1} = {
+ 'title' => $4,
+ 'type' => ($3 eq ".") ? 'gauge' : 'count',
+ 'values' => {
+ $1 => {
+ 'label' => $1,
+ 'field' => $1,
+ }
+ }
+ };
+ }
+ }
+ close($rh);
+ waitpid($pid, 0)
+ or die "waitpid(): $!\n";
+ if ($? & 0x80) {
+ die "varnishstat received signal ", $? && 0x7f, "\n";
+ } elsif ($?) {
+ die "varnishstat returned exit code ", $? >> 8, "\n";
+ }
+}
+
+sub usage() {
+
+ print STDERR "usage: varnish_<aspect> [config]\n";
+ print STDERR "aspects: ", join(', ', sort keys %ASPECTS), "\n";
+ exit 1;
+}
+
+MAIN:{
+ read_varnishstat($ENV{'VARNISH_NAME'});
+
+ my $aspect;
+ ($aspect = $0) =~ s|^(?:.*/)varnish_(\w+)$|$1|;
+
+ # XXX bug in munin-node
+ shift @ARGV
+ if (@ARGV && $ARGV[0] eq '');
+
+ if (@ARGV == 0) {
+ defined($ASPECTS{$aspect})
+ or usage();
+ measure($ASPECTS{$aspect});
+ } elsif (@ARGV == 1) {
+ if ($ARGV[0] eq 'autoconf') {
+ print "yes\n";
+ } elsif ($ARGV[0] eq 'aspects') {
+ foreach (sort keys %ASPECTS) {
+ print "$_\n";
+ }
+ } elsif ($ARGV[0] eq 'config') {
+ defined($ASPECTS{$aspect})
+ or usage();
+ config($ASPECTS{$aspect});
+ } else {
+ usage();
+ }
+ } else {
+ usage();
+ }
+}
+++ /dev/null
-#!/usr/bin/perl
-use Net::Telnet ();
-use Data::Dumper;
-
-$arg = shift @ARGV;
-
-%aspects = (
- 'cache' => 'Cache',
- 'backend' => 'Backend',
- 'shm' => 'SHM'
- );
-
-(my $whut = $0) =~ s/^.*\_//;
-
-# Hvis $whut IKKE fins, men $arg fins OG er noe annet enn blabla
-# så skal den trigge
-
-if (!$whut && $arg && $arg !~ /^(suggest|autoconf)$/) {
- print "Only 'suggest' and 'autoconf' may be used w/o symlinked name\n";
- exit 2;
-} elsif (!$whut && !$arg) {
- print "Uh. Bugger.\n";
- exit 2;
-}
-
-if ($arg eq 'autoconf') {
- print "Autoconf starting...\n";
- exit 0;
-} elsif ($arg eq 'suggest') {
- print "Suggest starting...\n";
- exit 0;
-} elsif ($arg eq 'config') {
- $config = 1;
-}
-
-$grepfor = $aspects{$whut};
-# print "Looking for $grepfor\n";
-
-if ($config) {
- print "graph_title Varnish $grepfor usage\n";
- print "graph_args --base 1000\n";
- print "graph_vlabel Activity / \${graph_period}\n";
- print "graph_category Varnish\n";
-}
-
-$i = 0;
-foreach $line (`varnishstat -1`) {
- chomp $line;
- if ($line =~ /^\s+(\d+)\s+($grepfor.*)$/) {
- $val = $1;
- $key = $2;
- ($printkey = lc ($key)) =~ s/\s/_/g;
- if ($config) {
- print "$printkey\.label $key\n";
- print "$printkey\.type DERIVE\n";
- print "$printkey\.min 0\n";
- print "$printkey\.draw ";
- if ($i == 0) {
- print "AREA\n";
- } else {
- print "STACK\n";
- }
- $i++;
- } else {
- print "$printkey\.value $val\n";
- }
- }
-}
-
-exit;
-