Skip to content

Instantly share code, notes, and snippets.

@sheeplogh
Created October 16, 2013 08:52
Show Gist options
  • Save sheeplogh/7004731 to your computer and use it in GitHub Desktop.
Save sheeplogh/7004731 to your computer and use it in GitHub Desktop.
ApacheのCombined + %D 形式のアクセスログから1秒毎の同時接続数を集計するスクリプト。 タイムスタンプを接続が開始された時刻とみなして、%D の間は接続が維持されているものとする。 結果はあくまで参考値。 スクリプトと同じディレクトリに access_log をおいてから実行する。
#!/usr/bin/perl
###
### ApacheのCombined + %D 形式のアクセスログから1秒毎の同時接続数を集計するスクリプト。
### タイムスタンプを接続が開始された時刻とみなして、%D の間は接続が維持されているものとする。
### 結果はあくまで参考値。
### スクリプトと同じディレクトリに access_log をおいてから実行する。
###
use strict;
use warnings;
use diagnostics;
use Time::Local;
open(LOGFILE, "./access_log") || die $!;
my $connections = [];
my $basetime = 0;
while (<LOGFILE>) {
/^(.*) (.*) (.*) \[(.+) (.+)\] "(.*) (.*) (.*)" (.*) (.*) "(.*)" "(.*)" (.*)/;
my $request_uri = $7;
my @cols = split(/\?/, $request_uri);
my $time_start = $4;
my $time_start_epoch = time_to_sec( time_from_str( $time_start ) );
my $time_end_epoch = $time_start_epoch + ( $13 /1000000 );
if ($basetime eq 0) {
$basetime = $time_start_epoch;
}
while ($basetime < $time_start_epoch) {
my $connections2 = [];
my $clients = 0;
foreach my $conn (@$connections) {
if ( @$conn[1] >= $basetime ) {
my @tmpconn = @{ $conn };
push @$connections2, \@tmpconn;
}
$clients++;
}
print localtime($basetime) . " " . $clients . "\n";
$basetime++;
$connections = $connections2;
}
my @connection = ($time_start_epoch, $time_end_epoch, $cols[0]);
push @$connections, \@connection;
}
close(LOGFILE);
###
### sub routines
###
sub time_from_str{
my $time_str = shift;
return unless $time_str;
my $time = {};
if( $time_str =~ /^(\d{2})\/(\w{3})\/(\d{4}):(\d{2}):(\d{2}):(\d{2})$/ ) {
@{ $time }{ qw( mday mon year hour min sec ) } = ( $1, $2, $3, $4, $5, $6 );
my %num_of_mon = (
jan => 0, feb => 1, mar => 2, apr => 3, may => 4, jun => 5,
jul => 6, aug => 7, sep => 8, oct => 9, nov => 10, dec => 11,
);
$time->{ mon } = $num_of_mon{ lc( $time->{ mon } ) };
return unless defined( $time->{ mon } );
$time->{ year } -= 1900;
return wantarray ? %{ $time } : $time;
}
return;
}
sub time_to_sec{
my $time;
if( ref( $_[0] ) eq 'HASH' ){
$time = shift;
}
else{
%{ $time } = @_;
}
return unless defined( $time->{ sec } );
return unless defined( $time->{ min } );
return unless defined( $time->{ hour } );
return unless defined( $time->{ mday } );
return unless defined( $time->{ mon } );
return unless defined( $time->{ year } );
require Time::Local;
my $sec = Time::Local::timelocal(
$time->{ sec },
$time->{ min },
$time->{ hour },
$time->{ mday },
$time->{ mon },
$time->{ year },
);
return $sec;
}
__END__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment