私たちは職場でSolaris 10を実行します。私がやりたいことは、他の行の前にある行を見つけることです。
実際のケース。次のクエリにより、一部のリクエストがタイムアウトしたことがわかります。
grep タイムアウト log.log.
これは私に次のようなものを与えます:
2010-11-30 20:59:57,495 ERROR [82.69.73.87 - 342E15CB9651927BE715780FC40DEC53 - 3675058] Send Call (AbstractEngineServlet.java:288) > - Merchant error HTTPS Comms found. Merchant Trans Id: 22283845800 The host did not accept the connection within timeout of 60000 ms
ログファイル中に呼び出しを記録するまでには、おそらく数行かかります。
2010-11-30 20:56:57,495 INFO [82.69.73.87 - 342E15CB9651927BE715780FC40DEC53 - 3675058] about to call http://www.example.com
だから私が望むのは、すべてのタイムアウトを識別し、その直前にあり、同じIPアドレスまたはセッションを持つすべての「すぐに呼び出された」行を識別することです。
上記の例では、「342E15CB9651927BE715780FC40DEC53」を含む前の行を見つけます。標準シェルツールを使用してこれは可能ですか?
答え1
これはawkの仕事のようです。ログが十分に規則的であると仮定します(特にセッションCookieを6番目のフィールドに抽出したため)。
<foo.log awk '
/about to call/ {target[$6]=$0;}
/AbstractEngineServlet.*timeout/ {print target[$6]; print;}
'
答え2
for i in `grep timeout log.txt|awk '{print $6}'`;
do
grep $i log.txt;
echo "-----------------";
done
答え3
テストされていないが類似
#!/usr/bin/env perl
my %lastline;
while (<>) {
if (/\b([[:xdigit:]]{32})\b/) {
if (/INFO/) {
$lastline{$1} = $_;
}
elsif (/ERROR/) {
print delete $lastline{$1} if exists $lastline{$1};
print;
}
}
}
うまくいくかもしれません。