日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

thinkphp mysql 日志_基于thinkphp实现异常日志详细统计功能

發(fā)布時(shí)間:2024/3/12 数据库 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 thinkphp mysql 日志_基于thinkphp实现异常日志详细统计功能 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

后端的代碼基于thinkphp框架開(kāi)發(fā),隨著業(yè)務(wù)的增加,代碼復(fù)雜度不斷增多,而且有好幾份代碼,可能部署在不同的服務(wù)器上。即使在測(cè)試服務(wù)器上經(jīng)過(guò)嚴(yán)格測(cè)試,正式環(huán)境有時(shí)也很難避免出現(xiàn)bug,所以需要較為詳細(xì)的日志來(lái)記錄,而且日志要有統(tǒng)一的位置存放。

1.thinkphp本身的異常處理

稍微熟悉thinkphp的都應(yīng)該知道,它的異常可以自己定義,只要自定定一個(gè)handle類,繼承think\exception\handle,然后重寫(xiě)里面的render方法,然后在配置文件配置自己定義的異常處理類,就可以根據(jù)業(yè)務(wù)場(chǎng)景的不同,以不同的形式輸出異常信息,比如json、html。所以一個(gè)工程中是存在多個(gè)think\exception\handle的子類的。對(duì)應(yīng)異常信息的記錄,其實(shí)tp本身是有記錄的。

think\Error類異常處理的代碼如下。

/**

* Exception Handler

* @access public

* @param \Exception|\Throwable $e

*/

public static function appException($e)

{

if (!$e instanceof \Exception) {

$e = new ThrowableError($e);

}

self::getExceptionHandler()->report($e);

if (PHP_SAPI == 'cli') {

self::getExceptionHandler()->renderForConsole(new ConsoleOutput, $e);

} else {

self::getExceptionHandler()->render($e)->send();

}

}

public static function appError($errno, $errstr, $errfile = '', $errline = 0)

{

$exception = new ErrorException($errno, $errstr, $errfile, $errline);

if (error_reporting() & $errno) {

// 將錯(cuò)誤信息托管至 think\exception\ErrorException

throw $exception;

}

self::getExceptionHandler()->report($exception);

}

其中self::getException()就是根據(jù)配置獲取處理異常的handle實(shí)例,然后調(diào)用了該實(shí)例的report方法。所以report方法是所有異常必經(jīng)之路。經(jīng)過(guò)report處理以后,才會(huì)根據(jù)php當(dāng)前運(yùn)行模式進(jìn)行渲染輸出。

2.thinkphp異常記錄的不足

點(diǎn)擊report跳轉(zhuǎn)到think\exception\handle

public function report(Exception $exception)

{

if (!$this->isIgnoreReport($exception)) {

// 收集異常數(shù)據(jù)

if (Container::get('app')->isDebug()) {

$data = [

'file' => $exception->getFile(),

'line' => $exception->getLine(),

'message' => $this->getMessage($exception),

'code' => $this->getCode($exception),

];

$log = "[{$data['code']}]{$data['message']}[{$data['file']}:{$data['line']}]";

} else {

$data = [

'code' => $this->getCode($exception),

'message' => $this->getMessage($exception),

];

$log = "[{$data['code']}]{$data['message']}";

}

if (Container::get('app')->config('log.record_trace')) {

$log .= "\r\n" . $exception->getTraceAsString();

}

Container::get('log')->record($log, 'error');

}

}

可以看到這是thinkphp默認(rèn)的異常記錄,缺點(diǎn)如下:

記錄的信息不夠詳情,僅僅記錄了異常信息,沒(méi)有記錄訪問(wèn)的url、參數(shù)、用戶id和其他相關(guān)的信息,對(duì)想要更快速的定位異常信息,提供的依據(jù)較少。

日志記錄是記錄在文件的,放在了runtime下的log目錄,按照日期劃分,但是這些文件是有大小和個(gè)數(shù)限制的。超過(guò)了就會(huì)合并、改名字、刪除。對(duì)于需要快速查找日志信息,有的時(shí)候不方便,還有可能找不到。

