perl

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

Operating perl applications as a non perl programmer

I’ve used

cpanm --installdeps .

To install all perl module dependencies for a perl application we’re running, when trying to deploy the same app on other servers the application doesn’t work, even though I’m using the same version of perl and following the same steps for installing perl modules. (sigh)
I’m suspecting there could be some problem with newer versions of perl modules ’cause the perl code itself is rsync’ed from the working server .
Here’s how you could create an autobundle package in perl, and use cpan to install the same modules in an other environment / server .

# on the working server:
perl -MCPAN -eautobundle
Wrote bundle file
    /path/to/cpan/.cpan/Bundle/Snapshot_2012_10_04_01.pm

Now copy the […].cpan/Bundle/Snapshot_2012_10_04_01.pm to the new server / instance, put it in […].cpan/Bundle/ and issue

perl -MCPAN -e 'install Bundle::Snapshot_2012_10_04_01'

Notice: leaving out the .pm file extension when referring to the Snapshot .
Oh, and by the way
How do I list all installed perl modules ? :

cpan -l

That’s not really intuitive when you’re not a perl programmer, I’ve always started up cpan in interactive mode, haven’t figured out that one before.
Also try:

perldoc -q installed

While you’re at it, it mentions cpan -a as well, which makes that Snapshot file .
Thank you gugod.org