From bd4be869d8af8b5f8bab2f006aa91080ee601b26 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Thu, 21 Jun 2001 15:41:31 +0000 Subject: [PATCH] Checks the memory usage on the system and complains if it's too high. At this point, it's kind of kludgey, using free(1) or top. --- src/lib/Spong/Client/plugins/check_memory | 127 ++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100755 src/lib/Spong/Client/plugins/check_memory diff --git a/src/lib/Spong/Client/plugins/check_memory b/src/lib/Spong/Client/plugins/check_memory new file mode 100755 index 0000000..4d9787a --- /dev/null +++ b/src/lib/Spong/Client/plugins/check_memory @@ -0,0 +1,127 @@ +# $Id# +# vim:syn=perl:expandtab:ts=3:sw=3:ai:si +# Register this routine with the plugin registry +$CHECKFUNCS{'memory'} = \&check_memory; + +# This routine checks the memory usage on various systems. Since I can't find a +# nice way of doing things, we grab the output of top or free on linux. It's +# likely going to have to be configured for each OS it runs on. :-( + +# $MEMCHECK = "/usr/bin/top -b -n 1 "; # To use 'top' +# $MEMCHECK = "/usr/bin/free"; # On linux systems + +sub check_memory { + if (!defined $MEMWARN or !defined $MEMCRIT) { + $color = "yellow"; + $summary = "Warning levels not defined"; + $message = "\$MEMWARN or \$MEMCRIT not defined!"; + } elsif ($MEMCHECK =~ /free/) { + ($color, $summary, $message) = &check_memory_free; + } elsif ($MEMCHECK =~ /top/) { + ($color, $summary, $message) = &check_memory_top; + } else { + $color = "yellow"; + $summary = "Don't know how to check memory"; + $message = "No suitable memory-checking command found\n". + "\$MEMCHECK=\"$MEMCHECK\""; + } + + &debug( "memory - $color, $summary" ); + &status( $SPONGSERVER, $HOST, "memory", $color, $summary, $message ); +} + +sub check_memory_free { + open CMD, "$MEMCHECK |"; + $message = ; + + $line = ; + ($memtotal, $memused, $memfree, $shared, $buffers, $cached) = + ( $line =~ /^Mem:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ ); + $message .= $line; + + $line = ; + ($hardmemused, $hardmemfree) = + ( $line =~ /^[^:]*:\s+(\d+)\s+(\d+)/ ); + $message .= $line; + + $line = ; + ($swaptotal, $swapused, $swapfree) = + ( $line =~ /^Swap:\s+(\d+)\s+(\d+)\s+(\d+)/ ); + $message .= $line; + + $physpctused = floor($hardmemused/$memtotal*100); + $virtpctused = floor(($hardmemused+$swapused)/($memtotal+$swaptotal)*100); + $summary = "$physpctused% phys mem used, $virtpctused% virt mem used"; + + $color = "green"; + if ($virtpctused > $MEMWARN) { $color = "yellow"; } + if ($virtpctused > $MEMCRIT) { $color = "red"; } + + close CMD; + return ($color, $summary, $message); +} + +sub check_memory_top { + $kmb='\s+(\d+[KM])'; + @parse_error = ("yellow", "Can't parse memory line", $message); + open CMD, "$MEMCHECK |"; + while () { + /PID/ && last; + /^$/ && next; + $message .= $_; + if (/^Mem/) { + # top from the procps on Linux has this format: + if (/^Mem:$kmb av,$kmb used,$kmb free,$kmb shrd,$kmb buff/) { + ($memtotal,$memused,$memfree,$shared,$buffers) = ($1,$2,$3,$4,$5); + &to_KB($memtotal,$memused,$memfree,$shared,$buffers); + $_ = ; + $message .= $_; + if (/^Swap:$kmb av,$kmb used,$kmb free$kmb cached/) { + ($swaptotal, $swapused, $swapfree, $cached) = ($1,$2,$3,$4); + &to_KB($swaptotal, $swapused, $swapfree, $cached); + } else { + close CMD; + return @parse_error; + }; + $hardmemused = $memused-$buffers-$cached; + } elsif (/^Memory:$kmb real,$kmb free,$kmb swap,$kmb free swap/) { + # the top package supporting various unices has this format + ($memtotal,$memfree,$swapused,$swapfree) = ($1,$2,$3,$4); + &to_KB($memtotal,$memfree,$swapused,$swapfree); + $hardmemused = $memtotal-$memfree; + $swaptotal = $swapused+$swapfree; + } elsif (/^Memory:$kmb real,$kmb free,$kmb swap in use,$kmb swap free/) { + # the top package supporting various unices has this format + ($memtotal,$memfree,$swapused,$swapfree) = ($1,$2,$3,$4); + &to_KB($memtotal,$memfree,$swapused,$swapfree); + $hardmemused = $memtotal-$memfree; + $swaptotal = $swapused+$swapfree; + } else { + close CMD; + return @parse_error; + } + $physpctused = floor($hardmemused/$memtotal*100); + $virtpctused = floor(($hardmemused+$swapused)/($memtotal+$swaptotal)*100); + } + } + close CMD; + $color = "green"; + $summary = "$physpctused% phys mem used, $virtpctused% virt mem used"; + if ($virtpctused > $MEMWARN) { $color = "yellow"; } + if ($virtpctused > $MEMCRIT) { $color = "red"; } + return ($color, $summary, $message); +} + +# Convert each value to the appropriate number of kilobytes +sub to_KB { + my $i; + for ($i=0; $i <= (scalar(@_)-1); ++$i) { + if ($_[$i] =~ /^(\d+)$/) { $_[$i] = floor($1/1024); next; } + if ($_[$i] =~ /^(\d+)K$/) { $_[$i] = $1; next; } + if ($_[$i] =~ /^(\d+)M$/) { $_[$i] = floor($1*1024); next; } + } + return @_; +} + +# I'm included perl code, I need this. +1; -- 2.30.2