几行代码轻松实现laravel链式追踪,一分钟快速排查系统问题

YY理解

所谓的链式追踪,并没有多高大尚,简单的可以理解为在一次请求中,生成一个链路请求trace_id,在整个请求过程中记录的日志都包含这个trace_id,对于拆分系统的微服务而言,可以在调用其他服务的时候把这个trace_id传入调用系统,这样整个请求生命周期中一直都有这个标识,可以顺藤摸瓜,问题有迹可循

优点

能快速的通过trace_id 查找完整的请求链路日志,通过命令或者elk方式只需要这个ID就能搜索出所有线索日志,进而快速排查问题

laravel代码实现

思路

laravel通常是运行在php-fpm模式下,请求都是在一个进程中完成的,所以本身就是一条从开始到结束的直线。只需要我们在请求最初时候产生这个trace_id ,然后在后续的代码处理记录日志的时候只要把这个ID加上即可。

laravel实现思路

对于laravel而言,可以使用前置中间件和后置中间件以及重新log记录日志方式便可以实现

laravel代码实现

  • 首先kernel.php 注册中间件

    /**
    * The application's route middleware groups. * * @var array
    */protected $middlewareGroups = [
    'gptapp' => [
    \App\Http\Middleware\RequestBefore::class,
    \App\Http\Middleware\ResponseAfter::class,
    ],
    ];
  • 编写请求之前前置中间件 RequestBefore,在请求到业务逻辑之前进行生成trace_id 保存到request 对象上

    class RequestBefore
    {
      public function handle(Request $request, Closure $next)
      {
          //没有则生成唯一请求ID
          if (! $request->header('Request-Id')) {
              $requestId = (string)md5( uniqid() . time());
              $request->headers->set('Request-Id', $requestId);
          }
          return $next($request);
      }
    }
  • 封装带有trace_id的日志记录方法 Log, laravel8以后有自带上下文的日志记录方法(此步骤可以省略)

    class extends Log {
      static function info ($arr) {
         //加上唯一ID 
         $arr['request_id'] = request()->headers->get('Request-Id', $requestId);
         //调用laravel log门面写日志
          SysLog::info(json_encode($arr));
      }
    }
  • 编写请求响应之后的后置中间件 ResponseAfter,使用带有trace_id 的日志记录方法进行日志保存

    class ResponseAfter
    {
      public function handle(Request $request, Closure $next)
      {
          $response = $next($request);
          // 执行操作
          Log::info([
              'request' => [
                  'client_ip' => $request->getClientIp(),
                  'method' => $request->getMethod(),
                  'route' => $request->getRequestUri(),
                  'content_type' => $request->getContentType(),
                  'content' => $request->all(),
                  'headers' => $request->headers->all(),
              ],
              'response' => [
                  'headers' => $response->headers->all(),
                  'contents' => $response->getContent(),
              ],
          ]);
          return $response;
      }
    }

总结

php是世界上最好的编程语言,其他编程语言能做的,php也能!!!

本作品采用《CC 协议》,转载必须注明作者和本文链接
PHP是世界上最好的编程语言,它能快速的进行技术变现,让代码多一份价值。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 1

赞,不错的方案 :+1:

2天前 评论

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