一、Nginx日志描述
通過訪問日志,你可以得到用戶地域來源、跳轉來源、使用終端、某個URL訪問量等相關信息;
通過錯誤日志,你可以得到系統某個服務或server的性能瓶頸等。因此,將日志好好利用,你可以得到很多有價值的信息。
打開nginx.conf配置文件:vim /usr/local/nginx/conf/nginx.conf
與Nginx日志相關的指令主要有兩條,一條是log_format,用來設置日志的格式,另外一條是access_log,用來指定日志文件的存放路徑、格式和緩存大小。兩條指令在Nginx配置文件中的位置可以在http{......}之間,也可以在虛擬主機之間,即server{......}兩個大括號之間。
二、用log_format指令設置日志格式
log_format指令用來設置日志的記錄格式,它的語法如下:
log_format name format [format...]
其中name表示定義的格式名稱,format表示定義的格式樣式。log_format有一個默認的、無須設置的combined日志格式設置,也就是“main”日志格式,相當於Apache的combined日志格式,其具體參數如下:
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent"';
#access_log logs/access.log main;
您也可以自定義一份日志的記錄格式,不過要注意,log_format指令設置的name名稱在Nginx 配置文件中是不能重復的。
假設將 Nginx 服務器作為 Web 服務器,位於負載均衡設備、 Squid 、Nginx 反向代理之后, 就不能獲取到客戶端的真實IP地址了。原因是經過反向代理后,由於在客戶端和 Web 服務器之 間地加了中間層,因此 Web 服務器無法直接拿到客戶端的 IP,通過$remote_addr 變量拿到的將是反向代理服務器的 IP 地址。但是,反向代理服務器在轉發請求的 HTTP 頭信息中,可以增加 X-Forwarded-For信息,用以記錄原有的客戶端 IP 地址和原來客戶端請求的服務器地址。
這時候,就要用 log_format 指令來設置日志格式 ,讓日志記錄 X-Forwarded-For 信息中的IP 地址 ,即客戶的真實IP。
例如,創建一個名為mylogformat的日志格式,再$http_x_forwarded_forlog_for變量記錄用戶的X_Forwarded-For IP 地址:
log_format mylogformat '$http_x_forwarded_for_$remote_user [$time_local]''"$request" $status $body_bytes_sent' '"$http_referer" "$http_user_agent"'
日志格式參數明細表:
$remote_addr |
客戶端的ip地址(代理服務器,顯示代理服務ip) |
$remote_user |
用於記錄遠程客戶端的用戶名稱(一般為“-”) |
$time_local |
用於記錄訪問時間和時區 |
$request |
用於記錄請求的url以及請求方法 |
$status |
響應狀態碼,例如:200成功、404頁面找不到等。 |
$body_bytes_sent |
給客戶端發送的文件主體內容字節數 |
$http_user_agent |
用戶所使用的代理(一般為瀏覽器) |
$http_x_forwarded_for |
可以記錄客戶端IP,通過代理服務器來記錄客戶端的ip地址 |
$http_referer |
可以記錄用戶是從哪個鏈接訪問過來的 |
三、用access_log指令指定日志文件存放路徑
用 log_format 指令設置了日志格式之后,需要用 access_log 指令指定日志文件存放路徑。access_log 指令的語法如下:
access_log path [format [buffer=size | off]]
其中:
path 表示日志文件的存放路徑;
format 表示使用 log_format 指令設置的日志格式的名稱,
buffer=size 表示設置內存緩沖區的大小,例如可以設置 buffer=32k。
(1)如果不想記錄日志,可以使用以下指令關閉日志記錄:
access_log off;
(2)如果想使用默認的 combined 格式的日志記錄,可以使用以下示例:
access_log /data1/1ogs/filename.log;
或者
access_log /data1/1ogs/filename.log combined;
(3)如果想使用自定義格式的日志記錄,可以使用以下示例,其中的 mylogformat 是日志格 式名稱:
log_format mylogformat '$remote_addr - $remote_user [$time_local] "$request" ‘ ‘$status $body_þytes_sent "$http_referer" ‘ ‘ “$http_user_agent'' $http_x_forwarded_for'; access_log /data1/logs/access.log mylogformat buffer=32k;
(4)在 Nginx 0.7.4之后的版本中,access_log 指令中的日志文件路徑可以包含變量,例如:
access_log /data1/1ogs/$server_name.log combined;
假設 server_name 指令設置的虛擬主機名稱為 test.domain.com ,那么access_log 指令將把訪問日志記錄在/data1/logs/test.domain.com.log 文件中。 如果日志文件路徑中含有變量,將存在以下一些限制:
(1) Nginx 進程設置的用戶和組必須有對該路徑創建文件的權限。假設 Nginx 的 user 指令 設置的用戶名和用戶組都是 WWW ,而/data1/logs/ 目錄的用戶名和用戶組為 root ,日志文件/data1/logs/test.domain.com.log 將無法被 Nginx 創建:
(2)緩存將不會被使用;
(3)對於每一條日志記錄,日志文件都將先打開文件,再寫入日志記錄,然后馬上關閉。 為了提高包含變量的日志文件存放路徑的性能,需要使用 open_log_file_cache 指令設置經常被使用的日志文件描述符緩存。
open_log_file_cache 指令主要用來設置含有變量的日志路徑的文件描述符緩存,它的語法如下:
open_log_file_cache max=N [inactive=time] [mim_uses=N] [valid=time] | off
該指令默認是禁止的,等同於:
open_log_file_cache off;
open_log_file_cache 指令的各項參數說明如下:
max: 設置緩存中的最大文件描述符數量。如果超過設置的最大文件描述符數量,則采用 LRU (Least Recently Used) 算法清除"較不常使用的文件描述符"。 LRU (Least Recently Used) 算 法的基本概念是:當內存緩沖區剩余的可用空間不夠時,緩沖區盡可能地先保留使用者最常使用 的數據,將最近未使用的數據移出內存,騰出空間來加載另外的數據。
inactive: 設置一個時間,如果在設置的時間內沒有使用此文件描述符,則自動刪除此描述符。 此參數為可選參數,默認的時間為 10 秒鍾。
min_uses: 在參數 inactive 指定的時間范圍內,如果日志文件超過被使用的次數,則將該日 志文件的描述符記入緩存。默認次數為 1。
valid: 設置多長時間檢查一次,看一看變量指定的日志文件路徑與文件名是否仍然存在。默 認時間為 60秒。
off: 禁止使用緩存。
open_log_file_cache 指令的設置示例如下:
open_log_file_cache max=1000 inactive=20s min_uses=2 valid=1m;
查看日志命令
tail -f /usr/local/nginx/logs/access.log
打開nginx.conf配置文件去掉#注釋見下圖:
自定義某一個server配置的日志,使用“main”日志格式。
日志生成的到Nginx根目錄logs/access.log文件,默認使用“main”日志格式,也可以自定義格式。
重新讀取加載Nginx配置文件:
執行命令
./sbin/nginx -s reload
查看日志文件:
執行命令:
tail -100f /usr/local/nginx/logs/abc.access.log
四、Nginx日志切割
生產環境中的服務器,由於訪問日志文件增長速度非常快,日志太大會嚴重影響服務器效率。 同時,為了方便對日志進行分析計算,須要對日志文件進行定時切割.定時切割的方式有按月切 割、按天切割、按小時切割等。最常用的是按天切割。
所謂自動分割Nginx日志文件,就是指Rotate Nginx log files,即讓Nginx每天(或每個星期,可自定義控制)生成一個日志文件,而不是將Nginx所有的運行日志都放置在一個文件中,這樣每個日志文件都相對較小,定位問題也更容易。
比如Nginx產生的訪問日志文件默認一直就是一個,不會自動地進行切割,如果訪問量很大的話,將導致日志文件容量非常大,不便於管理。當然了,我們也不希望看到這么龐大的一個訪問日志文件,那需要手動對這個文件進行切割。
如何切割?
由於 Nginx 的日志都是寫在一個文件當中的,因此,我們需要每天零點將前一天的日志存為另外一個文件,這里我們就將 Nginx 位於 logs 目錄中的 access.log 存為 access_[yyyy-MM-dd].log 的文件。其實 logs 目錄中還有個 error.log 的錯誤日志文件,這個文件也需要每天切割一個,在這里就說 access.log 了,error.log 的切割方法類似。
在 Linux 平台上進行切割,需要使用 date 命令以獲得昨天的日期、使用 kill 命令向 Nginx 進程發送重新打開日志文件的信號,以及 crontab 設置執行任務周期。
crontab Linux計划任務詳情參閱這篇:Linux定時任務Crontab命令詳解
先創建一個 Shell 腳本,如下:
#!/bin/bash LOGS_PATH=/usr/local/nginx/logs YESTERDAY=$(date -d "yesterday" +%Y-%m-%d) mv ${LOGS_PATH}/sdk_acc.log ${LOGS_PATH}/sdk_acc_${YESTERDAY}.log mv ${LOGS_PATH}/sell_acc.log ${LOGS_PATH}/sell_acc_${YESTERDAY}.log kill -USR1 $(cat /usr/local/nginx/nginx.pid) ## 向 Nginx 主進程發送 USR1 信號。USR1 信號是重新打開日志文件
上面這個腳本中的最后一行必須向 Nginx 的進程發送 USR1 信號以重新打開日志文件,如果不寫的話,Nginx 會繼續將日志信息寫入 access_[yyyy-MM-dd].log 的那個文件中,這顯然是不正確的。
腳本完成后將其存入 Nginx 安裝目錄的 sbin 中,取名為 cut-log.sh,之后使用 crontab -e 新增一個定時任務,在其中增加執行這個腳本:
0 0 * * * /bin/bash /usr/local/nginx/sbin/cut-log.sh