對(duì)于多服務(wù)器部署來(lái)說(shuō)、每個(gè)工程下面的日志文件是獨(dú)立的、沒(méi)有一個(gè)統(tǒng)一的地方去查看這些日志,需要一個(gè)工程一個(gè)工程去查找日志,非常麻煩。

不利于對(duì)每天的日志進(jìn)行分析,統(tǒng)計(jì)。

3.我們?nèi)绾胃倪M(jìn)

所以我們要強(qiáng)化日志記錄功能,因?yàn)閞eport方法是tp記錄日志的方法,所以顯然我們定義一個(gè)baseHandle繼承 think\exception\handle,然后在baseHandle重寫(xiě)report方法就可以了,然后工程中所有的handle都繼承baseHandle,異常自然就會(huì)被自定義的report方法里面邏輯處理。到底記錄這些異常信息,有很多方案。這里我們用的是mongo存儲(chǔ),盡可能詳情的記錄。無(wú)論如何,把數(shù)據(jù)都記錄在一塊了,然后后臺(tái)增加個(gè)查看異常信息的功能,幸福還會(huì)遠(yuǎn)嗎?

class BaseHandle extends parentHandle

{

public function report(Exception $exception)

{

parent::report($exception); // TODO: Change the autogenerated stub

try{

// //記錄日志

$exceptionLogParam = new ExceptionLogParam();

$exceptionLogParam->exception = $exception->getMessage();

$exceptionLogParam->trace = $exception->getTraceAsString();

$exceptionLogParam->is_cli = PHP_SAPI == 'cli' ? 1 : 0;

$exceptionLogParam->header = \GuzzleHttp\json_encode(Request::header(), JSON_UNESCAPED_UNICODE);

$exceptionLogParam->param = \GuzzleHttp\json_encode(Request::param(), JSON_UNESCAPED_UNICODE);

$exceptionLogParam->method = \GuzzleHttp\json_encode(Request::method(), JSON_UNESCAPED_UNICODE);

$exceptionLogParam->controller = Loader::parseName(Request::controller(), 0);

$exceptionLogParam->param = Request::param();

$exceptionLogParam->param = \GuzzleHttp\json_encode($exceptionLogParam->param, JSON_UNESCAPED_UNICODE);

$exceptionLogParam->action = Request::action();

$exceptionLogParam->module = Request::module();

$exceptionLogParam->user_id = RememberMeHelper::$_userId;

$exceptionLogParam->created_at = time();

$exceptionLogParam->cookie = \GuzzleHttp\json_encode(Request::cookie(),true);

$exceptionLogParam->session = \GuzzleHttp\json_encode(Request::session(),true);

$exceptionLogParam->url = Request::url();

$exceptionLogParam->server_ip = get_server_ip();

$exceptionLogParam->file_line_info = $exception->getFile().$exception->getLine();

ExceptionLogService::getInstance()->create($exceptionLogParam);

}catch (\Exception $exception){

\think\facade\Log::write('存儲(chǔ)日志發(fā)生了異常');

}

}

}

考慮過(guò)的其他存儲(chǔ)方法:

數(shù)據(jù)庫(kù)建立一個(gè)exception表專門存儲(chǔ),因?yàn)楫惓P畔⒘靠赡芊浅4?#xff0c;用mysql存儲(chǔ)代價(jià)比較昂貴,而且對(duì)mysql的讀寫(xiě)性能感覺(jué)會(huì)有干擾,所以放棄。

用一個(gè)專門的mongo數(shù)據(jù)庫(kù)存儲(chǔ),因?yàn)閠hinkphp的model是可以配置的,只要配置連接數(shù)據(jù)庫(kù)是mongo,使用起來(lái)沒(méi)有什么區(qū)別。mongo便宜一些,日志存的多,查詢方式比較單一,所以選了這個(gè)。

考慮過(guò)ELK,往ES里面寫(xiě)入文檔,了解過(guò)網(wǎng)上有很多說(shuō)可以用ELK做日志分析,但是對(duì)這個(gè)目前使用不熟悉,以后考慮研究下。

總結(jié)

以上是生活随笔為你收集整理的thinkphp mysql 日志_基于thinkphp实现异常日志详细统计功能的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。