2010-11-19 4 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

나는 이것을하는 두 가지 다른 방법을 생각할 수 있습니다.

1) finite state machine을 사용하여 파일을 한 줄씩 처리 할 수 ​​있습니다. 시작 줄을 치면 시간을 표시하십시오. 같은 ID로 중지 라인을 치면 시간과보고를 구분하십시오.

2) m 수정자를 사용하여 PHP의 Perl-Compatible Regular Expressions을 사용하여 각 시작/정지 줄 집합의 모든 텍스트를 일치시킨 다음 반환 된 각 일치 문자열의 첫 번째 줄과 마지막 줄만 봅니다.

두 경우 모두 ID가 일치하는지 확인하여 다른 세트와의 비교를 막을 수 있습니다.

0

나의 첫 번째 생각은 내 파서가 새로운 키로 시작 패턴을 만날 때마다 개체를 만드는 것입니다. 당신의 예에서, 1234는 서로 연관되어야하는 모든 로그 라인이 하나의 "물건"(객체)의 상태로 매핑 될 수있는 열쇠라고 가정합니다.

이러한 패턴 중 하나를 추적하기 시작하는 패턴이 표시되고 이에 대한 로그 항목이 표시 될 때마다 이러한 후속 라인이 나타내는 이벤트 유형 (상태 변경)에 대한 메소드를 호출합니다.

예제에서 이러한 "로그 상태"객체 (더 많은 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 

당신은 하위 거래를 떨어져 애타게 유사한 방식으로 항목의 각 세션의 목록을 처리 할 수 ​​있습니다.