- Repository
- Munin (2.0)
- Last change
- 2020-05-27
- Graph Categories
- Family
- contrib
- Capabilities
- Language
- Perl
- License
- GPL-2.0-only
mysql_isam_space_
Name
mysql_isam_space_ - Wildcard plugin to monitor the percent of table space used on isam and myisam tables on a mysql server.
Configuration
Configuration parameters for @@CONFDIR@@/PLUGIN, if you need to override the defaults below:
[mysql_isam_space_*]
env.mysqlopts - Options to pass to mysql
env.statefile - where to put the statefile
env.ignore - Tables to ignore. Regex.
env.absolute - use tables sizes, not percent of maximum
Default Configuration
[mysql_isam_space_*]
env.mysqlopts
env.statefile $ENV{MUNIN_PLUGSTATE}/plugin-mysql_isam_space.state
env.ignore
env.absolute 0
Author
Unknown author
License
GPLv2
Magic Markers
#%# family=contrib
#%# capabilities=suggest autoconf
#!@@PERL@@ -w
# -*- perl -*-
=head1 NAME
mysql_isam_space_ - Wildcard plugin to monitor the percent of table space used
on isam and myisam tables on a mysql server.
=head1 CONFIGURATION
Configuration parameters for @@CONFDIR@@/PLUGIN,
if you need to override the defaults below:
[mysql_isam_space_*]
env.mysqlopts - Options to pass to mysql
env.statefile - where to put the statefile
env.ignore - Tables to ignore. Regex.
env.absolute - use tables sizes, not percent of maximum
=head2 DEFAULT CONFIGURATION
[mysql_isam_space_*]
env.mysqlopts
env.statefile $ENV{MUNIN_PLUGSTATE}/plugin-mysql_isam_space.state
env.ignore
env.absolute 0
=head1 AUTHOR
Unknown author
=head1 LICENSE
GPLv2
=head1 MAGIC MARKERS
=begin comment
These magic markers are used by munin-node-configure when installing
munin-node.
=end comment
#%# family=contrib
#%# capabilities=suggest autoconf
=cut
my $DB = `basename $0 | sed 's/^mysql_isam_space_//g' | tr '_' '-'` ;
chomp $DB;
my $STATEFILE = $ENV{'statefile'} || "$ENV{MUNIN_PLUGSTATE}/plugin-mysql_isam_space.state";
my $MYSQLSHOW = $ENV{'mysqlshow'} || `command -v mysqlshow`;
my $ABSOLUTE = $ENV{'absolute'} || 0;
my @mysql_opts = ();
chomp $MYSQLSHOW;
if (exists $ENV{'mysqlopts'})
{
@mysql_opts = split /\s+/, $ENV{'mysqlopts'};
}
my $tables = undef;
my $databases = undef;
&print_autoconf () if ($ARGV[0] and $ARGV[0] eq "autoconf");
if (&use_statefile)
{
($databases, $tables) = &read_statefile;
}
else
{
($databases, $tables) = &fetch_state_from_mysql;
}
&print_config ($tables) if ($ARGV[0] and $ARGV[0] eq "config");
&print_suggest ($databases, $tables) if ($ARGV[0] and $ARGV[0] eq "suggest");
foreach my $t (keys %{$tables})
{
printf ("%s.%s %f\n", $t, "value ", $tables->{$t});
}
sub print_config
{
my $tables = shift;
print "graph_title MySQL \"$DB\" isam/myisam table-space usage\n";
print "graph_args --base 1000\n";
print "graph_vlabel percent\n";
print "graph_category mysql\n";
foreach my $t (keys %{$tables})
{
my $label = $t;
if (length ($t) >= 20)
{
$label = sprintf ("...%17s", substr ($t, -17));
}
print $t, ".label $label\n";
print $t, ".warning 0:90\n";
print $t, ".critical 0:95\n";
}
exit 0;
}
sub read_statefile
{
my $tables = shift;
my $databases = undef;
# Read the statefile
open (IN, $STATEFILE) or die "Could not open \"$STATEFILE\" for reading: $!";
while (<IN>)
{
tr/���/eoa/;
if (/^$DB\.([^\s]+)\s+([\d\.]+)\s*$/)
{
$tables->{$1} = $2;
}
if (/^([^\.]+)\./)
{
if (! grep (/^$1$/, @{$databases}))
{
push (@{$databases}, $1);
}
}
}
close (IN);
return ($databases, $tables);
}
sub use_statefile
{
if (-f $STATEFILE)
{
if ((stat ($STATEFILE))[9] > (time - 3600))
{
return 1;
}
}
return 0;
}
sub fetch_state_from_mysql
{
my $tables = shift;
my $databases = ();
# Fork off mysqlshow
my $pid = open (IN, '-|');
if (! defined ($pid))
{ # Fork fail
die "Couldn't fork.";
}
elsif ($pid == 0)
{ # Child
exec ($MYSQLSHOW, @mysql_opts, "--status", "-v");
}
my @mysql_status = <IN>;
close (IN);
if ($? != 0)
{
exit 1;
}
foreach $line (@mysql_status)
{
$line =~ tr/���/eoa/;
if ($line =~ /^\|\s+([^\|\s]+)\s+\|\s+([^\|\s]+)\s+\|/)
{
next if ($1 eq "Databases");
next if ($2 eq "N/A");
if ($2 > 0)
{
push (@{$databases}, $1)
}
}
}
if ((! -e $STATEFILE) or (-f $STATEFILE))
{
&makedirfor ($STATEFILE);
open (OUT, ">$STATEFILE") or die "Could not open \"$STATEFILE\" for writing: $!";
}
else
{
die "Outfile exists and isn't a \"file\".";
}
foreach my $db (@{$databases})
{
# Fork off mysqlshow
my $pid = open (IN, '-|');
if (! defined ($pid))
{ # Fork fail
die "Couldn't fork.";
}
elsif ($pid == 0)
{ # Child
exec ($MYSQLSHOW, @mysql_opts, "--status", "-v", $db);
# Notreached.
}
my %index;
my $headerseen;
while (<IN>)
{
my @fields = split (/\s*\|\s*/);
next if @fields < 2; # Separator line
if (! $headerseen and $fields[1] eq "Name")
{ # Header line, grab field names
%index = map {($fields[$_], $_)} 0..$#fields;
}
else
{
# mysqlshow says many fun things sometimes, sanity-check
next if $fields[$index{Data_length}] eq "";
next if ($fields[$index{Max_data_length}] eq "") && ( ! $ABSOLUTE );
next if ($fields[$index{Max_data_length}] == 0) && ( ! $ABSOLUTE );
my $value =
$ABSOLUTE ? $fields[$index{Data_length}]
: (100*$fields[$index{Data_length}]/$fields[$index{Max_data_length}]);
printf OUT ("%s.%s %f\n", $db, $fields[1], $value);
$tables->{$fields[1]} = $value if $DB eq $db;
}
}
close (IN);
}
close (OUT);
return ($databases, $tables);
}
sub makedirfor
{
my $filename = shift;
(my $dir = $filename) =~ s/\/[^\/]+$//;
if ($dir ne $filename and ! -d $dir)
{
&makedirfor ($dir);
mkdir ($dir, 0700);
}
return $dir;
}
sub print_suggest
{
my ($databases, $tables) = @_;
foreach my $db (@{$databases})
{
print "$db\n";
}
exit 0;
}
sub print_autoconf
{
# First check that mysqlshow exists...
if (! -x $MYSQLSHOW)
{
print "no (mysqlshow not found)\n";
exit 0;
}
# Fork off mysqlshow
my $pid = open (IN, '-|');
if (! defined ($pid))
{ # Fork fail
die "Couldn't fork.";
}
elsif ($pid == 0)
{ # Child
close STDERR;
open (STDERR, ">&STDOUT");
exec ($MYSQLSHOW, @mysql_opts, "--status", "-v");
}
my @slurp = <IN>;
close (IN);
if ($? == 0)
{
print "yes\n";
exit 0;
}
elsif (grep (/Can't connect to local MySQL server/, @slurp))
{
print "no (could not connect to mysql)\n";
}
else
{
print "no\n";
}
exit 0;
}
# vim:syntax=perl