]> git.etc.gen.nz Git - spong.git/commitdiff
Checks the memory usage on the system and complains if it's too high.
authorMichael Brown <michaelb@opentext.com>
Thu, 21 Jun 2001 15:41:31 +0000 (15:41 +0000)
committerMichael Brown <michaelb@opentext.com>
Thu, 21 Jun 2001 15:41:31 +0000 (15:41 +0000)
At this point, it's kind of kludgey, using free(1) or top.

src/lib/Spong/Client/plugins/check_memory [new file with mode: 0755]

diff --git a/src/lib/Spong/Client/plugins/check_memory b/src/lib/Spong/Client/plugins/check_memory
new file mode 100755 (executable)
index 0000000..4d9787a
--- /dev/null
@@ -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 = <CMD>;
+
+   $line = <CMD>;
+   ($memtotal, $memused, $memfree, $shared, $buffers, $cached) =
+      ( $line =~ /^Mem:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ );
+   $message .= $line;
+
+   $line = <CMD>;
+   ($hardmemused, $hardmemfree) =
+      ( $line =~ /^[^:]*:\s+(\d+)\s+(\d+)/ );
+   $message .= $line;
+   
+   $line = <CMD>;
+   ($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 (<CMD>) {
+      /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);
+            $_ = <CMD>;
+            $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;