laravelS 记录accesslog日志,服务慢查询预警
亲测生产可用
在网上拼拼凑凑的答案,和自己的想法做了个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 协议》,转载必须注明作者和本文链接
推荐文章: