laravelS 记录accesslog日志,服务慢查询预警

亲测生产可用

在网上拼拼凑凑的答案,和自己的想法做了个accesslog,可以记录在日志内统计不喜勿喷

功能包含

  1. mysql 慢查询
  2. 统计sql出现的频率 和 那些sql 最耗时

laravels实现accessLog,mysql慢查询报警,cache报警本地debug调试

  1. cache慢查询
  2. 接口慢查询报警
  3. accesslog 日志

    废话不说上代码/lumen+swoole

  4. lumen bootstrap/app.php 添加全局中间件
     $app->middleware([
          \App\Http\Middleware\Common\AfterTestMiddleware::class,
     ]);
  5. app/Http/Middleware/Common/AfterTestMiddleware.php
     public function handle($request, Closure $next)
     {
         $response =  $next($request);
         TestLog::TestLogFunc();
         return $response;
     }
  6. 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);
        }
    }
}
php
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 7

最近好多慢日志的帖子 :+1:

2年前 评论
小李世界 (作者) 2年前
哪吒的狗腿子 (楼主) 2年前
哪吒的狗腿子 (楼主) 2年前
小李世界 (作者) 2年前

1.记日志逻辑写在中间件的terminate()方法中更合理;

2.新增Log Channel使用Log方法比用原生file_put_contents()更优雅。

2年前 评论
哪吒的狗腿子 (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!