天天看點

nginx自動切割通路日志

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 A326

Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile

Safari/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定時任務管理器的使用知識。

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