mysql链路跟踪工具_EasySwoole利用链路追踪组件制作甩锅工具

前言

最近前端老是反馈API调用异常,说请求成功但是没有数据返回!

我写的代码怎么可能有bug,肯定是前端调用的方式不对!

经过一番套鼓,直接把请求参数和响应内容打印到控制台,果然不出我所料,请求缺少重要参数!

为了能让前端每次出问题后不用来找我(俗称甩锅),自己排查问题,我就想着把每次的请求参数和响应内容记录下来,前端查看请求记录详情排查问题。

刚好看到EasySwoole有这么一个组件(链路追踪)可以记录每次的请求信息,所以就写了这个甩锅工具。(说真的用起来真香)

话不多说先来一张甩锅工具效果图

7170105d4ea3db68744f2a9f9df65c94.png

每次请求需要记录的参数

请求地址、客户端IP、请求时间、请求状态、请求耗时、请求参数、响应内容

先创建mysql表CREATE TABLE `td_api_tracker_point_list` (

`pointd` varchar(18) NOT NULL,

`ip` varchar(100) DEFAULT '',

`create_date` varchar(30) DEFAULT '' COMMENT '访问时间 2020-02-23 12:00:00',

`pointName` varchar(100) DEFAULT NULL,

`parentId` varchar(18) DEFAULT NULL,

`depth` int(11) NOT NULL DEFAULT '0',

`isNext` int(11) NOT NULL DEFAULT '0',

`startTime` varchar(14) NOT NULL,

`endTime` varchar(14) DEFAULT NULL,

`spendTime` decimal(15,3) DEFAULT '0.000',

`status` varchar(10) NOT NULL,

`uri` varchar(255) DEFAULT '',

`result` text,

`data` text,

PRIMARY KEY (`pointd`),

UNIQUE KEY `trackerId_UNIQUE` (`pointd`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

创建ORM表模型

\App\Model\TrackerPoint\TrackerPointModel.php<?php

namespaceApp\Model\TrackerPoint;classTrackerPointModelextends\EasySwoole\ORM\AbstractModel

{protected$tableName='td_api_tracker_point_list';}

就是这么简单就创建好了表模型

安装链路追踪组件composer require easyswoole/tracker

使用链路追踪

在EasySwooleEvent.php的onRequest引入链路追踪并传入请求uri,get和post参数public static functiononRequest(Request$request,Response$response): bool

{$allow_origin=array("http://www.xxx1.com","https://www.xxxx2.com","http://127.0.0.1",);$origin=$request->getHeader('origin');if($origin!== []){$origin=$origin[0];if(in_array($origin,$allow_origin)){$response->withHeader('Access-Control-Allow-Origin',$origin);$response->withHeader('Access-Control-Allow-Methods','GET, POST, OPTIONS');$response->withHeader('Access-Control-Allow-Credentials','true');$response->withHeader('Access-Control-Allow-Headers','Content-Type, Authorization, X-Requested-With, token');if($request->getMethod() ==='OPTIONS') {$response->withStatus(Status::CODE_OK);return false;}

}

}/**

* 链路追踪

*/$point= PointContext::getInstance()->createStart($request->getUri()->__toString());$point->setStartArg(['uri'=>$request->getUri()->__toString(),'get'=>$request->getQueryParams(),'post'=>$request->getRequestParam()

]);return true;}

在EasySwooleEvent.php的afterRequest获取链路结果并写入到mysql表中//请求结束前执行public static functionafterRequest(Request$request,Response$response): void{// 真实IP$ip='';if(count($request->getHeader('x-real-ip'))) {$ip=$request->getHeader('x-real-ip')[0];}else{$params=$request->getServerParams();foreach(['http_client_ip','http_x_forward_for','x_real_ip','remote_addr']as$key) {if(isset($params[$key]) && !strcasecmp($params[$key],'unknown')) {$ip=$params[$key];break;}}}// 查看每次请求记录 http://host/index/tracker$point= PointContext::getInstance()->startPoint();$point->end();$array= Point::toArray($point);$rsp=$response->getBody();foreach($arrayas$k=>$v){$data['ip'] =$ip;$data['pointd'] =$v['pointId'];$data['pointName'] =$v['pointName'];$data['parentId'] =$v['parentId'];$data['depth'] =$v['depth'];$data['isNext'] =$v['isNext'];$data['startTime'] =$v['startTime'];$data['endTime'] =$v['endTime'];$data['spendTime'] =$v['endTime']-$v['startTime'];$data['status'] =$v['status'];$data['result'] = json_encode($v);$data['data'] =$rsp->__tostring();$data['uri'] =$v['startArg']['uri'];$data['create_date'] = date('Y-m-d H:i:s',time());if(strpos($v['startArg']['uri'],'index/tracker') !==false||strpos($v['startArg']['uri'],'index/tracker') !==false){//过滤index/tracker和index/getTracker这两个方法}else{\App\Model\TrackerPoint\TrackerPointModel::create()->data($data,false)->save();}}}

到这里基本大功告成了,剩下的就是写个页面把记录展示出来

安装模板视图composer require easyswoole/template

实现渲染引擎

创建文件\App\Template.php<?php

namespace App;

use EasySwoole\Template\RenderInterface;

class Template implements RenderInterface

{

protected $template;

function __construct()

{

$config = [

'view_path'    => EASYSWOOLE_ROOT.'/App/Views/',

'cache_path'   => EASYSWOOLE_ROOT.'/Temp/runtime/',

];

$this->template = new \think\Template($config);

}

public function render(string $template, array $data = [], array $options = []): ?string

{

// TODO: Implement render() method.

ob_start();

$this->template->assign($data);

$this->template->fetch($template);

$content = ob_get_contents() ;

return $content;

}

public function afterRender(?string $result, string $template, array $data = [], array $options = [])

{

// TODO: Implement afterRender() method.

}

public function onException(\Throwable $throwable): string

{

// TODO: Implement onException() method.

$msg = "{$throwable->getMessage()} at file:{$throwable->getFile()} line:{$throwable->getLine()}";

trigger_error($msg);

return $msg;

}

}

在EasySwooleEvent.php的mainServerCreate实例化视图并注入配置/*** ****************   实例化该Render,并注入你的驱动配置    *****************/Render::getInstance()->getConfig()->setRender(newTemplate());Render::getInstance()->attachServer(ServerManager::getInstance()->getSwooleServer());

在http控制器中使用视图模板渲染,存放模板的目录App/Views/index

控制器文件\App\HttpController\Index.php<?phpnamespaceApp \HttpController;useApp\Model\TrackerPoint\TrackerPointModel;useApp\Utility\MyQueue;useEasySwoole\Component\AtomicManager;useEasySwoole\Component\Timer;useEasySwoole\EasySwoole\Logger;useApp\Model\WechatModel;useEasySwoole\Http\AbstractInterface\Controller;useEasySwoole\ORM\DbManager;useEasySwoole\Queue\Job;useEasySwoole\Template\Render;useEasySwoole\Tracker\PointContext;useElasticsearch\ClientBuilder;use\Swoole\Coroutineasco;useEasySwoole\Mysqli\QueryBuilder;useEasySwoole\Jwt\Jwt;use\PhpOffice\PhpSpreadsheet\Spreadsheet;use\PhpOffice\PhpSpreadsheet\Writer\Xlsx;classIndexextendsController{protected functiononRequest(?string$action): ?bool{return true;}//渲染模板public functiontracker(){$this->response()->write(Render::getInstance()->render('index/tracker',['row'=> time(),'json'=>json_encode([])]));}//获取链路记录列表public functiongetTracker(){$model= TrackerPointModel::create();$param=$this->request()->getRequestParam();if(!empty($param['uri']) ){$model->where('uri',"%{$param['uri']}%",'like');}$limit=$param['limit']??10;$p=$param['page']??1;$data['code'] =0;$data['msg'] ='';$list=$model->withTotalCount()->limit($p* ($p-1),$limit)->order('pointd','desc')->select();$data['count'] =$model->lastQueryResult()->getTotalCount();foreach($listas$k=>$v){$uri= explode(':9501/',$v['uri']);if(count($uri)!=2){$uri= explode(':80/',$v['uri']);}$list[$k]['uri'] = !empty($uri[1])?$uri[1]:$v['uri'];$result= json_decode($v['result'],true);unset($result['startArg']['uri']);$list[$k]['result'] = json_encode($result['startArg']);if(strpos($v['uri'],'tracker') !==false||strpos($v['uri'],'getTracker') !==false){$list[$k]['data'] ='';}}$data['data'] =$list;$data['sql'] =$model->lastQuery()->getLastPrepareQuery();$this->response()->write(json_encode($data));return false;}

//测试计数器functionindex(){$this->response()->withHeader('Content-type','text/html;charset=utf-8');$atomic= AtomicManager::getInstance()->get('second');$atomic->add(1);echodate('i:s',time()).'计数器:'.$atomic->get().PHP_EOL;$this->response()->write('计数器:'.$atomic->get().PHP_EOL);}}

甩锅完毕

最后甩锅工具完成,直接丢链接给前端  http://你的域名:9501/index/tracker

7170105d4ea3db68744f2a9f9df65c94.png

本文为够意思原创文章,转载无需和我联系,但请注明来自够意思博客blog.go1s.cn:够意思博客 » EasySwoole利用链路追踪组件制作甩锅工具

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440807.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CCFCSP- 201312-4】有趣的数(线性dp)

题干&#xff1a; 试题编号&#xff1a;201312-4试题名称&#xff1a;有趣的数时间限制&#xff1a;1.0s内存限制&#xff1a;256.0MB问题描述&#xff1a; 问题描述   我们把一个数称为有趣的&#xff0c;当且仅当&#xff1a;   1. 它的数字只包含0, 1, 2, 3&#xff0c…

java selector 源码_Java NIO核心组件-Selector和Channel

昨天我们介绍了一下SelectorProvider和IO multiplexing.特别是IO multiplexing中的epoll系统调用,是Linux版本的Java的NIO的核心实现.那今天我们就来介绍一下, Java NIO中的核心组件, Selector和Channel.这两个组件,对于熟悉Java OIO,而不熟悉Java NIO的朋友来说,理解其作用是极…

【HDU - 1542】Atlantis (线段树,扫描线)

题干&#xff1a; There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend…

python 底层原理processpoolexecutor_python 多进程并行编程 ProcessPoolExecutor的实现

使用 ProcessPoolExecutorfrom concurrent.futures import ProcessPoolExecutor, as_completedimport random斐波那契数列当 n 大于 30 时抛出异常def fib(n):if n > 30:raise Exception(can not > 30, now %s % n)if n < 2:return 1return fib(n-1) fib(n-2)准备数组…

【HDU - 5700】【51nod - 1672】 区间交(贪心,STLset 或线段树第k大)

题干&#xff1a; 小A有一个含有n个非负整数的数列与m个区间&#xff0c;每个区间可以表示为li,ri。 它想选择其中k个区间&#xff0c; 使得这些区间的交的那些位置所对应的数的和最大。&#xff08;是指k个区间共同的交&#xff0c;即每个区间都包含这一段&#xff0c;具体可…

python 爬虫 博客园_Python爬虫爬取博客园作业

分析一下他们的代码&#xff0c;我在浏览器中对应位置右键&#xff0c;然后点击检查元素&#xff0c;可以找到对应部分的代码。但是&#xff0c;直接查看当前网页的源码发现&#xff0c;里面并没有对应的代码。我猜测这里是根据服务器上的数据动态生成的这部分代码&#xff0c;…

【洛谷 - P1507 】NASA的食物计划(二维费用背包,dp)

题干&#xff1a; 题目背景 NASA(美国航空航天局)因为航天飞机的隔热瓦等其他安全技术问题一直大伤脑筋,因此在各方压力下终止了航天飞机的历史,但是此类事情会不会在以后发生&#xff0c;谁也无法保证,在遇到这类航天问题时,解决方法也许只能让航天员出仓维修,但是多次的维修…

java 与 xml_xml与java对象转换

public static void main(String[] args) {//java bean 转 xmlDept d new Dept();List staffs new ArrayList<>();Staff s1 new Staff("wuyun", 20);Staff s2 new Staff("lilei", 22);staffs.add(s1);staffs.add(s2);d.setDeptName("开放平…

【蓝桥杯官网试题 - 算法训练 】P0502(乱搞,tricks)

题干&#xff1a; 编写一个程序&#xff0c;读入一组整数&#xff0c;这组整数是按照从小到大的顺序排列的&#xff0c;它们的个数N也是由用户输入的&#xff0c;最多不会超过20。然后程序将对这个数组进行统计&#xff0c;把出现次数最多的那个数组元素值打印出来。如果有两个…

python循环中的else_python 循环中else的简单示例

导读热词对python这个高级语言感兴趣的小伙伴&#xff0c;下面一起跟随编程之家 jb51.cc的小编两巴掌来看看吧&#xff01;众多语言中都有if else这对条件选择组合&#xff0c;但是在python中还有更多else使用的地方&#xff0c;比如说循环for&#xff0c;或者while都可以和els…

【蓝桥杯官网试题 -算法训练】素因子去重(数学,数论,因子约数)

题干&#xff1a; 问题描述 给定一个正整数n&#xff0c;求一个正整数p&#xff0c;满足p仅包含n的所有素因子&#xff0c;且每个素因子的次数不大于1 输入格式 一个整数&#xff0c;表示n 输出格式 输出一行&#xff0c;包含一个整数p。 样例输入 1000 样例输出 10 数…

【蓝桥杯官网试题 - 算法提高】 贪吃的大嘴 (多重背包转0-1背包,dp)

题干&#xff1a; 问题描述 有一只特别贪吃的大嘴,她很喜欢吃一种小蛋糕,而每一个小蛋糕有一个美味度,而大嘴是很傲娇的,一定要吃美味度和刚好为m的小蛋糕,而且大嘴还特别懒,她希望通过吃数量最少的小蛋糕达到这个目的.所以她希望你能设计一个程序帮她决定要吃哪些小蛋糕. 输…

java applet socket_Java swing applet中使用的套接字

小编典典基于此示例&#xff0c;这是一个使用Swing的简单网络客户端/服务器对。请注意与正确同步有关的一些问题&#xff1a;GUI本身是使用事件分配线程构建的invokeLater()。此外&#xff0c;代码还依赖的线程安全性append()。最后&#xff0c;它结合了文章Text Area Scrollin…

【牛客 - 370A】签到题(线段树扫描线 或 STLset)(求线段并)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/370/A 来源&#xff1a;牛客网 恭喜你找到了本场比赛的签到题&#xff01; 为了让大家都有抽奖的机会&#xff0c;只需要复制粘贴以下代码&#xff08;并且稍微填下空&#xff09;即可 AC&#xff1…

java sqlserver分页查询_SQLServer之常用的分页查询语句介绍

在SqlServer中&#xff0c;分页查询是经常用到的查询语句&#xff0c;一个好的分页查询语句&#xff0c;不能能将代码省略&#xff0c;还能提高运行效率&#xff0c;下面我们来探讨一下SQLServer中的分页查询语句。具体的业务逻辑是这样的&#xff0c;我数据库中有100条数据&am…

【牛客 - 370H】Rinne Loves Dynamic Graph(分层图最短路)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/370/H 来源&#xff1a;牛客网 Rinne 学到了一个新的奇妙的东西叫做动态图&#xff0c;这里的动态图的定义是边权可以随着操作而变动的图。 当我们在这个图上经过一条边的时候&#xff0c;这个图上所…

中位数及带权中位数问题(转)

先从一到简单的题看起&#xff1a; 士兵站队问题 在一个划分成网格的操场上&#xff0c;n个士兵散乱地站在网格点上。网格点由整数坐标(x,y)表示。士兵们可以沿网格边上、下、左、右移动一步&#xff0c;但在同一时刻任一网格点上只能有一名士兵。按照军官的命令&#xff0c;…

java编写学籍管理系统_java学籍管理系统源代码.doc

java学籍管理系统源代码package zuoye;//主类import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.io.*;import java.util.Hashtable;public class ManagerWindow extends JFrame implements ActionListener{InputStudent 基本信息录入null;ModifySit…

*【SGU - 114】Telecasting station (带权中位数 或 三分)

题干&#xff1a; Every city in Berland is situated on Ox axis. The government of the country decided to build new telecasting station. After many experiments Berland scientists came to a conclusion that in any city citizens displeasure is equal to product…

java的et5_Javascript与java相同的3des加密(使用etdesede/CBC/PKCS5Padding )

在某个项目中&#xff0c;需要开发一个与native相对应的web前端app&#xff0c;后台用的是java restful接口&#xff0c;请求数据时需要用的3des加密。如果想要请求接口&#xff0c;则需要javascript的加密与java相同&#xff0c;于是在baidu与google进行了大量搜索&#xff0c…