ALFCYAPC::Asia 2013 Tokyo
前夜祭 LT-thon
Masahiro Nagano @kazeburo
Me
• 長野雅広 Masahiro Nagano
• @kazeburo
• PAUSE: KAZEBURO
• Operations Engineer, Site Reliability
• LINE Corp.
Development support
on LINE Familly, livedoor
ALFC =
Apache::LogFormat::Compiler
Convert
‘%h %l %u %t "%r" %>s %b’
to perl-code
my $code = <<EOF;
sub {
my ($env,$res,$length,$reqtime,$time) = @_;
$time = time() if ! defined $time;
my @lt = localtime($time);;
my $t = sprintf '%02d/%s/%04d:%02d:%02d:%02d %s', $lt[3],
$abbr[$lt[4]], $lt[5]+1900, $lt[2], $lt[1], $lt[0], $tz;
q!! . ($env->{REMOTE_ADDR} || '-')
. q! ! . '-'
. q! ! . ($env->{REMOTE_USER} || '-')
. q! ! . "[" . $t . "]"
. q! "! . _safe($env->{REQUEST_METHOD}) . " " . _safe($env-
>{REQUEST_URI}) . " " . $env->{SERVER_PROTOCOL}
. q!" ! . $res->[0]
. q! ! . (defined $length ? $length : '-')
. q!!
}
EOF
and compile
my $log_line = eval $code;
$log_line->($env,$res);
SYNOPSIS
my $log_handler = Apache::LogFormat::Compiler->new(
'%h %l %u %t "%r" %>s %b'
);
warn $log_handler->log_line($env,$res);
use Plack::Builder;
use Time::HiRes qw/gettimeofday tv_interval/;
use Apache::LogFormat::Compiler;
my $log_handler = Apache::LogFormat::Compiler->new(
'%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i" %D'
);
my $compile_log_app = builder {
enable sub {
my $app = shift;
sub {
my $env = shift;
my $t0 = [gettimeofday];
my $res = $app->();
my $reqtime = int(tv_interval($t0) * 1_000_000);
$env->{psgi.error}->print($log_handler->log_line(
$env,$res,6,$reqtime, $t0->[0]));
}
};
$app
};
OR
Plack::Middleware::AxsLog
yet another AccessLog Middleware
use Plack::Builder;
builder {
enable 'AxsLog',
combined => 1,
response_time => 1;
$app
};
OR
Plack::Middleware::AccessLog
Plack (1.0023~)
Benchmark
0
10000
20000
30000
40000
50000
60000
51262
8826
Plack-1.0022 Plack-1.0029
Req/Sec
A
 Story
 of
 ALFC
とある Ops と Dev のおはなし∼
I'm
 tuning
 up
 this
 web
 application.
 
NYTProf
 said
 that
 PM::AccessLog
 is
 slow
 
Yes,
 I
 know.
 It's
 slow
 because..
 
Ops Dev
Why PM::AccessLog
was slow?
my %char_handler = (
h = sub { $env-{REMOTE_ADDR} || '-' },
t = sub { [ . $strftime-('%d/%b/%Y:%H:%M:%S %z', localtime) . ] },
r = sub { _safe($env-{REQUEST_METHOD}) .  
. _safe($env-{REQUEST_URI}) .  
. $env-{SERVER_PROTOCOL} },
);
my $char_handler = sub {
my $char = shift;
exists $char_handler{$char}
? $char_handler{$char}-($char) : -;
};
$fmt =~ s!
(?:
%{(.+?)}([a-z]) |
%(?:[])?([a-zA-Z%])
)
! $1 ? $block_handler-($1, $2) : $char_handler-($3) !egx;
I
 can't
 live
 with
 PM::AccessLog!!
I
 have
 idea
 for
 speedup
Ops Dev
Solution: combine strings

Apache::LogFormat::Compiler YAPC::Asia 2013 Tokyo LT-Thon