| 1 |
ats |
1.1 |
#!/usr/bin/perl -w |
| 2 |
|
|
# i-scream central monitoring system |
| 3 |
|
|
# http://www.i-scream.org |
| 4 |
tdb |
1.3 |
# Copyright (C) 2000-2004 i-scream |
| 5 |
ats |
1.1 |
# |
| 6 |
|
|
# This program is free software; you can redistribute it and/or |
| 7 |
|
|
# modify it under the terms of the GNU General Public License |
| 8 |
|
|
# as published by the Free Software Foundation; either version 2 |
| 9 |
|
|
# of the License, or (at your option) any later version. |
| 10 |
|
|
# |
| 11 |
|
|
# This program is distributed in the hope that it will be useful, |
| 12 |
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 |
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 |
|
|
# GNU General Public License for more details. |
| 15 |
|
|
# |
| 16 |
|
|
# You should have received a copy of the GNU General Public License |
| 17 |
|
|
# along with this program; if not, write to the Free Software |
| 18 |
|
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 19 |
|
|
|
| 20 |
|
|
use strict; |
| 21 |
|
|
use Getopt::Long; |
| 22 |
|
|
|
| 23 |
|
|
my $progname = "statgrab-make-mrtg-config"; |
| 24 |
|
|
my $statgrab = "statgrab"; |
| 25 |
|
|
my $workdir = undef; |
| 26 |
|
|
|
| 27 |
|
|
my $kib = 1024; |
| 28 |
|
|
my $mib = $kib * $kib; |
| 29 |
|
|
|
| 30 |
ats |
1.2 |
# Type 0 is plain integers. |
| 31 |
|
|
my $KIBIBYTES = 1; |
| 32 |
|
|
my $PERCENT = 2; |
| 33 |
|
|
|
| 34 |
ats |
1.1 |
# Print an entry in the MRTG config file. |
| 35 |
|
|
sub entry ($$$$$$$$$$) { |
| 36 |
ats |
1.2 |
my ($title, $vali, $valo, $max, $ylegend, $yunit, $legendi, $legendo, $gauge, $type) = @_; |
| 37 |
ats |
1.1 |
my $name = $vali; |
| 38 |
|
|
my $options = ""; |
| 39 |
|
|
$options .= " noo" unless defined $valo; |
| 40 |
|
|
$options .= " gauge" if $gauge; |
| 41 |
ats |
1.2 |
my $sgoptions = ""; |
| 42 |
|
|
$sgoptions .= " -o -p" if $type == $PERCENT; |
| 43 |
ats |
1.1 |
|
| 44 |
|
|
print "\n"; |
| 45 |
|
|
print "Title[$name]: $title\n"; |
| 46 |
|
|
print "PageTop[$name]: $title\n"; |
| 47 |
|
|
print "MaxBytes[$name]: $max\n"; |
| 48 |
|
|
print "YLegend[$name]: $ylegend\n"; |
| 49 |
|
|
print "ShortLegend[$name]: $yunit\n"; |
| 50 |
|
|
print "LegendI[$name]: $legendi\n"; |
| 51 |
|
|
print "LegendO[$name]: $legendo\n" if defined $valo; |
| 52 |
ats |
1.2 |
if ($type == $KIBIBYTES) { |
| 53 |
ats |
1.1 |
print "kMG[$name]: Ki,Mi,Gi,Ti\n"; |
| 54 |
|
|
} |
| 55 |
|
|
$valo = "const.0" unless defined $valo; |
| 56 |
|
|
print "Options[$name]:$options\n" if $options ne ""; |
| 57 |
ats |
1.2 |
print "Target[$name]: `$statgrab$sgoptions -m $vali $valo`\n"; |
| 58 |
ats |
1.1 |
} |
| 59 |
|
|
|
| 60 |
|
|
my $package_version = '@PACKAGE_VERSION@'; |
| 61 |
|
|
my $package_bugreport = '@PACKAGE_BUGREPORT@'; |
| 62 |
|
|
my $help_text = <<EOF; |
| 63 |
|
|
Usage: $progname [OPTION]... |
| 64 |
|
|
Generate MRTG configuration from statgrab output and write it to stdout. |
| 65 |
|
|
|
| 66 |
|
|
--no-header Don't print MRTG global options; useful if you |
| 67 |
|
|
want to include the output of this script in |
| 68 |
|
|
another MRTG config file |
| 69 |
|
|
--workdir PATH Use PATH for MRTG's WorkDir option |
| 70 |
|
|
--statgrab PATH Specify location of statgrab binary |
| 71 |
|
|
(default "statgrab") |
| 72 |
|
|
--help Display this help and exit |
| 73 |
|
|
|
| 74 |
|
|
Version $package_version - report bugs to $package_bugreport. |
| 75 |
|
|
EOF |
| 76 |
|
|
|
| 77 |
|
|
sub fatal ($) { |
| 78 |
|
|
my ($message) = @_; |
| 79 |
|
|
die "$progname: $message\n"; |
| 80 |
|
|
} |
| 81 |
|
|
|
| 82 |
|
|
sub main () { |
| 83 |
|
|
GetOptions('statgrab=s' => \$statgrab, |
| 84 |
|
|
'workdir=s' => \$workdir, |
| 85 |
|
|
'no-header' => \my $no_header, |
| 86 |
|
|
'help' => \my $help) or die $help_text; |
| 87 |
|
|
if ($help) { |
| 88 |
|
|
print "$help_text"; |
| 89 |
|
|
exit 0; |
| 90 |
|
|
} |
| 91 |
|
|
|
| 92 |
|
|
unless ($no_header or defined $workdir) { |
| 93 |
|
|
fatal "must specify --workdir or --no-header" |
| 94 |
|
|
} |
| 95 |
|
|
|
| 96 |
|
|
my %stats = (); |
| 97 |
|
|
my %toplevel = (); |
| 98 |
|
|
my %disks = (); |
| 99 |
|
|
my %fss = (); |
| 100 |
|
|
my %nets = (); |
| 101 |
|
|
open STATGRAB, "$statgrab|" or fatal "can't run statgrab"; |
| 102 |
|
|
while (<STATGRAB>) { |
| 103 |
|
|
chomp; |
| 104 |
|
|
/^([^=]*) = (.*)$/ or fatal "bad line in statgrab output"; |
| 105 |
|
|
$stats{$1} = $2; |
| 106 |
|
|
|
| 107 |
|
|
my @parts = split /\./, $1; |
| 108 |
|
|
$toplevel{$parts[0]} = 1; |
| 109 |
|
|
$disks{$parts[1]} = 1 if $parts[0] eq "disk"; |
| 110 |
|
|
$fss{$parts[1]} = 1 if $parts[0] eq "fs"; |
| 111 |
|
|
$nets{$parts[1]} = 1 if $parts[0] eq "net"; |
| 112 |
|
|
} |
| 113 |
|
|
close STATGRAB; |
| 114 |
|
|
|
| 115 |
|
|
unless ($no_header) { |
| 116 |
|
|
print "WorkDir: $workdir\n"; |
| 117 |
|
|
print "Options[^]: growright\n"; |
| 118 |
|
|
print "WriteExpires: Yes\n"; |
| 119 |
|
|
} |
| 120 |
|
|
|
| 121 |
|
|
if (exists $toplevel{"cpu"}) { |
| 122 |
ats |
1.2 |
entry("CPU idle", "cpu.idle", undef, "100", "Idle", "%", "idle", undef, 1, $PERCENT); |
| 123 |
|
|
entry("CPU iowait", "cpu.iowait", undef, "100", "iowait", "%", "iowait", undef, 1, $PERCENT); |
| 124 |
|
|
entry("CPU kernel", "cpu.kernel", undef, "100", "Kernel", "%", "kernel", undef, 1, $PERCENT); |
| 125 |
|
|
entry("CPU nice", "cpu.nice", undef, "100", "Nice", "%", "nice", undef, 1, $PERCENT); |
| 126 |
|
|
entry("CPU swap", "cpu.swap", undef, "100", "Swap", "%", "swap", undef, 1, $PERCENT); |
| 127 |
|
|
entry("CPU user", "cpu.user", undef, "100", "User", "%", "user", undef, 1, $PERCENT); |
| 128 |
ats |
1.1 |
} |
| 129 |
|
|
|
| 130 |
|
|
foreach my $disk (sort keys %disks) { |
| 131 |
|
|
my $name = $stats{"disk.$disk.disk_name"}; |
| 132 |
|
|
entry("Disk $name IO", "disk.$disk.read_bytes", "disk.$disk.write_bytes", 100*$mib, "IO rate", "B/s", "read", "write", 0, 0); |
| 133 |
|
|
} |
| 134 |
|
|
|
| 135 |
|
|
foreach my $fs (sort keys %fss) { |
| 136 |
|
|
my $name = $stats{"fs.$fs.mnt_point"}; |
| 137 |
|
|
my $size = $stats{"fs.$fs.size"}; |
| 138 |
|
|
my $inodes = $stats{"fs.$fs.total_inodes"}; |
| 139 |
|
|
entry("Filesystem $name space usage", "fs.$fs.used", undef, $size, "Space used", "B", "used", undef, 1, 0); |
| 140 |
|
|
entry("Filesystem $name inode usage", "fs.$fs.used_inodes", undef, $inodes, "Inodes used", "inodes", "used", undef, 1, 0); |
| 141 |
|
|
} |
| 142 |
|
|
|
| 143 |
|
|
if (exists $toplevel{"load"}) { |
| 144 |
|
|
entry("Load average over 1 minute", "load.min1", undef, 100, "Load average", "running", "load", undef, 1, 0); |
| 145 |
|
|
entry("Load average over 5 minutes", "load.min5", undef, 100, "Load average", "running", "load", undef, 1, 0); |
| 146 |
|
|
entry("Load average over 15 minutes", "load.min15", undef, 100, "Load average", "running", "load", undef, 1, 0); |
| 147 |
|
|
} |
| 148 |
|
|
|
| 149 |
|
|
if (exists $toplevel{"mem"}) { |
| 150 |
|
|
my $total = $stats{"mem.total"}; |
| 151 |
|
|
entry("Memory usage", "mem.used", "mem.cache", $total, "Memory usage", "B", "total", "cache", 1, 0); |
| 152 |
|
|
} |
| 153 |
|
|
|
| 154 |
|
|
foreach my $net (sort keys %nets) { |
| 155 |
|
|
my $name = $stats{"net.$net.interface_name"}; |
| 156 |
|
|
# FIXME should be able to discover interface speed |
| 157 |
|
|
entry("Network interface $name IO", "net.$net.rx", "net.$net.tx", 100*$mib, "Network IO", "B", "rx", "tx", 0, 0); |
| 158 |
|
|
} |
| 159 |
|
|
|
| 160 |
|
|
if (exists $toplevel{"page"}) { |
| 161 |
|
|
# FIXME what's a sensible maximum? |
| 162 |
|
|
entry("Paging IO", "page.in", "page.out", 1000, "Paging IO", "pages", "in", "out", 0, 0); |
| 163 |
|
|
} |
| 164 |
|
|
|
| 165 |
|
|
if (exists $toplevel{"proc"}) { |
| 166 |
|
|
# FIXME mildly silly assumption |
| 167 |
|
|
my $maxproc = 65536; |
| 168 |
|
|
entry("Processes running", "proc.running", undef, $maxproc, "Running", "procs", "running", undef, 1, 0); |
| 169 |
|
|
entry("Processes sleeping", "proc.sleeping", undef, $maxproc, "Sleeping", "procs", "running", undef, 1, 0); |
| 170 |
|
|
entry("Processes stopped", "proc.stopped", undef, $maxproc, "Stopped", "procs", "running", undef, 1, 0); |
| 171 |
|
|
entry("Processes", "proc.total", undef, $maxproc, "Total", "procs", "running", undef, 1, 0); |
| 172 |
|
|
entry("Processes zombie", "proc.zombie", undef, $maxproc, "Zombie", "procs", "running", undef, 1, 0); |
| 173 |
|
|
} |
| 174 |
|
|
|
| 175 |
|
|
if (exists $toplevel{"swap"}) { |
| 176 |
|
|
my $swapsize = $stats{"swap.total"}; |
| 177 |
|
|
entry("Swap usage", "swap.used", undef, $swapsize, "Swap usage", "B", "used", undef, 1, 0); |
| 178 |
|
|
} |
| 179 |
|
|
|
| 180 |
|
|
if (exists $toplevel{"user"}) { |
| 181 |
|
|
entry("Users", "user.num", undef, 1000, "Users", "users", "users", undef, 1, 0); |
| 182 |
|
|
} |
| 183 |
|
|
} |
| 184 |
|
|
|
| 185 |
|
|
main(); |