riywoさんの「Perlでssh tail -fして目的の行が来たら終了する」に便乗するコネタ。
ログをtailしながら(ほぼ)リアルタイムで解析していくworkerの処理がどれくらい遅延しているのか確認して、それをgrowthforecastでグラフ化したいなと思ったので以下のようなスクリプトを書いてcronで実行しているよという話
#!/usr/bin/perl
use strict;
use Time::Piece;
use LWP::UserAgent;
my $worker = `/usr/bin/pgrep worker.pl`;
chomp($worker);
die "couldnot find worker pid" unless $worker;
pipe my $logrh, my $logwh
or die "Died: failed to create pipe:$!";
my $pid = fork;
if ( ! defined $pid ) {
die "Died: fork failed: $!";
}
elsif ( $pid == 0 ) {
close $logrh;
open STDERR, '>&', $logwh
or die "Died: failed to redirect STDERR";
close $logwh;
exec("/usr/bin/strace",'-s','300','-p',$worker,'-e','trace=read');
die "Died: exec failed: $!";
}
#parent
close $logwh;
my $time;
my $line = 0;
while(<$logrh>){
if ( m!\[(\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2}) \+0900\]! ) {
$time = $1;
last;
}
$line++;
last if $line > 3000;
}
kill($pid);
close $logrh;
while (wait == -1) {}
die "couldnot find time within 3000 lines" unless $time;
my $time = Time::Piece->strptime($time,q!%d/%b/%Y:%H:%M:%S!)->epoch;
my $delay = time() - $time + 3600*9;
$ua->post("http://growthforecast.local/api/worker/rag/host", {
number => $delay
});
まずpipeをつくり、fork。子プロセスで標準エラーをpipeに結びつけて、straceをreadのシステムコールだけトレースするようにして実行。straceの結果は親プロセスでpipeから読み取り、アクセスログの時間っぽい文字列を探す。文字列が見つかったらループを抜け、子プロセスを停止し、現在時間との差を計算して、GrowthForecastにポスト。
強引な手だけど見える化で得たものプライスレス