2017-02-16 16 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 уже является списком строк. С помощью этой информации мы можем выполнить итерацию через 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 

Линия if any(error in line for error in valid_errors): проверяет line, чтобы увидеть, если какой-либо из ошибок в valid_errors в линии. Синтаксис представляет собой генератор, который дает error для каждого error в valid_errors.

Чтобы ответить на ваш вопрос, связанный с down_nodes, я не верю, что вы должны включить его в тот же any(). Вы должны попробовать что-то вроде

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

Ahh фантастический. Я уже думал об этом. Кажется, он работает очень хорошо :) - Я не знаю о конце строки, хотя, любой (ошибка в строке для ошибки в valid_errors): - есть ли здесь переменная переменной? как i или линия и т. д.? Я этого раньше не видел. any() - полезная вещь, которую нужно знать. Но я бы хотел узнать больше, если у вас есть только одно или два объяснения строки? (Я пытался повышать, но это не позволяло мне) – jonnybinthemix

+0

@jonnybinthemix Я добавил немного ответа – wpercy

+0

Спасибо, я ценю, что вы тратите время на это для меня :) - Это приятно и просто, мне нравится Это. – jonnybinthemix

1

Во-первых, вам нужно найти все журналы:

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) 

Например, чтобы найти все *.txt файлы в текущей директории:

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

Затем получить объекты файлов от названий:

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) 

Теперь Вы можете обрабатывать поток строк, полученных из данного каталога:

txt_file_names = find_files('*.txt', '.') 
txt_files = open_files(txt_file_names) 
txt_lines = lines_from_files(txt_files) 
find_errors(txt_lines) 

Идея обработки журналов как потока данных происходит из разговоров Дэвида Безли.

+1

А, это интересно спасибо. Я использовал re.compile, re.match и т. Д. В другом скрипте, который работал, и задался вопросом, будет ли это полезно здесь. Но, хотя я хочу отобразить всю строку журнала, а не части данной строки журнала, я подумал, что проще просто сбросить строки. По сути, я хочу, чтобы скрипт обнаружил серверы, которые не работают, и затем автоматически проверяет несколько вещей, чтобы увидеть, если они работают по общей причине ... затем отобразить на экране очевидные. – jonnybinthemix