2017-02-16 20 views
3

ログディレクトリからいくつかのログファイルを解析して、リスト内の任意の数の文字列をサーバー名とともに検索しようとしています。私は何百万ものオプションを試したような気がしますが、ログファイル1つでうまく動作します。しかし、ディレクトリ内のすべてのログファイルを調べようとすると、どこにも見えません。複数のログファイルを文字列として解析する

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) 

私は多分..私は、これは、このリストをループその後、リスト内の個々のログファイルを置くために、前方方法であることとreadlines()続いopen()を使用することが考えられますが、私はここにロジックのいくつかの種類が欠けています正しく考えていない。

私は実際にここでいくつかのポインタでどうすればいいですか。

ありがとうございました。

+1

ログはglobによる返り値としてすでにリストになっています。 –

答えて

1

logsはすでに文字列のリストなので、最後のforループは冗長です。その情報を使用して、logsを繰り返し実行し、それぞれlogに対して何かを実行できます。

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 

valid_errorsのエラーのいずれかが一致しているかどうかを確認するためにlineをチェックif any(error in line for error in valid_errors):ライン。構文は、それぞれerrorerrorvalid_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()は知っておくと便利です。しかし、あなたは1つまたは2つの回線の説明があれば、もっと学びたいですか? (私は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

関連する問題