### 日志規范
[TOC]
#### 前言
> 良好的日志書寫使用將為開發和運維提供便利;良好的日志級別定義和配置,在為快速定位問題的前提上,將可以有效地提升性能。
根據約束力強弱及故障敏感性,規約依次分為[強制]、[推薦]、[參考]三大類。
對于規約條目的延伸信息中,"說明"對內容做了引申和解釋;
"[正例]"提倡什么樣的編碼和實現方式;
"[反例]"說明需要提防的雷區,以及真實的錯誤案例。
#### 工具組件選用
PHP
[推薦]使用SeasLog作為日志記錄工具。
較Log4php,MonoLog而言,具有更好的性能和使用便捷性。
[參考] http://pecl.php.net/package/seaslog
JAVA
[推薦]使用log4j2作為日志記錄工具。
較log4j,logback而言,log4j2的異步模式具有更好的性能。
[參考]http://logging.apache.org/log4j/2.x/manual/async.html#AllAsync
#### 目錄名稱
##### 根目錄
[強制]日志根目錄通過日志組件配置決定。
[強制]不允許將日志根目錄寫死位置。
##### 日志目錄
[強制]通過配置或程序中定義Logger指定日志分級目錄。
[推薦]每一個Logger代表一個具體的應用邏輯層,為每一個Logger,在根目錄中分配一個日志分目錄。
[正例]根目錄 /data/logs/tsb/
* 用戶邏輯分級目錄 /data/logs/tsb/user
* 移動邏輯分級目錄 /data/logs/tsb/mobile
#### 級別定義
定義
相較于PHP與Java各自規范不同,我們統一為8個級別,其中包括強制級別和推薦級別。
[強制]DEBUG
debug信息、細粒度信息事件
如:調試信息
[強制]INFO
重要事件、強調應用程序的運行過程
如:用戶登錄的SQL信息、創建任務時的執行過程
[推薦]NOTICE
一般重要性事件、執行過程中較INFO級別更為重要的信息
如:調用外部API時的過程日志
[強制]WARNING / WARN
出現了非錯誤性的異常信息、潛在異常信息、需要關注并且需要修復
如:調用了已經被棄用的API、用戶請求參數中包含了非法字符但經過處理無害
[強制]ERROR
運行時出現的錯誤、不必要立即進行修復、不影響整個邏輯的運行、需要記錄并做檢測
如:調用預期存在的Cache出現未命中進而查詢DB、調用某首選API不通進而調用候選API
[強制]CRITICAL / FATAL
緊急情況、需要立刻進行修復、程序組件不可用
如:程序組件異常退出、用戶注冊邏輯不能發送郵件
[推薦]ALERT
必級立即采取行動的緊急事件、需要立即通知相關人員緊急修復
如:整個網站垮掉、DB/Cache無法連接
[推薦]EMERGENCY
系統不可用
如:磁盤不可寫
#### 配置
> [強制]通過配置決定輸出某級別以上的日志信息。
[正例]在php.ini或SeasLog.ini中設置seaslog.level值,控制只輸出日志級別INFO以上級別的信息。
[參考] SeasLog 配置
[正例]在 log4j.configurationFile 指定的配置文件中,為log4j2設置Logger Level,控制只輸出日志級別INFO以上級別的信息。
[參考] Log4j2 配置
#### 日志文件
##### 文件命名
[強制]以 " {日期} {文件名分隔符} [{級別}] . log " 格式命名
[強制]{日期}格式可選范圍:yyyymmdd (年月日) , yyyymmddhh (年月日時)
[推薦]{文件名分隔符}使用:點
[參考]{文件名分隔符} 可選范圍:中劃線,下劃線,點
[正例]/data/logs/tsb/user/20170913.INFO.log
[正例]/data/logs/tsb/user/2017091314.ERROR.log
#### 日志輸出
[強制]不同級別日志通過配置分開輸出。
[推薦]對于不能通過配置作出分級別輸出的工具組件,應將ERROR以上級別單獨輸出。
#### 內容格式
##### 日志內容
[強制]簡明扼要,無冗余
[強制]關鍵業務必須可通過日志回溯請求,并定義明確的日志級別
[強制]異常與錯誤必須記錄日志,并定義明確的日志級別
[強制]不允許將已捕獲的異常棧隨意丟進日志,應給出明確的級別和語義描述
[強制]每一條日志內容必須包括且不限于以下內容:時間、進程ID、日志級別、日志內容。
##### 日志格式
[強制]每一條日志記錄為一行
[推薦]對于日志內容中有換行操作的,應計劃處理為一行,否則日志收集之后將出現不可查看或分析問題
[強制]單條日志內容格式為
{時間點} {日志分隔符} {級別} {日志分隔符} {進程ID} {日志分隔符} [{線程名}] {日志分隔符} {日志內容}
[強制]{時間點} 格式為:yyyy-MM-dd hh:mm:ss[.SSS] (年-月-日 小時:分鐘:秒[.毫秒])
[推薦]{日志分隔符} 使用:豎線
[參考]{日志分隔符} 可選范圍:豎線,空格
[正例]2017-09-13 19:35:54 | ERROR | 26922 | api error /api/getuserinfo 404
[正例]2017-09-13 19:35:54 ERROR 26922 api error /api/getuserinfo 404
* * * * *
https://github.com/SeasX/SeasLog/blob/master/Specification/README_zh.md