Minor munin-node hack

We’ve got a Postgres sql server running 9.1beta3 , and I’m currently setting up some Munin graphs for that server. I ran into an annoying error when I wanted to test one of the postgres_* plugins

# munin-run postgres_bgwriter
Unable to detect PostgreSQL version

It kind of put me off, since I’d already setup those plugins on 4 other servers running postgres …
Google gave me an url for the source code for the munin Pgsql plugin, which is written in Perl . The corresponding plugin on this FreeBSD installation was in :
/usr/local/lib/perl5/site_perl/5.12.4/Munin/Plugin/Pgsql.pm , so I had look at the code there. And it turned out to be this function that spat out my error:

sub get_version {
    my ($self) = @_;

    return if (defined $self->{detected_version});

    my $r = $self->runquery("SELECT version()");
    my $v = $r->[0]->[0];
    die "Unable to detect PostgreSQL version\n"
        unless ($v =~ /^PostgreSQL (\d+)\.(\d+).(\d+) on/);
    $self->{detected_version} = "$1.$2";
}

So the code says that print out “Unable to detect PostgreSQL version\n” unless the query “SELECT version()” returns a string similar to the regula expression /^PostgreSQL (\d+)\.(\d+).(\d+) on/ …
I ran the query on the servers where these plugins worked ok, and compared to the troublesome server.
Working server

=# select version();
                                                     version                                                      
------------------------------------------------------------------------------------------------------------------
 PostgreSQL 8.4.15 on amd64-portbld-freebsd

Non-working server:

select version();
                                                 version                                                 
---------------------------------------------------------------------------------------------------------
 PostgreSQL 9.1beta3 on amd64-portbld-freebsd

Looking at the regular expression /^PostgreSQL (\d+)\.(\d+).(\d+) on/, translated it means something like a string starting with “PostgreSQL [whitespace] [one or more digits] [a period] [one or more digits] [a period] [one or more digits [whitespace] on” This matches the working server which has the string PostgreSQL 8.4.15 on, but the 9.1beta3 doesn’t match (\d+)\.(\d+).(\d+) ! .
Upgrading the Postgres server to 9.1.[something not beta] is out of the question for the moment so I tried to make the regular expression true by changing /^PostgreSQL (\d+)\.(\d+).(\d+) on/ to /^PostgreSQL (\d+)\.(\d+)beta(\d+) on/ , the whole function ended up like this:

sub get_version {
    my ($self) = @_;

    return if (defined $self->{detected_version});

    my $r = $self->runquery("SELECT version()");
    my $v = $r->[0]->[0];
    die "Unable to detect PostgreSQL version\n"
        unless ($v =~ /^PostgreSQL (\d+)\.(\d+)beta(\d+) on/);
    $self->{detected_version} = "$1.$2";
}

And it seem to have been enough to get those munin-node postgres_* plugins working again:

# munin-run postgres_bgwriter
buffers_checkpoint.value 4514399
buffers_clean.value 10922461
buffers_backend.value 63381760
buffers_alloc.value 72530920829

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>