#!/usr/bin/perl
# -*- perl -*-
# Jean-Samuel Reynaud <js.reynaud@free.fr>
# Based on postgres_locks
#
# Wildcard-plugin to monitor slony latency. To monitor a
# slony cluster, link slony_<cluster_schema> to this file. E.g.
#
#    ln -s /usr/share/munin/node/plugins-auto/slony_ /etc/munin/node.d/slony__my_cluster
#
# ...will monitor my_cluster's slony cluster
#
# Show slony latency
#
# Parameters:
#
# 	config
# 	autoconf
#
#
#
# Configuration variables:
#
#	PGHOST		- Database server to use. Defaults to using ident
#			  authentication with the local server.
#	PGPORT		- Port to connect to. Defaults to '5432'.
#	PGDATABASE	- Database to connect to. Defaults to 'template1'.
#	PGUSER		- User to connect as, if necessary.
#	PGPASSWORD	- Corresponding password to use, if necessary.
#
#	(See libpq documentation for more.)
#	Note that PGDATABASE will default to 'template1' in this plugin, and
#	without PGHOST it will try ident authentication with the local server,
#	as the user that the plugin is running as.
#
# Configuration example:
#
#	# Use local server, ident authentication with the 'postgres' user.
#	[slony_*]
#	user postgres
#
#	# Use local server, TCP authentication with a username and password.
#	[slony_*]
#	env.PGHOST localhost
#	env.PGUSER someuser
#	env.PGDATABASE somedb
#	env.PGPASSWORD somepassword
#
# Magic markers
#%# family=auto
#%# capabilities=

use strict;
use warnings;
use DBI;


my $cluster = $0;
$cluster =~ s/^.*slony_([\w\d\._\-]*)$/$1/;

# Default to template1 database.
$ENV{'PGDATABASE'} ||= 'template1';


my $dbh = DBI->connect ('dbi:Pg:', '', '', {RaiseError =>1})
    || die "Unable to access database.\nError returned was: ". $DBI::errstr;

if ($ARGV[0] && $ARGV[0] eq "config") {
    print <<EOF;
graph_title Slony latency
graph_args --base 1000
graph_vlabel Latency in seconds
graph_category PostgreSQL
graph_info Shows Slony latency
EOF
my $sql="select no_id,no_comment,pa_conninfo from $cluster.sl_node join $cluster.sl_path on (pa_server=no_id) where pa_client= $cluster.getlocalnodeid('$cluster'::name);";
    my $sth = $dbh->prepare ($sql);
    $sth->execute ();
    my $locks = 0;
    my $exlocks = 0;
    while (my ($no_id,$comment, $conninfo) = $sth->fetchrow ()) {
        $conninfo =~ s/.*host=([\w\d\._\-]*)\s.*/$1/;
        $no_id = sprintf("slave_%u",$no_id);
print<<EOF
$no_id.label $conninfo
$no_id.info $comment
$no_id.type GAUGE
$no_id.warning 60
$no_id.critical 1800
$no_id.min 0
EOF
}
} else {

    my $sql="select st_received,st_lag_num_events,EXTRACT(EPOCH FROM st_lag_time)::integer from $cluster.sl_status;";
    my $sth = $dbh->prepare ($sql);
    $sth->execute ();
    my $locks = 0;
    my $exlocks = 0;
    while (my ($no_id,$nb_event, $lag) = $sth->fetchrow ()) {
        $no_id = sprintf("slave_%u",$no_id);
        print "$no_id.value $lag\n"
    }
}
