nginx的日誌

nginx的日誌

nginx的日誌包括錯誤日誌和訪問日誌,分別使用不同的指令來定義其輸出位置和相應的級別。 下面介紹其各自的用途。

錯誤日誌

nginx提供了error_log指令來指定錯誤日誌的輸出文件和級別。 指令定義如下:
Syntax: error_log file [level];
Default:    
error_log logs/error.log error;
Context:    main, http, mail, stream, server, location

error_log的第一個參數,定義了輸出的文件名。另外還可以使用一些特殊的文件,可選值有:
  • stderr,向nginx進程的標準錯誤輸出流輸出日誌。
  • syslog,向syslog輸出日誌。配置樣例如下:
    error_log syslog:server=192.168.1.1 debug;
    
  • memory,向環形內存緩衝區寫出日誌,一般情況下僅在調試時纔會用到。配置樣例如下:
    error_log memory:32m debug;
    
    使用gdb的指令來查看內存中日誌的方法,如下
    set $log = ngx_cycle->log
    
    while $log->writer != ngx_log_memory_writer
        set $log = $log->next
    end
    
    set $buf = (ngx_log_memory_buf_t *) $log->wdata
    dump binary memory debug_log.txt $buf->start $buf->end
    
  • /dev/null,忽略錯誤日誌,相當於是關閉了錯誤日誌。

error_log指令的第二個參數,定義了輸出日誌的級別,默認值爲error。官方文檔對級別的定義比較簡單,如下說明來自於文章Configuring the Nginx Error Log and Access Log
  • debug – Useful debugging information to help determine where the problem lies.
  • info – Informational messages that aren’t necessary to read but may be good to know.
  • notice – Something normal happened that is worth noting.
  • warn – Something unexpected happened, however is not a cause for concern.
  • error – Something was unsuccessful.
  • crit – There are problems that need to be critically addressed.
  • alert – Prompt action is required.
  • emerg – The system is in an unusable state and requires immediate attention.
從上到下,嚴重程度逐漸變高。比如使用如下指令指定級別爲error時,
error_log logs/error.log error;
級別爲errorcritalertemerg的日誌將輸出到文件logs/error.log中。需要注意的是,在構建nginx時需要指定選項--with-debug,否則無法使用error_log來使debug生效,參見A debugging log

訪問日誌

nginx提供了access_log指令來實現訪問日誌的輸出文件和級別。官方文檔中給出的配置樣例
log_format compression '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" "$gzip_ratio"';

access_log /spool/logs/nginx-access.log compression buffer=32k;
關鍵指令有log_formataccess_log

log_format

指令定義如下:
Syntax: log_format name [escape=default|json] string ...;
Default:    
log_format combined "...";
Context:    http
使用log_format可以在配置文件中定義多個輸出格式,滿足不同場景下的access_log指令輸出日誌的需求。如下是log_format指令提供的日誌字段和說明,來自nginx日誌配置
  • $remote_addr和$http_x_forwarded_for,記錄客戶端IP地址。
  • $remote_user,記錄客戶端用戶名稱。
  • $request,記錄請求的URL和HTTP協議。
  • $status,記錄響應的狀態碼
  • $body_bytes_sent,發送給客戶端的字節數,不包括響應頭的大小;該變量與Apache模塊mod_log_config裏的“%B”參數兼容。
  • $bytes_sent,發送給客戶端的總字節數。
  • $connection,連接的序列號。
  • $connection_requests,當前通過一個連接獲得的請求數量。
  • $msec,日誌寫入時間。單位爲秒,精度是毫秒。
  • $pipe,如果請求是通過HTTP流水線(pipelined)發送,pipe值爲“p”,否則爲“.”。
  • $http_referer,記錄從哪個頁面鏈接訪問過來的。
  • $http_user_agent,記錄客戶端瀏覽器相關信息。
  • $request_length,請求的長度(包括請求行,請求頭和請求正文)。
  • $request_time,請求處理時間,單位爲秒,精度毫秒。從讀入客戶端的第一個字節開始,直到把最後一個字符發送給客戶端後進行日誌寫入爲止。
  • $time_iso8601,ISO8601標準格式下的本地時間。
  • $time_local,通用日誌格式下的本地時間。
定位性能問題時比較有用的幾個字段,如下
  • $upstream_connect_time,與upstream服務器建立鏈接時所花費的時間。
  • $upstream_header_time,與upstream服務器,從建立鏈接開始到收到響應消息的http頭部的第一個字節時所花費的時間。
  • $upstream_response_time,與upstream服務器,從建立鏈接到接收到響應的最後一個字節時所花費的時間。
  • $request_time,從接收到客戶請求的第一個字節到返回給客戶響應的最後一個字節發出時,所花費的時間。

access_log

指令定義如下
Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
Default:    
access_log logs/access.log combined;
Context:    http, server, location, if in location, limit_except
指令的參數說明:
  • path,日誌文件的全路徑名。與error_log相同,access_log指令也允許將日誌輸出到syslog輸出日誌,配置方法與error_log相同。
  • format,日誌的格式,使用log_format指令指定。
  • buffer,內存中緩存日誌的大小,適當的取值可以改善日誌輸出操作的效率。
  • gzip,日誌數據的壓縮級別。
  • flush,日誌保存在緩存區中的最長時間,配合使用buffer,可以改善日誌輸出操作的效率。
配置樣例
# 關閉日誌。
access_log off;
# 日誌記錄至logs/access.log中,格式爲combined。
access_log logs/access.log combined;

