2013-02-15 32 views
3

我有一個我想解析的apache日誌文件。我找到了幾種不同的方法,包括apachelog,兩個回答herethis。使用這些方法中的任何一種,我都能夠解析日誌中的大部分行。然而,有些線路有2個IP地址:解析有2個IP地址的apache日誌

xxx.xx.xx.xxx, yy.yyy.yy.yyy - - [14/Feb/2013:03:55:21 +0000] "GET /alink HTTP/1.0" 200 90210 "http://www.google.com/search" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.4 (KHTML, like Gecko; Google Web Preview) Chrome/22.0.1229 Safari/537.4" 

沒有提到的方法能夠正確解析此行。 (我甚至嘗試過apachelog的虛擬主機選項)。有什麼建議麼?我使用自己的商家後一種方法我提到的(但我開到任何東西),例如:

parts = [ 
    r'(?P<host>\S+)',     # host %h 
    r'\S+',        # indent %l (unused) 
    r'(?P<user>\S+)',     # user %u 
    r'\[(?P<time>.+)\]',    # time %t 
    r'"(?P<request>.+)"',    # request "%r" 
    r'(?P<status>[0-9]+)',    # status %>s 
    r'(?P<size>\S+)',     # size %b (careful, can be '-') 
    r'"(?P<referer>.*)"',    # referer "%{Referer}i" 
    r'"(?P<agent>.*)"',     # user agent "%{User-agent}i" 
    ] 
    pattern = re.compile(r'\s+'.join(parts)+r'\s*\Z') 

    for line in open(log): 
     try:  
      m = pattern.match(line) 
      if m: 
       res = m.groupdict() 
       data.append(res) 
      if not m: 
       print line 
     except: 
      print line 

回答

3

您可以修改正則表達式的第一個組件,允許以逗號分隔的主機列表。您例如線以下工作:

import re 
parts = [ 
    r'(?P<host>\S+(,\s*\S+)*)',   # comma-separated list of hosts        
    r'\S+',        # indent %l (unused)     
    r'(?P<user>\S+)',     # user %u       
    r'\[(?P<time>.+)\]',    # time %t       
    r'"(?P<request>.+)"',    # request "%r"      
    r'(?P<status>[0-9]+)',    # status %>s       
    r'(?P<size>\S+)',     # size %b (careful, can be '-')  
    r'"(?P<referer>.*)"',    # referer "%{Referer}i"    
    r'"(?P<agent>.*)"',     # user agent "%{User-agent}i"  
] 
pattern = re.compile(r'\s+'.join(parts)+r'\s*\Z') 

test = 'xxx.xx.xx.xxx, yy.yyy.yy.yyy - - [14/Feb/2013:03:55:21 +0000] "GET /alink HTTP/1.0" 200 90210 "http://www.google.com/search" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.4 (KHTML,like Gecko; Google Web Preview) Chrome/22.0.1229 Safari/537.4"' 
m = pattern.match(test) 
res = m.groupdict() 

上述命令後,res['host']包含xxx.xx.xx.xxx, yy.yyy.yy.yyy。如果您需要單獨的主機地址,則可以使用res['host'].split(',')獲取地址列表。