#!/usr/bin/env perl # # $Id$ use strict; use warnings; use Getopt::Std; use Time::Piece; my %opt; getopts( 'achs:', \%opt ); $opt{h} and HELP_MESSAGE(); $opt{a} && $opt{c} and die "options -a and -c are incompatible\n"; if ( defined( $opt{s} ) && ( $opt{s} =~ /\D/ || !$opt{s} || $opt{s} > 39 ) ) { die "option -s takes a number of seconds between 1 and 59\n"; } sub HELP_MESSAGE { print STDERR <) { my ($time) = /(?!^|\s)\[([^]]*)\](?=$|\s)/ or die "Cannot find timestamp in log line: $_"; my $min; eval { $min = Time::Piece->strptime( $time, $time_format ) } or die "timestamp in log is not in required format\n"; if ( $opt{s} ) { # round the time to the last interval $min -= $min->sec() % $opt{s}; } else { # round the time to the minute $min -= $min->sec(); } #warn "input time is $time, min is $min\n"; push( @mins, $min ) if !$mins{$min}++; if ( !defined($prevmin) ) { $prevmin = $min; $latest = $min; } elsif ( $prevmin ne $min ) { #print_min($prevmin); $prevmin = $min; $latest = $latest < $min ? $min : $latest; } if ( $min == $latest ) { print "+ $_" if $opt{a}; ++$count_in_min{$min}; } else { print "- $_" if $opt{a}; ++$count_past_min{$min}; } } exit if $opt{a}; #@mins = sort { $a <=> $b } @mins; # will usually be sorted already if ( $opt{c} && @mins ) { # add any empty minutes my @allmins = shift(@mins); while (@mins) { if ( $opt{s} ) { for ( my $mins = $allmins[-1] + $opt{s} ; $mins < $mins[0] && $mins < $allmins[-1] + 60 ; $mins += $opt{s} ) { push( @allmins, $mins ); } } for ( my $min = $allmins[-1] + 60 ; $min < $mins[0] ; $min += 60 ) { if ( $opt{s} ) { for ( my $mins = $min + $opt{s} ; $mins < $mins[0] && $min < $min + 60 ; $mins += $opt{s} ) { push( @allmins, $mins ); } } push( @allmins, $min ); } push( @allmins, shift(@mins) ); } @mins = @allmins; } for my $min (@mins) { print_min($min); }