nginx自動切割訪問日誌

來源:互聯網
上載者:User

 

Web 存取日誌 (access_log) 記錄了所有外部客戶端對Web伺服器的訪問行為,包含了用戶端IP,訪問日期,訪問的URL資源,伺服器返回的HTTP狀態代碼等重要訊息。
一條典型的Web訪問日誌如下:


112.97.37.90 - - [14/Sep/2013:14:37:39 +0800] "GET / HTTP/1.1" 301 5"-" "Mozilla/5.0 (Linux; U; Android 2.3.6; zh-cn; Lenovo A326Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 MobileSafari/533.1 MicroMessenger/4.5.1.259" -

 

規劃:

1、  要解決問題:

當網站訪問量大後,日誌資料就會很多,如果全部寫到一個記錄檔中去,檔案會變得越來越大。檔案大速度就會慢下來,比如一個檔案幾百兆。寫入日誌的時候,會影響操作速度。另外,如果我想看看訪問日誌,一個幾百兆的檔案,下載下來開啟也很慢。使用第三方免費的日誌分析工具-日誌寶,可以上傳nginx、apache、iis的記錄檔,它們協助分析網站安全方面。畢竟專攻,更加專業。日誌寶對上傳的檔案也是做了大小限制的,不超過50m。

 

2、nignx沒有自動分開檔案儲存體日誌的機制。由於nginx它不會幫你自動分檔案儲存。所以,需要自己編寫指令碼來實現。

 

shell指令檔nginx_log_division.sh內容如下:

 

# /bin/bash

logs_path="/data/wwwlogs/"

#以前的記錄檔。

log_name="xxx.log"   

pid_path="/usr/local/nginx/logs/nginx.pid"

 

mv ${logs_path}${log_name}${logs_path}${log_name}_$(date --date="LAST   WEEK" +"%Y-%m-d").log

 

kill -USR1 `cat ${pid_path}`

 

上面shell指令碼的原理是:先把以前的記錄檔移動重新命名成一個,目的是就是備份。

按照上個周一的本日來命名,運行指令碼的時候時間點是”2013-09-16”,那麼組建檔案名稱是”xxx.log_ 20130909.log”。

在沒有執行kill -USR1 `cat${pid_path}`之前,即便已經對檔案執行了mv命令而改變了檔案名稱,nginx還是會向新命名的檔案” xxx.log_ 20130909”照常寫入日誌資料的。原因在於:linux系統中,核心是根據檔案描述符來找檔案的。

 

----------------對linux檔案描述符的理解

 

檔案描述符是linux核心為每個開啟的檔案命名的一個整數標識。

linux核心為每一個進程產生(或者說維護)一個”檔案描述符表”,這個檔案描述符表記錄的是“此進程所開啟的檔案(進行標識)”。

在這裡的環境中,nginx就是一個運行中的進程,這個進程早就開啟了一個記錄檔,在檔案描述符表是記錄了檔案的。

即便記錄檔的路徑改變了,但是還是能夠找到(根據檔案描述符表可以定位)。

 ----------------------------------------------

當執行命令“kill -USR1 `cat ${pid_path}`”的時候,nginx.pid檔案中儲存的其實就是一個數字(自己可以開啟看一下,我這裡是894),nginx 將其主進程的 pid (進程號)寫入到了nginx.pid 檔案中,所以可以通過cat命令直接拿到其主進程號,直接操作指定的進程號。

 

kill -USR1 `cat ${pid_path}` 就等同於

kill –USR1 894  #指定發訊號(USR1)訊號給這個進程編號。

 

在linux系統中,linux是通過訊號與”正在啟動並執行進程”進行通訊的。linux系統中,也很多預定義好的訊號,像SIGHUP。USR1是使用者自訂訊號。可以理解為:進程自己定義接到這個訊號該幹嘛(也就是進程編寫者自己確定收到這個訊號幹嘛還是什麼都不做都行,完全交給開發人員自己決定)。而在nginx中,它自己編寫了代碼處理當我接到USR1訊號的時候,讓nginx重新開啟記錄檔。具體原理如下:

1、nginx 的主進程收到USR1訊號,會重新開啟記錄檔(以nginx設定檔中的日誌名稱命名,就是設定檔中access_log項所設定的值,如果檔案不存在,會自動建立一個新的檔案xxx.log)。

 

2、然後把記錄檔的擁有者改為“背景工作處理序(worker進程)”,目的是讓worker進程就具備了對記錄檔的讀寫權限(master和worker通常以不同使用者運行,所以需要改變擁有者)。

 

3、nginx主進程會關閉重名的記錄檔(也就是剛才使用mv命令重新命名成xxx.log_20130909.log的檔案),並通知背景工作處理序使用新開啟的記錄檔(剛才主進程開啟的檔案xxx.log)。具體實現上更細化點就是,主進程把USR1訊號發給worker,worker接到這個訊號後,會重新開啟記錄檔(也就是設定檔中約定的xxx.log)

 

 

===================================定時執行指令碼

 

設定上面的shell指令檔加入到定時任務中去。crontab是linux下面一個定時任務進程。開機此進程會啟動,它每隔一定時間會去自己的列表中看是否有需要執行的任務。

 

crontab -e

 

* 04 * * 1/data/wwwlogs/nginx_log_division.sh

 

 

會開啟一個檔案,加入上面的代碼

格式為 "分 時 日 月 星期幾  要執行的shell檔案路徑"。用*可以理解成“每”,每分鐘,每個小時,每個月等等。

我設定是在周一淩晨4點運行nginx_log_division.sh指令碼,指令碼的內容就是重建一個新的記錄檔。

 

 

附:設定nginx日誌的配置方法

 

log_format site  '$remote_addr - $remote_user[$time_local] "$request" '

            '$status $body_bytes_sent "$http_referer" '

            '"$http_user_agent" $http_x_forwarded_for';

 

access_log /data/wwwlogs/xxxx.com.log  site

#第二個參數表示使用那個日誌格式,為每一個日誌格式標識了一個名稱,site對應的就是log_format中的名稱

 

 

以上涉及到crontab定時工作管理員的使用知識。

 

 

還有沒完全理解透徹和錯誤的地方。希望以後更新。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.