#!/usr/bin/perl -w use strict; use Getopt::Long; use Time::HiRes; use List::Util qw( sum ); use Data::Dumper; #use IO::Select; # does not work the way I want on Windows GetOptions( 'debug|d' => \my $debug, 're:s' => \my @buckets, 'totals|t' => \my $totals, 'window|w:s' => \my @windows, # in seconds 'update|u:i' => \my $update, ); if (! @windows) { @windows = qw(1 5 60); }; @windows = sort { $a <=> $b } @windows; $update ||= 1; @buckets = map { s/:(\w+)$// ? [ $1 => qr/$_/ ] : [$_ => qr/$_/ ] } @buckets; if ($totals) { unshift @buckets, ['totals' => qr/(?!)/ ]; }; my @names = map { $_->[0] } @buckets; my @slots; my $last = 0; my $last_update = 0; while (<>) { my $now = time; $last ||= $now - $windows[-1]; my $elapsed = $now - $last; #print "Elapsed: $elapsed ($slots[0]->{totals})\n"; chomp; # Check how many buckets have passed without data for (0..int($now - $last)-1) { unshift @slots, +{ map {; $_ => 0 } @names }; }; # Limit slots to maximum reporting size splice @slots, $windows[-1]+1; if ($totals) { $slots[0]->{totals}++; }; BUCKET: for my $b (@buckets) { my ($n,$r) = @$b; if (/$r/) { $slots[0]->{ $n }++; last BUCKET; }; }; $last = $now; if ($now - $last_update >= $update) { local $" = "\t"; print "\t@windows\n"; for my $n (@names) { print "$n\t"; for my $w (@windows) { print sprintf "%0.2f\t", sum( map { $_->{ $n } } @slots[ 1.. $w ] ) / $w; }; print "\n"; }; $last_update = $now; }; };