本文目錄:1.1 錯誤日誌ErrorLog1.2 訪問日誌CustomLog1.3 日誌輪替:rotatelogs工具1.4 日誌輪替:cronolog工具1.5 rotatelogs和cronolog的比較 需要記錄的日誌類型有:錯誤日誌ErrorLog、訪問日誌CustomLog。錯誤日誌一般採 ...
本文目錄:
1.1 錯誤日誌ErrorLog
1.2 訪問日誌CustomLog
1.3 日誌輪替:rotatelogs工具
1.4 日誌輪替:cronolog工具
1.5 rotatelogs和cronolog的比較
需要記錄的日誌類型有:錯誤日誌ErrorLog、訪問日誌CustomLog。錯誤日誌一般採用預設即可,最多改下錯誤日誌的存放路徑,而CustomLog因為量比較多,很可能需要定製。事實上,ErrorLog由httpd的核心模塊提供,而CustomLog卻提供了專門的模塊mod_log_config來處理,該模塊還支持TransferLog指令,該指令和CustomLog作用和用法基本類似,如有需要可查官方手冊,本文略過。
最後介紹兩種日誌輪替工具:apache httpd自帶的rotatelogs工具和cronolog工具。
1.1 錯誤日誌ErrorLog
錯誤日誌的級別LogLevel:debug, info, notice, warn(預設), error, crit, alert, emerg。
錯誤日誌的定義語法:
ErrorLog file-path|syslog[:[facility][:tag]]
如果使用syslog替換file-path,則表示採用系統自帶的syslog日誌工具,facility是記錄syslog日誌的設施類型。一般來說,不會採用這種方法記錄日誌。
如果採用file-path,則有兩種方式:直接指定文件路徑;前面使用管道,表示將輸出的日誌作為標準輸入傳遞給管道後的日誌處理程式,例如傳遞給apache自帶的rotatelogs工具。例如:
ErrorLog "logs/error_log"
ErrorLog "|/usr/local/apache/bin/rotatelogs /var/log/error_log 86400" common
當然,對於ErrorLog來說,數據量並不會太多,一般直接使用文件記錄即可。對於CustomLog,則可以考慮使用日誌切割工具進行分割、輪替等行為。
錯誤日誌的記錄格式由ErrorLogFormat指令控制,例如以下是worker和event模式下錯誤日誌的預設記錄格式,其中各參數代表的意義見官方手冊ErrorLogFormat。
ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ %a] %M% ,\ referer\ %{Referer}i"
1.2 訪問日誌CustomLog
使用CustomLog指令指定訪問日誌記錄的位置,可以在同一個host下多次使用該指令表示同一條日誌記錄到多個位置。語法格式為:
CustomLog file|pipe format|nickname [env=[!]environment-variable| expr=expression]
使用LogFormat可以指定日誌記錄的事項,例如是否要記錄客戶端IP地址,是否要記錄請求方法等。使用LogFormat還可以定義日誌分類(在httpd術語中稱為nickname),例如common類、combined類、combinedio類。它支持非常彈性化的記錄事項,具體的見官方手冊LogFormat。
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
<IfModule logio_module>
# You need to enable mod_logio.c to use %I and %O
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
</IfModule>
然後使用CustomLog指令就可以使用已經定義的日誌類。例如:
CustomLog "logs/access_log" combined
當然,使用LogFormat定義分類只是為了方便,CustomLog指令完全可以不使用nickname而是直接定義要記錄的事項。例如:
CustomLog "logs/access_log" "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
如果提供CustomLog的第三個參數,即env或者expr,則表示滿足條件的請求才會記錄日誌。例如,當請求的是gif文件時將獨立記錄該日誌,而其他請求則記錄在另一個日誌中。
SetEnvIf Request_URI \.gif$ gif-image
CustomLog "gif-requests.log" common env=gif-image
CustomLog "nongif-requests.log" common env=!gif-image
通常來說,除了特殊需求,一般都只需使用LogFormat提供的各個事項即可。否則日誌訂製就是一件非常噁心且複雜的事情。
1.3 日誌輪替:rotatelogs工具
首先說明rotatelogs工具,它是apache httpd提供的一個基於時間間隔、大小切分日誌的簡單工具。
預設,它在啟動時不會立即創建日誌文件,而是在有請求到達時才會創建。同理在輪替時也如此,如果到達了輪替的時間間隔,如果沒有新請求到達,則暫時不會創建新的日誌文件。如果使用"-f"選項,則在啟動時,不管是否有沒有請求,都立即創建日誌文件。如果使用"-c"選項,則在每次輪替時無論是否有新請求到達,都創建新日誌文件。
rotatelogs [ -l ] [ -f ] [ -t ] [ -v ] [ -e ] [ -c ] [ -n number-of-files ] logfile rotationtime|filesize(B|K|M|G)
選項說明:
logfile
:指定日誌記錄路徑。可以加上一些修飾符,例如時間類的a.log_%Y.%m.%d將在a.log後追加年、月、日的尾碼,如果沒有給定任何尾碼修飾,則自動加上".nnnnnnnn",表示創建時的時間點換算成距離1970-01-01 00:00:00的總秒數,也就是"date +%s",每次輪替時也會加上該尾碼。如果使用相對路徑,則相對於ServerRoot。-n
:使用數字作為尾碼,且表示輪替的迴圈列表,例如"-n 3"表示一直在log.1、log.2、log.3這三個文件中記錄,不會再創建任何新的日誌文件。rotationtime
:指定輪替的時間間隔。將初始化為對應時間格式的起始值。例如,設置為3600時,將表示在每個小時的開頭進行輪替,儘管當前時間點進入下一個小時可能只有5分鐘,在5分鐘之後也會進行一次輪替。filesize
:以大小方式輪替日誌。-l
:使用本地時間計算時間間隔。預設使用的是UTC時間。-f
:強制立即打開日誌文件。因為有些時候在啟動httpd時,可能一小段時間內沒有任何請求到達,因為沒有日誌需要記錄,所以暫時不會創建日誌文件。使用該選項可立即創建文件。-t
:截斷日誌而不再是輪替日誌。這種情況下,不會再添加任何文件尾碼。-v
:詳細記錄輪替或截斷時的信息。-e
:將日誌也輸出到標準錯誤輸出中。當日誌還需要被其他工具處理時,該選項有用。-c
:每個時間間隔到了都創建新文件,儘管沒有日誌到達。而預設的情況下,在輪替時間間隔到達時,如果沒有日誌到達,將暫時不會創建日誌,而是等待第一個請求到達後才創建。
關於更多的時間類修飾符,見下文。
註意,如果出現了輪替時文件名重覆的情況,例如按照5M大小進行輪替,但文件名的格式為"a.log_%Y.%m.%d",如果同一天內出現了多次輪替,由於文件名相同,則會覆蓋舊文件進行記錄。
另外,rotatelogs只能對日誌文件名本身使用時間類修飾符,無法將其設置在目錄上,否則啟動httpd時會因為無法打開日誌而報錯。
示例:以下使用了日誌管道"|",表示記錄的日誌傳遞給後面的程式(此處為rotatelogs)進行處理。
每天輪替一次$ServerRoot/logs/mylog.nnnnnnnn,其中nnnnnnnn是當前時間換算成秒的數值。且在啟動時不立即創建日誌文件,輪替時也不立即創建新日誌文件。
CustomLog "|/usr/local/apache/bin/rotatelogs logs/mylog 86400" common
按照文件大小輪替。
CustomLog "|bin/rotatelogs /var/log/logfile 5M" common
輪替錯誤日誌,達到5M時就輪替。
ErrorLog "|bin/rotatelogs /var/log/errorlog.%Y-%m-%d-%H_%M_%S 5M"
截斷日誌而非輪替日誌。
CustomLog "|bin/rotatelogs -t /var/log/logfile 86400" common
以下是日期類的修飾符。下麵的cronolog工具也採用這同一套修飾符。
% %字元
n 換行
t 水平製表符
時間類:
H 小時(00..23)
I 小時(01..12)
p 該locale下的AM或PM標識
M 分鐘(00..59)
S 秒 (00..61, which allows for leap seconds)
X 該locale下時間表示符(e.g.: "15:12:47")
Z 時區。若時區不能確定,則無意義
日期類:
a 該locale下的工作日簡名(e.g.: Sun..Sat)
A 該locale下的工作日全名(e.g.: Sunday .. Satur-ay)
b 該locale下的月份簡稱(e.g.: Jan .. Dec)
B 該locale下的月份全稱(e.g.: January .. December)
c 該locale下的日期和時間(e.g.: "Sun Dec 15 14:12:47 GMT 1996")
d 當月中的天數 (01 .. 31)
j 當年中的天數 (001 .. 366)
m 月數 (01 .. 12)
U 當年中的星期數,以周日作為一周開始,其中第一周為首個含星期天的星期(00..53)
W 當年中的星期數,以星期一作為一周的開始,其中第一周為首個含星期天的星期(00..53)
w 工作日數(0 .. 6, 0表示星期天)
x 該locale下的日期表示(e.g. "13/04/97")
y 兩位數的年份(00 .. 99)
Y 四位數的年份(1970 .. 2038)
1.4 日誌輪替:cronolog工具
可以在epel源中下載,或者從其github上安裝:https://github.com/fordmason/cronolog。
[root@xuexi ~]# cronolog -h
usage: cronolog [OPTIONS] logfile-spec
-H NAME, --hardlink=NAME maintain a hard link from NAME to current log
-S NAME, --symlink=NAME maintain a symbolic link from NAME to current log
-P NAME, --prev-symlink=NAME maintain a symbolic link from NAME to previous log
-l NAME, --link=NAME same as -S/--symlink
-h, --help print this help, then exit
-p PERIOD, --period=PERIOD set the rotation period explicitly
-d DELAY, --delay=DELAY set the rotation period delay
-o, --once-only create single output log from template (not rotated)
-x FILE, --debug=FILE write debug messages to FILE
( or to standard error if FILE is "-")
-a, --american American date formats
-e, --european European date formats (default)
-s, --start-time=TIME starting time
-z TZ, --time-zone=TZ use TZ for timezone
-V, --version print version number, then exit
這個工具的使用非常簡單,但必須得搞懂它的輪替原理。以下麵設置為例:
CustomLog "|/usr/local/sbin/cronolog logs/%Y/%m/%d/access.log" combined
由於使用的是相對路徑,所以它相對於ServerRoot。假設ServerRoot為/usr/local/apache,則這裡的日誌將創建在/usr/local/apache/logs/%Y/%m/%d/access.log,其中%Y、%m、%d分別表示的是年、月、日。這些修飾符組成的文件名或目錄被稱為模板。
cronolog的輪替原理是:根據當前日誌文件模板的時間點,和當前時間進行比較,如果模板中的某個部分和當前時間點的不同,則需要進行輪替,輪替時會自動創建缺失的目錄,並且計算下一次進行輪替的時間點。在輪替時,先關閉當前日誌文件,再根據當前時間點創建新日誌文件,並打開新日誌文件。但註意,cronolog工具在創建或輪替時,如果沒有請求到達,則不會立即創建日誌文件,這和rotatelogs工具的預設情況是一樣的。
看上去很簡單,確實很簡單,它只需要根據指定的時間修飾符和當前時間點進行比較就可以了。例如上面的配置,如果當前時間點為2017-10-01,則按照以下順序進行創建,註意,只有在請求到達時才會創建,沒有請求時是不會創建的。
- Period 1:在第一個請求到達時創建
- logs/2017目錄是否存在,不存在則創建。
- logs/2017/10目錄是否存在,不存在則創建。
- logs/2017/10/01目錄是否存在,不存在則創建。
- 創建logs/2017/10/01/access.log文件,並寫日誌。
- Period 2:在2017-10-02凌晨第一個請求到達時創建
- logs/2017目錄已存在,不創建。
- logs/2017/10目錄已存在,不創建。
- logs/2017/10/02目錄不存在,創建。
- 創建logs/2017/10/02/access.log文件,並寫日誌。
之後將繼續按照此規則不斷進行下去。
也就是說,cronolog預設將按照最小單位的時間修飾符為輪替時間間隔。例如,最小單位為%d時,將按照天輪替,最小單位為%W將按周輪替,最小單位為%S,將按秒輪替。但仍然需要說明的是,只有請求到達時,才會按照當前時間點創建新的日誌文件。例如,如果按秒輪替,第10秒時創建了一個文件10.log,第11秒將關閉該日誌文件,但是不會立即創建新日誌文件,假設在第15秒時新的請求到達,則創建一個15.log,而不是11.log。
此外,cronolog可使用"-p N UNITs"選項顯式指定輪替時間間隔,有效單位UNITs為:seconds,minutes,hours,days,weeks和months。例如"-p 5 minutes"表示每5分鐘輪替一次。但需要註意,N的值必須為更高一級UNITs的公因數(不包括最大公因數),例如小時的長度為60分鐘,在指定minutes單位時,可以指定"1,2,3,4,5,6,10,15,20,30 minutes",但不能指定為"7,9,11,12,13,14"等minutes。
如果不想輪替,有兩種方法:不要使用時間類的修飾符;使用"-o"選項。這時候會一直寫同一個文件。
cronolog還支持動態符號鏈接功能,例如下麵的配置,這樣就使得每次訪問/usr/local/apache/logs/access_log都能訪問到最新的日誌文件。
CustomLog "|/path/to/cronolog --symlink=/usr/local/apache/logs/access_log /usr/local/apache/logs/%Y/%m/access_log" combined
最後,cronolog不支持日誌截斷。
1.5 rotatelogs和cronolog的比較
這兩個工具各有優缺點。
- 在日誌文件路徑上:rotatelogs無法將時間類修飾符作為目錄,只能使用在日誌文件名上。而cronolog可以。例如logs/%Y%m/%d/access.log。
- 在日誌控制力度上:rotatelogs對日誌的控制力更強,它可以控制啟動時、輪替時是否立即創建日誌文件。而cronolog僅只能在有新請求到達時才創建日誌文件。
- 在特性上:rotatelogs更豐富一些,它支持日誌截斷,支持在一定數量內迴圈輪替。而cronolog只能輪替,且只能按照時間不斷向後輪替。
- 在日誌訪問方便性上:cronolog通過它的動態符號鏈接功能使得這一點比rotatelogs方便的多。
其實這些都是小問題。