2017-02-16 1 views
3

로그 디렉터리에서 여러 로그 파일을 구문 분석하여 목록에서 서버 이름과 함께 문자열을 검색하려고합니다. 내가 백만 가지 옵션을 시도한 것 같아요, 그리고 그것은 하나의 로그 파일로 잘 작동합니다.하지만 디렉터리에있는 모든 로그 파일을 통과하려고 할 때 나는 어디에도 가지 않는 것처럼 보입니다.문자열에 대한 다중 로그 파일 구문 분석

if args.f: 
    logs = args.f 
else: 
    try: 
     logs = glob("/var/opt/cray/log/p0-current/*") 
    except IndexError: 
     print "Something is wrong. p0-current is not available." 
     sys.exit(1) 

valid_errors = ["error", "nmi", "CATERR"] 

logList = [] 
for log in logs: 
    logList.append(log) 



#theLog = open("logList") 
#logFile = log.readlines() 
#logFile.close() 
#printList = [] 

#for line in logFile: 
# if (valid_errors in line): 
#  printList.append(line) 
# 
#for item in printList: 
# print item 


# with open("log", "r") as tmp_log: 

#  open_log = tmp_log.readlines() 
#   for line in open_log: 
#    for down_nodes in open_log: 
#     if valid_errors in open_log: 
#      print valid_errors 

down_nodes는 아래 표시된 서버의리스트를 포함하는 스크립트까지 상기 미리 작성된 목록이다.

내가 해왔 던 다양한 시도 중 일부가 주석 처리되었습니다.

logList = [] 
for log in logs: 
    logList.append(log) 

나는 이것이 내가 어쩌면 ..이 목록을 통해 목록에서 다음 루프를 각 개별 로그 파일을 넣고 open()readlines() 다음에하지만 난 여기에 논리의 일종을 누락 사용하는 것이 앞으로 방법이 될 수있다 생각 제대로 생각하지 않아.

나는 여기에 약간의 포인터로 정말로 할 수있다.

감사합니다.

+1

로그는 glob 별 결과로 이미 목록입니다. –

답변

1

따라서 logs은 이미 문자열 목록이므로 마지막 for 루프가 중복됩니다. 이 정보를 가지고 logs을 반복하고 각각 log에 대해 작업을 수행 할 수 있습니다. valid_errors의 오류 중 하나가 일치하는 경우

for log in logs: 
    with open(log) as f: 
     for line in f.readlines(): 
      if any(error in line for error in valid_errors): 
       #do stuff 

라인 if any(error in line for error in valid_errors): 체크 line 표시한다. 구문은 각각 error에 대해 error을 생성하는 생성자이며 valid_errors입니다.

down_nodes과 관련된 질문에 답변하려면 동일한 any()에 포함시켜야한다고 생각하지 않습니다.

txtfiles = find_files('*.txt', '.') 

그런 얻을 파일 객체 : 현재 디렉토리에있는 모든 *.txt 파일을 찾을 예를 들어

import os 
import fnmatch 

def find_files(pattern, top_level_dir): 
    for path, dirlist, filelist in os.walk(top_level_dir): 
     for name in fnmatch.filter(filelist, pattern) 
      yield os.path.join(path, name) 

: 당신은 모든 로그를 찾을

if any(error in line for error in valid_errors) and \ 
    any(node in line for node in down_nodes): 
+0

아 환상적입니다. 나는 그것을 생각하고 있었다. 그것은 꽤 잘 작동하는 것 :) - 나는 최종 라인에 대해, 어떤 (valid_errors에 오류 라인에 오류) 몰라 : - 여기에 변수가 오류가 무엇입니까? 나 또는 라인 등 좋아? 나는 전에 이것을 보지 못했다. any()는 유용한 정보입니다. 하지만 한 두 라인의 설명이 있다면 더 배우고 싶습니다. (내가 upvote하려고했지만 그것은 나를 못하게) – jonnybinthemix

+0

@ jonnybinthemix 대답에 조금을 추가했습니다 – wpercy

+0

고맙습니다, 당신을 위해 시간을내어 주셔서 감사합니다 :) - 이건 좋고 간단 해요, 내가 좋아 그것. – jonnybinthemix

1

첫째로 당신이 필요로하는 뭔가를 시도해야한다 이름에서 :

def open_files(filenames): 
    for name in filenames: 
     yield open(name, 'r', encoding='utf-8') 
파일에서개

마지막으로 개별 라인 :

def lines_from_files(files): 
    for f in files: 
     for line in f: 
      yield line 

당신이 검사는 다음과 같이 수있는 몇 가지 오류를 찾으려면 이후 : 이제 특정 디렉토리에서 생성 된 라인의 스트림을 처리 할 수 ​​

import re 

def find_errors(lines): 
    pattern = re.compile('(error|nmi|CATERR)') 
    for line in lines: 
     if pattern.search(line): 
      print(line) 

를 :

로그를 데이터 스트림으로 처리하는 아이디어는 David Beazley의 대화에서 비롯된 것입니다.

+1

아, 고맙습니다. 나는 re.compile, re.match 등을 사용하고 있었고 다른 스크립트에서 일하고 있었고 여기가 유용할지 궁금해했다. 그러나 나는 주어진 로그 라인의 일부분이 아닌 전체 로그 라인을 표시하고자하므로 라인을 덤프하는 것이 더 쉬울 것이라고 생각했다. 본질적으로 내가 바라는 것은 스크립트가 다운 된 서버를 찾은 다음 자동으로 몇 가지를 확인하여 일반적인 이유인지 확인한 후 화면에 분명히 표시합니다. – jonnybinthemix