# 日誌記錄至logs/access.log,內存中緩存至多64k日誌,每隔10s將日誌刷新到文件中。
access_log logs/access.log buffer=64k flush=10s;

其它指令

open_log_file_cache

指令定義如下
Syntax: open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
Default:    
open_log_file_cache off;
Context:    http, server, location
指令的參數說明:
  • max,設置緩存中的最大文件描述符數量,當緩存中的文件句柄的數量超出本值,則採用LRU算法選擇需要清理的文件句柄。
  • inactive,設置存活時間,當文件句柄在指定時間內沒有日誌寫出,則關閉該文件句柄。默認是10s。
  • min_uses,在inactive指定的時間段內,文件句柄至少使用的次數,否則會被關閉。默認是1次。
  • valid,檢查文件句柄關聯的日誌文件是否存在的時間間隔。默認60s。
  • off,關閉緩存。
配置樣例
open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;

log_not_found

指令定義如下
Syntax: log_not_found on | off;
Default:    
log_not_found on;
Context:    http, server, location
是否在error_log中記錄被訪問URL不存在的錯誤。默認值爲on,表示記錄相關信息。

log_subrequest

指令定義如下
Syntax: log_subrequest on | off;
Default:    
log_subrequest off;
Context:    http, server, location
是否在access_log中記錄子請求的訪問日誌。默認值爲off,表示不記錄相關信息。

rewrite_log

指令定義如下
Syntax: rewrite_log on | off;
Default:    
rewrite_log off;
Context:    http, server, location, if
用來控制nginx執行URL重寫操作的處理日誌是否寫出到文件中;在調試重寫規則時,建議開啓日誌。當啓用後,將以notice級別來記錄URL重寫操作相關的日誌。

如何管理nginx輸出的日誌

爲避免應用輸出的日誌過多、過大,導致硬盤滿而影響應用、硬件的穩定性,需要對日誌文件進行管理。而通常情況下采取的策略有:
  • 文件繞接,控制文件的數量,避免文件無限制生成。
  • 按天切換,控制文件的生成規則,避免單個文件中記錄的數量過多,同時便於管理。
  • 按大小切換,控制文件的大小,避免單個文件中記錄的數量過多,同時便於管理。
  • 。。。
從官方文檔以及衆網友的分享看,nginx並沒有對日誌文件的管理提供原生的支持。但仍然可以找到一些方法來解決nginx日誌管理的問題。

原生方法

nginx的開發者提供了一種簡單、粗暴的方式來實現日誌文件的切換。來自官網的一篇文章Log Rotation介紹了這種方法,核心腳本如下:
mv access.log access.log.0
kill -USR1 `cat master.nginx.pid`
sleep 1
# do something with access.log.0
gzip access.log.0
nginx開發人員對上述方法的解釋:
  • How it works
    The rotator should send the -USR1 signal to the master process. The master process reopens files, does chown() and chmod() to enable the worker processes to write to files, and send a notification to the worker procesess. They reopen files instantly. If the rotator sends the -HUP signal, then them master does a reconfiguration and starts a new worker processes those write to the new log files, but the old shuting down worker processes still uses the old log files.
  • Another explanation
    When master process receives -USR1 it repopens all logs, does chown() and chmod() (to allow unpriviliged worker processes to reopen them), and notifies workers about reopening. Then the workers reopens its logs too. So the old logs are available to gzip right away - you will not lose any line.

使用logrotate

在網上簡單搜索,發現使用logrotate也是一個不錯的選擇,網上可以找到相當數量的介紹文章。此處不再贅述使用方法和原理。

如何利用nginx的日誌

如下是截取自純手工玩轉 Nginx 日誌的一些例子。給定access_log日誌的格式如下
log_format myformat '$remote_addr^A$http_x_forwarded_for^A$host^A$time_local^A$status^A'
'$request_time^A$request_length^A$bytes_sent^A$http_referer^A$request^A$http_user_agent';
利用awk命令,可以快速得到如下的數據。
  • 查找訪問頻率最高的URL,以及相應的訪問次數:
    cat access.log | awk -F '^A' '{print $10}' | sort | uniq -c
    
  • 查找當前日誌文件中500錯誤的訪問:
    cat access.log | awk -F '^A' '{if($5 == 500) print $0}'
    
  • 查找當前日誌文件 500 錯誤的數量:
    cat access.log | awk -F '^A' '{if($5 == 500) print $0}' | wc -l
    
  • 查找某一分鐘內 500 錯誤訪問的數量:
    cat access.log | awk -F '^A' '{if($5 == 500) print $0}' | grep '09:00' | wc-l
    
  • 查找耗時超過 1s 的慢請求:
    tail -f access.log | awk -F '^A' '{if($6>1) print $0}'
    
  • 假如只想查看某些字段的值:
    tail -f access.log | awk -F '^A' '{if($6>1) print $3"|"$4}'
    
  • 查找 502 錯誤最多的 URL:
    cat access.log | awk -F '^A' '{if($5==502) print $11}' | sort | uniq -c
    
  • 查找 200 空白頁
    cat access.log | awk -F '^A' '{if($5==200 && $8 < 100) print $3"|"$4"|"$11"|"$6}'
    
  • 查看實時日誌數據流
    tail -f access.log | cat -e
    
    或者
    tail -f access.log | tr '^A' '|'
    
AWK的深入使用方法,請參考The GNU Awk User’s Guide

參考資料



查看原文:http://www.jackieathome.net/archives/431.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章