親測生產可用
在網上拼拼湊湊的答案,和自己的想法做了個accesslog,可以記錄在日誌內統計不喜勿噴
功能包含
- mysql 慢查詢
- 統計sql出現的頻率 和 那些sql 最耗時
- cache慢查詢
- 介面慢查詢報警
- accesslog 日誌
廢話不說上程式碼/lumen+swoole
- lumen bootstrap/app.php 新增全域性中介軟體
$app->middleware([ \App\Http\Middleware\Common\AfterTestMiddleware::class, ]);
- app/Http/Middleware/Common/AfterTestMiddleware.php
public function handle($request, Closure $next) { $response = $next($request); TestLog::TestLogFunc(); return $response; }
- app/Providers/EventServiceProvider.php 增加 \App\Listeners\QueryListener::class
public function handle(QueryExecuted $event)
{
$data = request()->get('mysql ',['number'=>0,'result'=>[]]);
$sql = str_replace('%', "'%%'", $event->sql);
$sql = str_replace('?', '"' . '%s' . '"', $sql);
$binding_sql = vsprintf($sql, $event->bindings);
$data['number'] += 1;
// 開啟debug
if (env('APP_DEBUG') == 'true'){
$data['result'][$binding_sql][] = ['time'=>$event->time.'ms','sql'=>$binding_sql];
}
// 報警
if ($event->time >= 500 ) {
$binding_sql = vsprintf($sql, $event->bindings);
$data['slowsql'][$binding_sql] = ['time' => $event->time . 'ms', 'detail' => $event->detail];
// 釘釘告警 sql慢查詢
request()->offsetSet('mysql ',$data);
}
}
<?php
namespace TEST;
class TestLog
{
/**
* 記錄access log
*/
public static function TestLogFunc()
{
try {
// 拼接日誌
$content = self::xxxxxxx();
// 寫入日誌
self::write($content);
// 檢測是否有慢請求
$request_time = ((microtime(true) - request()->server('REQUEST_TIME_FLOAT')) * 1000);
// 判斷是否超時
if ( 1000 <= $request_time){
// 釘釘通知 慢請求
}
}catch (\Exception $exception){
return;
}
}
/**
* 拼接日誌 日誌格式:[請求時間] 請求方式 狀態碼 路由 引數list 客戶端ip db次數 cache次數 響應時間 hader頭資訊
*
* @param $err_code
* @return string
*/
public static function xxxxxxx($err_code = 200){
$request_time = ((microtime(true) - request()->server('REQUEST_TIME_FLOAT')) * 1000);
$map = request()->all();
$dbMap = request()->get('mysql',['number'=>0,'result'=>[]]);
$cacheMap = request()->get('cache',['number'=>0,'result'=>[]]);
unset($map['mysql'],$map['cache']);
// access log 拼接
$content = sprintf('[%s] %s %s %s %s %s db=%s cache=%s time=%dms %s %s',
date('Y-m-d H:i:s'),
request()->getMethod(),
$err_code,
request()->getPathInfo(),
json_encode($map,320),
request()->server('HTTP_X_FORWARDED_FOR') ? request()->server('HTTP_X_FORWARDED_FOR') : request()->server('REMOTE_ADDR'),
$dbMap['number'],
$cacheMap['number'],
$request_time,
json_encode(request()->header(),320),
isset($dbMap['slowsql']) ? 'slowsql='.json_encode($dbMap['slowsql']) : ''
);
return $content;
}
/**
*
* @param $content
* @param $fileName
*/
public static function write($content){
// 守護程式模式 直接寫入檔案
if (env('DAEMONIZE') == true){
$fileName = '/access-' . date('Y-m-d') . '.log';
file_put_contents($fileName, $content . PHP_EOL, FILE_APPEND);
}else {
$fileObject = fopen("php://stdout", "w");
fwrite($fileObject, $content.PHP_EOL);
fclose($fileObject);
}
}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結