#!/usr/bin/perl -w
###############################################################################
# Webmin Sysstats - mysql.pl
#
# Webmin Sysstats Module
# Copyright (C) 2003 by Eric Gerbier
# Bug reports to: gerbier@users.sourceforge.net
# $Id$
#
# 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; either version 2 of the License, or
# (at your option) any later version.
#
# 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.
#
###############################################################################
use strict;
use warnings;
use RRDs;
use English qw(-no_match_vars);
use FindBin;
# to be used alone or from sysstat.pl without warning
# because require verify the path
if ( !exists $ENV{WEBMINSTAT_TEMP} ) {
use lib "$FindBin::Bin/../..";
## no critic (RequireBarewordIncludes)
require 'sysstats-aquisition-lib.pl';
## use critic;
}
###############################################################################
# use mysqladmin tool
sub get_admin_server_status($) {
my $my_config = $_[0];
my $cmd = $my_config->{'mysqladmin'};
# add user and password if exists
if ( exists $my_config->{'user'} ) {
$cmd .= ' --user=' . $my_config->{'user'};
}
if ( $my_config->{'password'} ) {
# quotemeta is used to escape special char in password
$cmd .= ' --password=' . quotemeta $my_config->{'password'};
}
if ( $my_config->{'port'} ) {
$cmd .= ' --port=' . $my_config->{'port'};
}
if ( $my_config->{'host'} ) {
$cmd .= ' --host=' . $my_config->{'host'};
}
$cmd .= ' extended-status';
my %params;
# format :
# +--------------------------------+---------+
# | Variable_name | Value |
# +--------------------------------+---------+
# | Uptime | 184314 |
# +--------------------------------+---------+
my $r_tab = read_pipe($cmd);
foreach ( @{$r_tab} ) {
if (m/Variable_name/) {
# title
next;
}
elsif (m/\s(\S+)\s+.\s(\w+)/) {
my $name = $1;
my $value = $2;
#debug("name=$name value=$value");
$params{$name} = $value;
}
}
return \%params;
}
###############################################################################
# use DBI module
# be careful : on some hosts (BSD), some data are different from a "show status"
# (the number is very different)
sub get_dbi_server_status($) {
my $server = shift;
$server->{port} = 3306 unless ( exists $server->{port} );
my $dbh = DBI->connect( "dbi:mysql::$server->{host}:$server->{port}",
$server->{user}, $server->{password},
{ PrintError => 0, RaiseError => 0 } );
if ($dbh) {
my $q = $dbh->prepare('SHOW STATUS');
$q->execute() or return;
my %result;
for ( 0 .. $q->rows ) {
my ( $var_name, $value ) = $q->fetchrow_array;
if ( defined $value ) {
$result{$var_name} = $value;
}
}
$q->finish();
$q = undef;
$dbh->disconnect();
$dbh = undef;
return \%result;
}
else {
unset_warnings();
## no critic (ProhibitNoWarnings)
no warnings 'once';
## use critic;
warning(
"Can not connect to $server->{user}\@$server->{host} ($DBI::errstr)"
);
set_warnings();
use warnings 'all';
return;
}
}
###############################################################################
my %config;
read_file_cached( 'config', \%config );
my %codes = action_load( \%config );
my $pre = $config{'pre'};
my $vol_num = 1;
my $result;
if ( $config{'mysqladmin'} ) {
$result = get_admin_server_status( \%config );
}
else {
eval { require DBI };
if ($EVAL_ERROR) {
warning("perl module DBI not found : $EVAL_ERROR");
goto FIN;
}
else {
$result = get_dbi_server_status( \%config );
}
}
if ( !defined $result ) {
warning('no data from mysql server');
goto FIN;
}
while ( exists $config{ $pre . $vol_num } ) {
my @tab = split /,/, $config{ $pre . $vol_num };
my $real_vol_num = $tab[0];
my $vol = $tab[1];
my $runstop = $tab[3];
#debug( "volume = $vol");
my $total = 'U';
if ( is_param_runstop($runstop) ) {
if ( exists $result->{$vol} ) {
$total = $result->{$vol};
}
else {
warning("can not find $vol in mysql status");
}
debug("mysql $vol ($real_vol_num) : total=$total");
action_param( $vol, $total, \%codes );
}
else {
debug("aquisition for $vol stopped");
}
my $rrdbase = $real_vol_num . '.rrd';
RRDs::update( $rrdbase, "N:$total" );
my $ERR = RRDs::error();
warning("mysql : ERROR while updating $rrdbase: $ERR") if $ERR;
$vol_num++;
}
# a label to quit
#I can not use return when executing this script standalone,
# so I had to use goto
FIN: