#!/usr/bin/perl
#
# Gather load stats from gibraltar LFW for input to statsplot.
#
# Corey Satten, corey @ cac.washington.edu, 3/19/02 - version 0.5
#
# explanation of output:
#
#   packets/sec forwarded ---------------------------------------------+
#   packets/sec not forwarded -------------------------------------+   |
#   number of iptables "connected" states --------------------+    |   |
#   /etc, /var/tmp, /var, /var/log %used +----+----+----+     |    |   |
#   memory: %active ---------------+     |    |    |    |     |    |   |
#   memory: %used -----------+     |     |    |    |    |     |    |   |
#   1 min cpu load avg +     |     |     |    |    |    |     |    |   |
#   yymmdd@hh:mm:ss    v     v     v     v    v    v    v     v    v   v
#   020312@10:34:00 l 0.00 m 29.9 5.9 d 76.3 0.9 28.5 43.7 s 123 p 0.3 595.2

require 'sys/syscall.ph';

$| = 1;
$interval = $#ARGV==0 ? abs($ARGV[0]) : 15;
$interval = 1 if ($interval < 1);
if ($interval > 1 && $interval <= 60) {
  if (60 % $interval == 0) {  # synchronize time to exact multiple of interval
    ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
    sleep($interval - ($sec % $interval));
    }
  }
$ntm = time-$interval;
while (1) {
  $tim = time;
  sleep($interval - ($tim - $ntm));
  $ntm = $ntm + $interval;	# intended sample time
  ($sec,$min,$hour,$mday,$mon,$year) = localtime($ntm);
  $now = sprintf("%02d%02d%02d@%02d:%02d:%02d",
		  $year%100, $mon+1, $mday, $hour, $min, $sec);

  open(F, "/proc/loadavg");
  @ld = split(/ /, <F>);
  close(F);

  open(F, "/proc/meminfo");
  while (<F>) {
    s/^MemTotal:\s+(\d+).*/\1/ && ($mt = $1);
    s/^MemFree: \s+(\d+).*/\1/ && ($mf = $1);
    s/^Active:  \s+(\d+).*/\1/ && ($ma = $1);
    s/^Cached:  \s+(\d+).*/\1/ && ($mc = $1);
    }
  close(F);

  open(F, "/proc/net/ip_conntrack");
  while (<F>) {};
  $st = $.;
  close(F);

  open(F, "/proc/net/snmp");
  while (<F>) {
    if (/^Ip: \d/) {
      @ip = split;
      $fw = abs($ip[6] - $fo) if ($fo); $fw = 0 if ($fw > 1000000); #forwarded
      $fo = $ip[6];
      $re = abs($ip[3] - $ro) if ($ro); $re = 0 if ($re > 1000000); #received
      $ro = $ip[3];
      last;
      }
    }
  close(F);

  printf("%s", $now);
  printf(" l %s", $ld[0]);					# cpu load
  printf(" m %.1f %.1f", 100*($mt-$mf-$mc)/$mt, 100*$ma/$mt);	# memory
  printf(" d");
  foreach $fs ("/etc", "/var/tmp", "/var", "/var/log") {	# disk
    printf(" %.1f", statfs($fs));
    }
  printf(" s %s", $st);						# states
  printf(" p %.1f %.1f", ($re-$fw)/$interval, $fw/$interval);	# pkts
  printf("\n");
  }

sub statfs {
  local($s, $fs, $r, @a);
  $fs = $_[0];
  $s = ' ' x 128;			# pre-alloc space for return structure
  $r = syscall(&SYS_statfs, $fs, $s);
  @a = unpack("l9", $s);
  return 100*(1-$a[3]/$a[2]);		# percentage used
  }
