2017-01-11 43 views
1

我想分析大量文本日誌文件(約100萬線)。下面的示例:解析一個大的文本文件,並提取數據,而循環一次以上 - Python的

2016年11月8日03:49.879的阿爾法:(157)一切都很好

2016年11月8日03:49.979的阿爾法:(157)有一個錯誤這裏

2016年11月8日03:50.879伽瑪:(2)其他東西在這裏

2016年11月8日03:51.879三角洲:(69)有些事情正在發生

我想實現的是查找錯誤,然後返回與該錯誤相關的所有行 - 在這種情況下爲alfa。問題是,當我第一次循環並發現錯誤,然後將alfa(157)保存爲參考,然後如何在沒有循環通過1M的情況下返回所有的alfa(157)行(即使是在例如錯誤之前發生的行)再次行。如果有50個錯誤怎麼辦?這可能嗎?這是否是O(n2)問題?

我想使用Python:

def analyze_log(f): 
    for line in f: 
     (..) 
+1

在'dict'中出現的組錯誤,其中鍵是日誌標籤,值是行列表。您可以使用該詞典打印報告。 –

+0

是否需要連續抓取所有線? – jure

+0

@jure他們直到(數),消息長度不同 –

回答

0

你可以從你的錯誤157,或任何椅子中錯誤的所有行追加,在相同的字典鍵:

log_errors = {} 
... 
if log_errors.has_key(error_key): 
    log_errors[error_key].append(line_from_log) 
else: 
    log_errors[error_key] = line_from_log 

PS。 has_key()已從python 3中刪除,請使用'in'運算符。

1

1M線是不是現代的硬件那麼大,我會用字典組裝的內存數據庫。喜歡的東西:

log_database = {} 
for i, line in enumerate(logfile): 
    date, time, label, message = line.split(None, 3) 
    log_database.setdefault(label, []).append({ 
     "line number": i, 
     "date": date, 
     "time": time, 
     "message": message, 
    }) 
+0

我會運行腳本後處理內存數據庫的?它會從內存中刪除它,還是我必須處理它? –

+0

如果你想訪問數據的腳本運行後,你將不得不堅持好歹它,例如,轉儲到一個JSON文件(或只是使用關係數據庫一樣'sqlite'或'mysql')。腳本運行後,所有內存都將被回收。 –

1

我建議你建立一個管道,你可以在每一行上執行多個操作的方式。如果你想變得更加奇特,你甚至可以使用協程來構建它,然後異步並行運行。

def has_errors(line): 
    return True if ('alfa' in line and 'ERROR' in line) else False 

def do_something(line): 
    # add your processing logic 
    processed = line 
    return processed 

errors = list() 
processed = list() 

with open('kwyjibo.log') as log_file: 
    for line in log_file: 
     if has_errors(line): 
      errors.append(line) 
     processed.append(do_something(line)) 

# contents of kwyjibo.log 
# 2016-11-08 03:49.879 alfa: (157) all is good 
# 2016-11-08 03:49.979 alfa: (157) there is an ERROR here 
# 2016-11-08 03:50.879 gamma: (2) something else is here 
# 2016-11-08 03:51.879 delta: (69) something is going on 

# Output 
# In [3]: errors 
# Out[3]: ['2016-11-08 03:49.979 alfa: (157) there is an ERROR here\n'] 

# In [4]: processed 
# Out[4]: 
# ['2016-11-08 03:49.879 alfa: (157) all is good\n', 
# '2016-11-08 03:49.979 alfa: (157) there is an ERROR here\n', 
# '2016-11-08 03:50.879 gamma: (2) something else is here\n', 
# '2016-11-08 03:51.879 delta: (69) something is going on\n'] 
+0

這種方法的好處是您可以根據需要進行多種不同的處理步驟。考慮在建立管道的地方使用* NIX類型的工具。這種方法的好處在於,如果通過使處理元素協同並行,然後執行並行處理來實現併發處理,則可以水平擴展。 –

+0

你在大文件上試過這種方法嗎?幾百萬行? –

+0

@Always_hungry我已經用這種方法處理400萬行文件。如果你在內存和約束方面有問題,那麼你需要考慮如何處理每個處理步驟的輸出,也許不是將它存儲在列表中,而是將它寫入另一個文件。在這種情況下,我通常會編寫我的應用程序,以便可以同時運行,然後平行運行它。 –

相關問題