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定時任務管理器的使用知識。
還有沒完全了解透徹和錯誤的地方。希望以後更新。