原文鏈接:https://blog.csdn.net/zhao0829wang/article/details/47166381
一、配置文件
TP通過配置文件對日誌進行設置.要開啓日誌記錄,必須在配置中開啓LOG_RECORD參數,以及可以在項目配置文件中配置需要記錄的日誌級別
'LOG_RECORD' => true, // 進行日誌記錄
'LOG_EXCEPTION_RECORD' => true, // 是否記錄異常信息日誌
'LOG_LEVEL' => 'EMERG,ALERT,CRIT,ERR,WARN,NOTIC,INFO,DEBUG,SQL', // 允許記錄的日誌級別
EMERG 嚴重錯誤,導致系統崩潰無法使用
ALERT 警戒性錯誤, 必須被立即修改的錯誤
CRIT 臨界值錯誤, 超過臨界值的錯誤
ERR 一般性錯誤
WARN 警告性錯誤, 需要發出警告的錯誤
NOTICE 通知,程序可以運行但是還不夠完美的錯誤
INFO 信息,程序輸出信息
DEBUG 調試,用於調試信息
SQL SQL語句,該級別只在調試模式開啓時有效
根據TP的define(‘APP_DEBUG’,false)的設置不同,TP會讀取不同的配置文件,
TP默認對debug模式設置瞭如下Log輸出,文件位置爲ThinkPhp/Conf/debug.php.
無論你項目config.php怎麼配置LOG,都會是以下Level=EMERG,ALERT,CRIT,ERR,WARN,NOTIC,INFO,DEBUG,SQL.即默認輸出所有Log。
```
return array(
'LOG_RECORD' => true, // 進行日誌記錄
'LOG_EXCEPTION_RECORD' => true, // 是否記錄異常信息日誌
'LOG_LEVEL' => 'EMERG,ALERT,CRIT,ERR,WARN,NOTIC,INFO,DEBUG,SQL', // 允許記錄的日誌級別
'DB_FIELDS_CACHE' => false, // 字段緩存信息
'DB_SQL_LOG' => true, // 記錄SQL信息
'APP_FILE_CASE' => true, // 是否檢查文件的大小寫 對Windows平臺有效
'TMPL_CACHE_ON' => false, // 是否開啓模板編譯緩存,設爲false則每次都會重新編譯
'TMPL_STRIP_SPACE' => false, // 是否去除模板文件裏面的html空格與換行
'SHOW_ERROR_MSG' => true, // 顯示錯誤信息
);
```
此時如果想要使用自己的配置,需要在項目目錄下添加/Conf/debug.php進行配置
當Debug=false時,纔會讀取config.php的Log配置,即此時config.php配置纔會生效.
二、核心類TP/Lib/Core/Log.class.php
Tp的日誌輸出核心類爲 TP/Lib/Core/Log.class.php.
參照源碼和文檔看,得出以下結論。
1>. TP框架一般使用的record+save
2>. TP框架有兩種記錄日誌的方式:write,record+save
3>. write寫入日誌是不受Log配置文件控制的,無論你怎麼設置,都會輸出寫入文件.
4>. 所以怎麼使用要視自己的需求選擇
開發調試輸出日誌
use Think\Log;
然後Log:record()
或者直接\Think\Log:record()
通常日誌文件的寫入是自動完成的,如果我們需要在開發的過程中手動記錄日誌信息,可以使用Log類的方法來操作。日誌文件的寫入有兩種方法:
一、使用Log::write 方法
Log::write 直接寫入日誌
用法 Log::write($message,$level=self::ERR,$type='',$destination='',$extra='')
參數
message(必須):要記錄的日誌信息,字符串
level(可選):要記錄的日誌級別,默認爲ERR 錯誤
type(可選):日誌記錄方式,默認爲空取LOG_TYPE配置
destination(可選):日誌記錄目標,默認爲空自動生成或LOG_DEST配置
extra(可選):日誌記錄額外參數,默認爲空取LOG_EXTRA配置
返回值 無
使用示例:
Log::write('調試的SQL:'.$SQL, Log::SQL);
表示用默認的日誌記錄方式記錄調試SQL信息
二、使用Log::record和 Log::save方法
用法 Log::record($message,$level=self::ERR,$record=false)
Log::record記錄日誌
用法 Log::record($message,$level=self::ERR,$record=false)
參數
message(必須):要記錄的日誌信息,字符串
level(可選):要記錄的日誌級別,默認爲ERR 錯誤
record(可選):是否強制記錄,默認爲false表示判斷LOG_LEVEL配置
返回值 無
Log::record方法必須結合Log::save方法才能完成日誌記錄,因爲record方法只是把日誌信息保存到內存,並沒有真正寫入日誌,直到調用Log::save方法。
Log::save 保存記錄的日誌
用法 Log::save($type='',$destination='',$extra='')
參數
type(可選):日誌記錄方式,默認爲空取LOG_TYPE配置
destination(可選):日誌記錄目標,默認爲空自動生成或LOG_DEST配置
extra(可選):日誌記錄額外參數,默認爲空取LOG_EXTRA配置
使用示例:
Log::record('測試調試錯誤信息', Log::DEBUG);
Log::record('調試的SQL:'.$SQL, Log::SQL);
Log::save();
參考源碼爲:
/**
* 日誌處理類
* @category Think
* @package Think
* @subpackage Core
* @author liu21st <[email protected]>
*/
class Log
{
// 日誌級別 從上到下,由低到高
const EMERG = 'EMERG'; // 嚴重錯誤: 導致系統崩潰無法使用
const ALERT = 'ALERT'; // 警戒性錯誤: 必須被立即修改的錯誤
const CRIT = 'CRIT'; // 臨界值錯誤: 超過臨界值的錯誤,例如一天24小時,而輸入的是25小時這樣
const ERR = 'ERR'; // 一般錯誤: 一般性錯誤
const WARN = 'WARN'; // 警告性錯誤: 需要發出警告的錯誤
const NOTICE = 'NOTIC'; // 通知: 程序可以運行但是還不夠完美的錯誤
const INFO = 'INFO'; // 信息: 程序輸出信息
const DEBUG = 'DEBUG'; // 調試: 調試信息
const SQL = 'SQL'; // SQL:SQL語句 注意只在調試模式開啓時有效
// 日誌記錄方式
const SYSTEM = 0;
const MAIL = 1;
const FILE = 3;
const SAPI = 4;
// 日誌信息
static $log = array();
// 日期格式
static $format = '[ c ]';
/**
* 記錄日誌 並且會過濾未經設置的級別
* @static
* @access public
* @param string $message 日誌信息
* @param string $level 日誌級別
* @param boolean $record 是否強制記錄
* @return void
*/
static function record($message, $level = self::ERR, $record = false)
{
if ($record || false !== strpos(C('LOG_LEVEL'), $level)) {
self::$log[] = "{$level}: {$message}\r\n";
}
}
/**
* 日誌保存
* @static
* @access public
* @param integer $type 日誌記錄方式
* @param string $destination 寫入目標
* @param string $extra 額外參數
* @return void
*/
static function save($type = '', $destination = '', $extra = '')
{
if (empty(self::$log)) return;
$type = $type ? $type : C('LOG_TYPE');
if (self::FILE == $type) { // 文件方式記錄日誌信息
if (empty($destination))
$destination = C('LOG_PATH') . date('y_m_d') . '.log';
//檢測日誌文件大小,超過配置大小則備份日誌文件重新生成
if (is_file($destination) && floor(C('LOG_FILE_SIZE')) <= filesize($destination))
rename($destination, dirname($destination) . '/' . time() . '-' . basename($destination));
} else {
$destination = $destination ? $destination : C('LOG_DEST');
$extra = $extra ? $extra : C('LOG_EXTRA');
}
$now = date(self::$format);
error_log($now . ' ' . get_client_ip() . ' ' . $_SERVER['REQUEST_URI'] . "\r\n" . implode('', self::$log) . "\r\n", $type, $destination, $extra);
// 保存後清空日誌緩存
self::$log = array();
//clearstatcache();
}
/**
* 日誌直接寫入
* @static
* @access public
* @param string $message 日誌信息
* @param string $level 日誌級別
* @param integer $type 日誌記錄方式
* @param string $destination 寫入目標
* @param string $extra 額外參數
* @return void
*/
static function write($message,$level=self::ERR,$type='',$destination='',$extra='') {
$now = date(self::$format);
$type = $type?$type:C('LOG_TYPE');
if(self::FILE == $type) { // 文件方式記錄日誌
if(empty($destination))
$destination = C('LOG_PATH').date('y_m_d').'.log';
//檢測日誌文件大小,超過配置大小則備份日誌文件重新生成
if(is_file($destination) && floor(C('LOG_FILE_SIZE')) <= filesize($destination) )
rename($destination,dirname($destination).'/'.time().'-'.basename($destination));
}else{
$destination = $destination?$destination:C('LOG_DEST');
$extra = $extra?$extra:C('LOG_EXTRA');
}
error_log("{$now} {$level}: {$message}\r\n", $type,$destination,$extra );
//clearstatcache();
}
}