2013-07-27 35 views
0

我有一個可用的bash腳本,告訴我nginx訪問日誌進入時將原始日誌格式化爲豐富多彩的信息。將用戶代理信息包含在nginx訪問日誌bash腳本中

不幸的是,我不太清楚如何採取我已經創建的內容,並添加顯示請求的用戶代理。我希望能夠一目瞭然地瞭解哪個User-Agent被使用過。它是Googlebot嗎?在Windows上是Firefox 22嗎?

這裏是bash腳本我有:

#!/bin/bash 

LOG_DEFAULT_PATH="/var/log/nginx/access.log" 
LOG_PATH="$1" 

if [ "$LOG_PATH" = "" ] && test -f "$LOG_DEFAULT_PATH"; then 

    echo -e "\033[35mAuto-detected Log File: \033[32m$LOG_DEFAULT_PATH\033[0m" 
    LOG_PATH="$LOG_DEFAULT_PATH" 

fi 

if [ "$LOG_PATH" = "" ]; then 

    echo -e "\033[32mUsage: $0 /path/to/nginx/access_log\033[0m" 

else 

    (tail -n 500 -F $LOG_PATH | awk '{printf "%s%s %s %s%s%s %s %s %s%s%s %s%s\n", "\033[40;1;35m", $5, $6, "\033[0;32m", $1, "\033[37m", $10, substr($7, 2), "\033[31m", $8, "\033[36m", $2, "\033[0m"}') 

fi 

腳本的主體是在與tail命令開頭的行。我使用awk將不同部分的請求打印到終端,併爲每個部分着色。這裏我會假設用戶代理信息也會顯示出來。

這裏的日誌格式:

log_format vhost_combined '$http_host $remote_addr - $remote_user [$time_local] ' 
           '"$request" $status $body_bytes_sent "$http_referer" ' 
           '"$http_user_agent"'; 

當然,更好的腳本任何建議,也將不勝感激!

+0

您應該注意到awk使用「」作爲默認分割字段。但是,在字段內部,如$ time_local或$ http_user_agent,有空白,因此字段拆分可能與您想象的完全不同。在awk中使用正則表達式來分割日誌可能會更好。 – TroyCheng

回答

0

前段時間我解決了我自己的問題,但忘了在這裏更新。

以下是我想出了腳本:

#!/bin/sh 

LOG_DEFAULT_PATH="/var/log/nginx/access.log" 
LOG_PATH="$1" 

if [ "$LOG_PATH" = "" ] && [ -f "$LOG_DEFAULT_PATH" ]; then 

    echo -e "\033[35mAuto-detected Log File: \033[32m$LOG_DEFAULT_PATH\033[0m" 
    LOG_PATH="$LOG_DEFAULT_PATH" 

fi 

if [ "$LOG_PATH" = "" ]; then 

    echo -e "\033[32mUsage: $0 /path/to/nginx/access_log\033[0m" 

else 

    sudo tail -n 500 ./nginx-access.log | perl -n -e'/^(\S+) (\S+) (\S+) (\S+) \[([^:]+):(\d+:\d+:\d+) ([^\]]+)\] \"(\S+) (.*?) (\S+)\" (\S+) (\S+) "([^"]*)" "([^"]*)"$/ && print "\033[40;1;35m[$5 $6]\033[0;32m $1 \033[37m$11 $8 \033[31m$9 \033[36m$2 \033[30;1m$14\033[0m\n"' 

fi 

實質上,scsript的主要部分或本體是在底部的perl命令。它使用正則表達式分隔日誌格式,然後使用print顯示一些變量。

用戶代理最後使用正則表達式中的$14以粗體灰色文本顯示。

如果別人需要,可以給出進一步的解釋。

0

正如我在評論中所說的,注意字段中的空白區域,因爲awk使用空格作爲默認分隔符,所以您可能無法獲得正確的字段。您可以使用-F選項來更改默認分隔符,或者您可以在awk中使用正則表達式來執行此操作。在AWK對正則表達式的一個例子:

awk '{if(match($0,/GET ([^ ]*)/,a)){print a[1];}}' access_log 

而且正則表達式,你可以參考這個樣子的:

^(\d+\.\d+\.\d+\.\d+) ([^ ]+) ([^ ]+) \[([^\]]*)\] \"([A-Z]+) ([^\"]+)\" (\d+) (\d+) \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" ([\d\.]+)((\d+) (\d+))? 

結果: enter image description here

如果不能看到清晰的圖像,右鍵點擊它並在另一個選項卡中重新打開以查看原始大小。

+0

我似乎無法得到這個工作。我嘗試了多種方式。不過,我確實得到了第一個示例模式。命令行選項會爲答案提供什麼? –

+0

試着瞭解它是如何工作的,並根據你的情況進行修改。你想從日誌中獲得用戶代理,對吧?閱讀手冊,使用'man awk或awk --help'來查看如何使用自定義字段分隔符。嘗試谷歌'awk匹配',並找到它的工作原理,trey修改正則表達式,並使其適合你的情況,但你最好不要直接詢問代碼,試着理解它。 – TroyCheng

相關問題