ossp-pkg/snmpdx/snmpdx.d/sysVM.pm
1.6
##
## snmpdx -- SNMP Daemon Extension
## Copyright (c) 2003 The OSSP Project <http://www.ossp.org/>
## Copyright (c) 2003 Ralf S. Engelschall <rse@engelschall.com>
## Copyright (c) 2003 Cable & Wireless <http://www.cw.com/>
##
## Permission to use, copy, modify, and distribute this software for
## any purpose with or without fee is hereby granted, provided that
## the above copyright notice and this permission notice appear in all
## copies.
##
## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
## SUCH DAMAGE.
##
## sysVM: System Virtual Memory
##
package My::Probe::sysVM;
our @ISA = qw(My::Probe);
sub oids ($) {
my ($self) = @_;
return $self->{-ctx}->{-mib}->oids("*.snmpdx.host.system.sysVM.*");
}
sub probe ($$) {
my ($self, $obj) = @_;
if ($self->{-ctx}->{-platform}->id() =~ m/FreeBSD/i) {
# sysVMRamMax "/sbin/sysctl -n hw.physmem", convert bytes to MB
# sysVMRamUsed sysVMRamMax - sysVMRamFree
# sysVMRamFree "/usr/bin/vmstat", avm, convert KB to MB
#
if ($obj->{-name} =~ m/\.sysVMRam(Max|Used|Free)$/) {
my $sysVMRamMax = undef;
my $sysVMRamUsed = undef;
my $sysVMRamFree = undef;
# local workspace
my $out; my $raw; my $n2i; my @dat;
# sysVMRamMax
$out = $self->{-ctx}->{-sys}->run("/sbin/sysctl -n hw.physmem", "forever");
$raw = $out->{-stdout};
if ($raw =~ m/^(\d+)$/) {
$sysVMRamMax = int($1 / 1024 / 1024);
}
# sysVMRamFree
$out = $self->{-ctx}->{-sys}->run("/usr/bin/vmstat", "1m");
$raw = $out->{-stdout};
$n2i = {};
if ($raw =~ m/^[^\n]*\n *([^\n]*\bavm\b[^\n]*)\n *([^\n]*)\n$/s) {
$n2i = &mkn2i(split / +/, $1);
}
if (defined $n2i->{avm}) {
@dat = split(/ +/, $2);
$sysVMRamFree = int(@dat[$n2i->{avm}] / 1024);
}
# sysVMRamUsed
if (defined $sysVMRamMax and defined $sysVMRamFree) {
$sysVMRamUsed = $sysVMRamMax - $sysVMRamFree;
}
$obj->{-value} = $sysVMRamMax if ($obj->{-name} =~ m/\.sysVMRamMax$/);
$obj->{-value} = $sysVMRamUsed if ($obj->{-name} =~ m/\.sysVMRamUsed$/);
$obj->{-value} = $sysVMRamFree if ($obj->{-name} =~ m/\.sysVMRamFree$/);
}
# sysVMSwapMax "/usr/sbin/swapinfo -k", 1K-blocks, last line, convert KB to MB
# sysVMSwapUsed "/usr/sbin/swapinfo -k", Used, last line, convert KB to MB
# sysVMSwapFree sysVMSwapMax - sysVMSwapUsed
#
if ($obj->{-name} =~ m/\.sysVMSwap(Max|Used|Free)$/) {
my $sysVMSwapMax = undef;
my $sysVMSwapUsed = undef;
my $sysVMSwapFree = undef;
# local workspace
my $out; my $raw; my $n2i; my @dat;
# sysVMSwapMax, sysVMSwapUsed
$out = $self->{-ctx}->{-sys}->run("/usr/sbin/swapinfo -k", "1m");
$raw = $out->{-stdout};
$n2i = {};
if ($raw =~ m/^\s*([^\n]*\b1K-blocks[^\n]*\bUsed[^\n]*).*\n([^\n]+)$/s) {
$n2i = &mkn2i(split / +/, $1);
}
@dat = split(/ +/, $2);
if (defined $n2i->{_1K_blocks}) {
$sysVMSwapMax = int(@dat[$n2i->{_1K_blocks}] / 1024)
}
if (defined $n2i->{Used}) {
$sysVMSwapUsed = int(@dat[$n2i->{Used}] / 1024)
}
# sysVMSwapFree
if (defined $sysVMSwapMax and defined $sysVMSwapUsed) {
$sysVMSwapFree = $sysVMSwapMax - $sysVMSwapUsed;
}
$obj->{-value} = $sysVMSwapMax if ($obj->{-name} =~ m/\.sysVMSwapMax$/);
$obj->{-value} = $sysVMSwapUsed if ($obj->{-name} =~ m/\.sysVMSwapUsed$/);
$obj->{-value} = $sysVMSwapFree if ($obj->{-name} =~ m/\.sysVMSwapFree$/);
}
# sysVMActivity "/usr/bin/vmstat", add pi and po column
#
if ($obj->{-name} =~ m/\.sysVMActivity$/) {
my $sysVMActivity = undef;
# local workspace
my $out; my $raw; my $n2i; my @dat;
$out = $self->{-ctx}->{-sys}->run("/usr/bin/vmstat", "1m");
$raw = $out->{-stdout};
$n2i = {};
if ($raw =~ m/^[^\n]*\n *([^\n]*(\bp[io]\b[^\n]*){2})\n *([^\n]*)\n$/s) {
$n2i = &mkn2i(split / +/, $1);
}
if (defined $n2i->{pi} and defined $n2i->{po}) {
@dat = split(/ +/, $3);
$sysVMActivity = @dat[$n2i->{pi}] + @dat[$n2i->{po}];
}
$obj->{-value} = $sysVMActivity;
}
}
elsif ($self->{-ctx}->{-platform}->id() =~ m/Linux/i) {
# sysVMRamMax "/bin/cat /proc/meminfo", MemTotal, convert KB to MB
# sysVMRamUsed "/bin/cat /proc/meminfo", MemTotal-Buffers-Cached-MemFree, convert KB to MB
# sysVMRamFree sysVMRamMax - sysVMRamUsed
#
# FIXME sysVMRamMax does not include the kernel and some of its structures so
# FIXME it is not pyhsical RAM, see dmesg | egrep '^Memory:'
# FIXME /bin/cat is used here but could be replaced by native perl code to improve performance
#
if ($obj->{-name} =~ m/\.sysVMRam(Max|Used|Free)$/) {
my $sysVMRamMax = undef;
my $sysVMRamUsed = undef;
my $sysVMRamFree = undef;
# local workspace
my $out; my $raw; my $n2i; my @dat; my $tmp;
# sysVMRamMax, sysVMRamUsed
$out = $self->{-ctx}->{-sys}->run("/bin/cat /proc/meminfo", "1m");
$raw = $out->{-stdout};
$tmp = {};
$tmp->{MemTotal} = $1 if ($raw =~ m/\nMemTotal:[^\n]*\b(\d+)\b[^\n]*kB\n/s);
$tmp->{Buffers} = $1 if ($raw =~ m/\nBuffers:[^\n]*\b(\d+)\b[^\n]*kB\n/s);
$tmp->{Cached} = $1 if ($raw =~ m/\nCached:[^\n]*\b(\d+)\b[^\n]*kB\n/s);
$tmp->{MemFree} = $1 if ($raw =~ m/\nMemFree:[^\n]*\b(\d+)\b[^\n]*kB\n/s);
if (defined $tmp->{MemTotal}) {
$sysVMRamMax = int($tmp->{MemTotal} / 1024);
}
if ( defined $tmp->{MemTotal}
and defined $tmp->{Buffers}
and defined $tmp->{Cached}
and defined $tmp->{MemFree}
) {
$sysVMRamUsed = int (( $tmp->{MemTotal}
- $tmp->{Buffers}
- $tmp->{Cached}
- $tmp->{MemFree}
) / 1024 );
}
# sysVMRamFree
if (defined $sysVMRamMax and defined $sysVMRamUsed) {
$sysVMRamFree = $sysVMRamMax - $sysVMRamUsed;
}
$obj->{-value} = $sysVMRamMax if ($obj->{-name} =~ m/\.sysVMRamMax$/);
$obj->{-value} = $sysVMRamUsed if ($obj->{-name} =~ m/\.sysVMRamUsed$/);
$obj->{-value} = $sysVMRamFree if ($obj->{-name} =~ m/\.sysVMRamFree$/);
}
# sysVMSwapMax "/bin/cat /proc/meminfo", SwapTotal, convert KB to MB
# sysVMSwapUsed sysVMSwapMax - sysVMSwapFree
# sysVMSwapFree "/bin/cat /proc/meminfo", SwapFree, convert KB to MB
#
if ($obj->{-name} =~ m/\.sysVMSwap(Max|Used|Free)$/) {
my $sysVMSwapMax = undef;
my $sysVMSwapUsed = undef;
my $sysVMSwapFree = undef;
# local workspace
my $out; my $raw; my $n2i; my @dat;
# sysVMSwapMax, sysVMSwapFree
$out = $self->{-ctx}->{-sys}->run("/bin/cat /proc/meminfo", "1m");
$raw = $out->{-stdout};
if ($raw =~ m/\nSwapTotal:[^\n]*\b(\d+)\b[^\n]*kB\n/s) {
$sysVMSwapMax = int($1 / 1024);
}
if ($raw =~ m/\nSwapFree:[^\n]*\b(\d+)\b[^\n]*kB\n/s) {
$sysVMSwapFree = int($1 / 1024);
}
# sysVMSwapUsed
if (defined $sysVMSwapMax and defined $sysVMSwapFree) {
$sysVMSwapUsed = $sysVMSwapMax - $sysVMSwapFree;
}
$obj->{-value} = $sysVMSwapMax if ($obj->{-name} =~ m/\.sysVMSwapMax$/);
$obj->{-value} = $sysVMSwapUsed if ($obj->{-name} =~ m/\.sysVMSwapUsed$/);
$obj->{-value} = $sysVMSwapFree if ($obj->{-name} =~ m/\.sysVMSwapFree$/);
}
# sysVMActivity "/usr/bin/vmstat", add si and so column
#
if ($obj->{-name} =~ m/\.sysVMActivity$/) {
my $sysVMActivity = undef;
# local workspace
my $out; my $raw; my $n2i; my @dat;
$out = $self->{-ctx}->{-sys}->run("/usr/bin/vmstat", "1m");
$raw = $out->{-stdout};
$n2i = {};
if ($raw =~ m/^[^\n]*\n *([^\n]*(\bs[io]\b[^\n]*){2})\n *([^\n]*)\n$/s) {
$n2i = &mkn2i(split / +/, $1) if (not defined $n2i->{sr});
}
if (defined $n2i->{si} and defined $n2i->{so}) {
my @dat = split(/ +/, $3);
$sysVMActivity = @dat[$n2i->{si}] + @dat[$n2i->{so}];
}
$obj->{-value} = $sysVMActivity;
}
}
elsif ($self->{-ctx}->{-platform}->id() =~ m/SunOS/i) {
# sysVMRamMax "/usr/platform/$arch/sbin/prtdiag", Memory size
# sysVMRamUsed sysVMRamMax - sysVMRamFree
# sysVMRamFree "/bin/pagesize" * "/bin/sar -r 1 1", freemem, convert bytes to MB
#
if ($obj->{-name} =~ m/\.sysVMRam(Max|Used|Free)$/) {
my $sysVMRamMax = undef;
my $sysVMRamUsed = undef;
my $sysVMRamFree = undef;
# local workspace
my $out; my $raw; my $n2i; my @dat; my $arch; my $pagesize; my $tmp;
# initialize arch; get or assume pagesize(1)
$arch = $self->{-ctx}->{-platform}->arch();
$out = $self->{-ctx}->{-sys}->run("/bin/pagesize", "forever");
$raw = $out->{-stdout};
$pagesize = 4096;
if ($raw =~ m/^(\d+)$/) {
$pagesize = $1;
}
# sysVMRamMax
$out = $self->{-ctx}->{-sys}->run("/usr/platform/$arch/sbin/prtdiag -v", "1m");
$raw = $out->{-stdout};
if ($raw =~ m/\nMemory size: (\d+) Megabytes/s) {
$sysVMRamMax = $1;
}
# sysVMRamFree
$out = $self->{-ctx}->{-sys}->run("/bin/sar -r 1 1", "1m");
$raw = $out->{-stdout};
$n2i = {};
if ($raw =~ m/^.*\n([^\n]*\bfreemem[^\n]*)\n(.*)$/s) {
$n2i = &mkn2i(split / +/, $1);
}
@dat = split(/ +/, $2);
if (defined $n2i->{freemem}) {
$tmp = @dat[$n2i->{freemem}];
}
$sysVMRamFree = int($tmp * $pagesize / 1024 / 1024) if (defined $tmp);
# sysVMRamUsed
if (defined $sysVMRamMax and defined $sysVMRamFree) {
$sysVMRamUsed = $sysVMRamMax - $sysVMRamFree;
}
$obj->{-value} = $sysVMRamMax if ($obj->{-name} =~ m/\.sysVMRamMax$/);
$obj->{-value} = $sysVMRamUsed if ($obj->{-name} =~ m/\.sysVMRamUsed$/);
$obj->{-value} = $sysVMRamFree if ($obj->{-name} =~ m/\.sysVMRamFree$/);
}
# sysVMSwapMax "swap -l", egrep ^/ and accumulate, convert 512byte blocks to MB
# sysVMSwapUsed sysVMSwapMax - sysVMSwapFree
# sysVMSwapFree "swap -l", egrep ^/ and accumulate, convert 512byte blocks to MB
#
if ($obj->{-name} =~ m/\.sysVMSwap(Max|Used|Free)$/) {
my $sysVMSwapMax = undef;
my $sysVMSwapUsed = undef;
my $sysVMSwapFree = undef;
# local workspace
my $out; my $raw; my $n2i; my @dat; my $tmpMax; my $tmpFree;
# sysVMSwapMax, sysVMSwapFree
$out = $self->{-ctx}->{-sys}->run("/usr/sbin/swap -l", "1m");
$raw = $out->{-stdout};
$n2i = {};
if ($raw =~ m/^\s*([^\n]*\bblocks[^\n]*\bfree[^\n]*)\n(.*)$/s) {
$n2i = &mkn2i(split / +/, $1) if (scalar keys %$n2i == 0);
}
$tmpMax = undef;
$tmpFree = undef;
foreach my $r (split /\n/, $2) {
if ($r =~ m/^\//) {
@dat = split(/ +/, $r);
if (defined $n2i->{blocks}) {
$tmpMax = 0 if (not defined $tmpMax);
$tmpMax += @dat[$n2i->{blocks}];
}
if (defined $n2i->{free}) {
$tmpFree = 0 if (not defined $tmpFree);
$tmpFree += @dat[$n2i->{free}];
}
}
}
$sysVMSwapMax = int($tmpMax * 512 / 1024 / 1024) if (defined $tmpMax);
$sysVMSwapFree = int($tmpFree * 512 / 1024 / 1024) if (defined $tmpFree);
# sysVMSwapUsed
if (defined $sysVMSwapMax and defined $sysVMSwapFree) {
$sysVMSwapUsed = $sysVMSwapMax - $sysVMSwapFree;
}
$obj->{-value} = $sysVMSwapMax if ($obj->{-name} =~ m/\.sysVMSwapMax$/);
$obj->{-value} = $sysVMSwapUsed if ($obj->{-name} =~ m/\.sysVMSwapUsed$/);
$obj->{-value} = $sysVMSwapFree if ($obj->{-name} =~ m/\.sysVMSwapFree$/);
}
# sysVMActivity "/bin/vmstat", sr column
#
if ($obj->{-name} =~ m/\.sysVMActivity$/) {
my $sysVMActivity = undef;
# local workspace
my $out; my $raw; my $n2i; my @dat;
$out = $self->{-ctx}->{-sys}->run("/bin/vmstat", "1m");
$raw = $out->{-stdout};
$n2i = {};
if ($raw =~ m/^[^\n]*\n *([^\n]*\bsr\b[^\n]*)\n *([^\n]*)\n$/s) {
$n2i = &mkn2i(split / +/, $1) if (not defined $n2i->{sr});
}
if (defined $n2i->{sr}) {
@dat = split(/ +/, $2);
$sysVMActivity = @dat[$n2i->{sr}];
}
$obj->{-value} = $sysVMActivity;
}
}
return;
}
# name to index
sub mkn2i ($) {
my (@name) = @_;
my $rc = {};
my $i = 0;
foreach my $f (@name) {
$f =~ s/[^\w]/_/;
$f =~ s/^([^a-zA-Z_])/_$1/;
$rc->{$f} = $i++;
};
return $rc;
}
1;