2010-11-19 6 views
0

phpやpythonの前の行からの文脈知識を必要とする複数行ログファイルを解析する最も良い方法は何ですか?PHP/Pythonでのサービス時間の複数行ログ解析

ex。

Date Time ID Call 

1/1/10 00:00:00 1234 Start 
1/1/10 00:00:01 1234 ServiceCall A Starts 
1/1/10 00:00:05 1234 ServiceCall B Starts 
1/1/10 00:00:06 1234 ServiceCall A Finishes 
1/1/10 00:00:09 1234 ServiceCall B Finishes 
1/1/10 00:00:10 1234 Stop 

各ログ行にはセッションにバインドするための一意のIDがありますが、連続する各行のセットは同じセッションのものであるとは限りません。

最終的な目標は、各トランザクションの所要時間と各サブトランザクションの所要時間を調べることです。

既にライブラリがある場合は、ライブラリを使用したいと考えています。

答えて

0

私はこれを行う2つの異なる方法を考えることができます。

1)finite state machineを使用して、ファイルを1行ずつ処理することができます。スタートラインをヒットしたら、時間をマークします。あなたが同じIDで停止行を押すと、時間と報告を比較する。

2)PHPのPerl-Compatible Regular Expressionsをm修飾子とともに使用して、各開始/停止行セットのすべてのテキストを一致させ、返された各一致文字列の最初と最後の行を見てください。

どちらの場合も、IDが一致していることを確認して、異なるセットとの照合を防止します。

0

私の最初の考えは、パーサが新しいキーで開始パターンを検出するたびにオブジェクトを作成することでした。私はあなたの例から、1234は、相互に関連しなければならないすべてのログ行を1つの "物"(オブジェクト)の状態にマッピングできるようなキーであると仮定しています。

これらのいずれかを追跡するパターンが表示され、それに関連するログエントリが表示されるたびに、後続の行が表すイベントタイプ(状態変更)のメソッドを呼び出します。

これらの「ログ状態」オブジェクト(より多くのapropos用語がないため)は、各ServiceCallのリストまたは辞書(または他のコンテナ)を含んでいる可能性があります。

したがって、ログを読み取るパーサー/ディスパッチャの場合、ログ項目が既存のオブジェクト(キー)に関連する場合、その項目はオブジェクトにディスパッチされます。 は、さらに独自の(ServiceCallまたは他の)オブジェクトおよび/またはそれらにイベントをディスパッチするか、例外を発生させるか、コールバックを呼び出すか、必要に応じて他の関数にコールアウトします。

おそらく、Stopイベントがディスパッチされたときにログオブジェクトによって呼び出されるコレクションまたは最終処理ハンドルも必要になります。

私は、ソートやステータスの報告方法をサポートして、アプリケーションが他のチャンネルの信号やコマンドに応答してライブ(未収集)オブジェクトをすべて列挙できるようにしたいと思います。パーサー/ディスパッチャーが実行したブロックチェック)

0

これは、私が少し前に書いたログパーサーのバリエーションです。 (一般的なアプローチはJim Dennisの説明とかなりよく似ていますが、任意のセッションのすべてのエントリを蓄積するためにリストのデフォルトを使用しましたが。あなたのデータの場合)

from pyparsing import Suppress,Word,nums,restOfLine 
from datetime import datetime 
from collections import defaultdict 

def convertToDateTime(tokens): 
    month,day,year,hh,mm,ss = tokens 
    return datetime(year+2000, month, day, hh,mm,ss) 

# define building blocks for parsing and processing log file entries 
SLASH,COLON = map(Suppress,"/:") 
integer = Word(nums).setParseAction(lambda t:int(t[0])) 
date = integer + (SLASH + integer)*2 
time = integer + (COLON + integer)*2 
timestamp = date + time 
timestamp.setParseAction(convertToDateTime) 

# define format of a single line in the log file 
logEntry = timestamp("timestamp") + integer("sessionid") + restOfLine("descr") 

# summarize calls into single data structure 
calls = defaultdict(list) 
for logline in log: 
    entry = logEntry.parseString(logline) 
    calls[entry.sessionid].append(entry) 

# first pass to find start/end time for each call 
for sessionid in sorted(calls): 
    calldata = calls[sessionid] 
    print sessionid, calldata[-1].timestamp - calldata[0].timestamp 

、これはプリントアウト:

1234 0:00:10 

をあなたがサブトランザクションを離れていじめるために同様のアプローチを持つエントリの各セッションのリストを処理することができます。