链路追踪php,easyswoole链路追踪

Tracker

Easyswoole提供了一个基础的追踪组件,方便用户实现基础的服务器状态监控,与调用链记录。

组件要求

php: >=7.1.0

ext-swoole: ^4.4.0

easyswoole/component: ^2.0

安装方法

composer require easyswoole/tracker

仓库地址

调用链

Easyswoole的调用链跟踪是一个以类似有序的树状链表的解构实现的,解构如下:

struct Point{

struct Point* nextPoint;

struct Point[] subPoints;

const END_SUCCESS = 'success';

const END_FAIL = 'fail';

const END_UNKNOWN = 'unknown';

int startTime;

mixed startArg;

int endTime;

string pointName;

string endStatus = self::END_UNKNOWN;

mixed endArg;

string pointId;

string parentId;

int depth = 0;

bool isNext

}

基本使用

use EasySwoole\Tracker\Point;

use EasySwoole\Component\WaitGroup;

use EasySwoole\Tracker\PointContext;

/*

* 假设我们的调用链是这样的

* onRequest ->> actionOne ->> actionOne call remote Api(1,2) ->> afterAction

*/

go(function (){

/*

* 创建入口

*/

$onRequest = new Point('onRequest');

//记录请求参数,并模拟access log

\co::sleep(0.01);

$onRequest->setStartArg([

'requestArg' => 'requestArgxxxxxxxx',

'accessLogId'=>'logIdxxxxxxxxxx'

]);

//onRequest完成

$onRequest->end();

//进入 next actionOne

$actionOne = $onRequest->next('actionOne');

//action one 进入子环节调用

$waitGroup = new WaitGroup();

//sub pointOne

$waitGroup->add();

$subOne = $actionOne->appendChild('subOne');

go(function ()use($subOne,$waitGroup){

\co::sleep(0.1);

$subOne->end();

$waitGroup->done();

});

//sub pointTwo,并假设失败

$waitGroup->add();

$subTwo = $actionOne->appendChild('subTwo');

go(function ()use($subTwo,$waitGroup){

\co::sleep(1);

$subTwo->end($subTwo::END_FAIL,['failMsg'=>'timeout']);

$waitGroup->done();

});

$waitGroup->wait();

$actionOne->end();

//actionOne结束,进入afterAction

$afterAction = $actionOne->next('afterAction');

//模拟响应记录

\co::sleep(0.01);

$afterAction->end($afterAction::END_SUCCESS,['log'=>'success']);

/*

* 从入口开始打印调用链

*/

echo Point::toString($onRequest);

});

//以上代码等价于如下

go(function (){

PointContext::getInstance()->createStart('onRequest')->next('actionOne')->next('afterAction');

//记录请求参数,并模拟access log

\co::sleep(0.01);

PointContext::getInstance()->find('onRequest')->setStartArg([

'requestArg' => 'requestArgxxxxxxxx',

'accessLogId'=>'logIdxxxxxxxxxx'

])->end();

$subOne = PointContext::getInstance()->find('actionOne')->appendChild('subOne');

$subTwo = PointContext::getInstance()->find('actionOne')->appendChild('subTwo');

$waitGroup = new WaitGroup();

$waitGroup->add();

go(function ()use($subOne,$waitGroup){

\co::sleep(0.1);

$subOne->end();

$waitGroup->done();

});

//sub pointTwo,并假设失败

$waitGroup->add();

go(function ()use($subTwo,$waitGroup){

\co::sleep(1);

$subTwo->end($subTwo::END_FAIL,['failMsg'=>'timeout']);

$waitGroup->done();

});

$waitGroup->wait();

PointContext::getInstance()->find('actionOne')->end();

//模拟响应记录

\co::sleep(0.01);

PointContext::getInstance()->find('afterAction')->end(Point::END_SUCCESS,['log'=>'success']);

/*

* 从入口开始打印调用链

*/

echo Point::toString(PointContext::getInstance()->startPoint());

});

以上代码输出结果:

#

PointName:onRequest

Status:success

PointId:AoRVFMgrsbNwukBZc7

Depth:0

IsNext:false

Start:1561736477.2808

StartArg:{"requestArg":"requestArgxxxxxxxx","accessLogId":"logIdxxxxxxxxxx"}

End:1561736477.2939

EndArg:null

ChildCount:0

Children:None

NextPoint:

#

PointName:actionOne

Status:success

PointId:2zOWG1SvMbyBcnRmje

Depth:0

IsNext:true

Start:1561736477.2809

StartArg:null

End:1561736478.2993

EndArg:null

ChildCount:2

Children:

#

PointName:subOne

Status:success

PointId:0wU31l8brpfCnXdTxH

Depth:1

IsNext:false

Start:1561736477.2939

StartArg:null

End:1561736477.4006

EndArg:null

ChildCount:0

Children:None

NextPoint:None

#

PointName:subTwo

Status:fail

PointId:Jphr6RD8KSHmYbt70A

Depth:1

IsNext:false

Start:1561736477.2939

StartArg:null

End:1561736478.2993

EndArg:{"failMsg":"timeout"}

ChildCount:0

Children:None

NextPoint:None

NextPoint:

#

PointName:afterAction

Status:success

PointId:oPnGNrkj6qwb381BQl

Depth:0

IsNext:true

Start:1561736477.2809

StartArg:null

End:1561736478.3119

EndArg:{"log":"success"}

ChildCount:0

Children:None

NextPoint:None

如果想以自己的格式记录到数据库,可以具体查看Point实现的方法,每个Point都有自己的Id

进阶使用

HTTP API请求追踪

EasySwooleEvent.php

namespace EasySwoole\EasySwoole;

use EasySwoole\EasySwoole\Swoole\EventRegister;

use EasySwoole\EasySwoole\AbstractInterface\Event;

use EasySwoole\Http\Request;

use EasySwoole\Http\Response;

use EasySwoole\Tracker\Point;

use EasySwoole\Tracker\PointContext;

class EasySwooleEvent implements Event

{

public static function initialize()

{

// TODO: Implement initialize() method.

date_default_timezone_set('Asia/Shanghai');

}

public static function mainServerCreate(EventRegister $register)

{

}

public static function onRequest(Request $request, Response $response): bool

{

$point = PointContext::getInstance()->createStart('onRequest');

$point->setStartArg([

'uri'=>$request->getUri()->__toString(),

'get'=>$request->getQueryParams()

]);

return true;

}

public static function afterRequest(Request $request, Response $response): void

{

$point = PointContext::getInstance()->startPoint();

$point->end();

echo Point::toString($point);

$array = Point::toArray($point);

}

}

Index.php

namespace App\HttpController;

use EasySwoole\Component\WaitGroup;

use EasySwoole\Http\AbstractInterface\Controller;

use EasySwoole\Tracker\PointContext;

class Index extends Controller

{

protected function onRequest(?string $action): ?bool

{

/*

* 调用关系 HttpRequest->OnRequest

*/

$point = PointContext::getInstance()->next('ControllerOnRequest');

//假设这里进行了权限验证,并模拟数据库耗时

\co::sleep(0.01);

$point->setEndArg([

'userId'=>'xxxxxxxxxxx'

]);

$point->end();

return true;

}

function index()

{

//模拟调用第三方Api,调用关系 OnRequest->sub(subApi1,subApi2)

$actionPoint = PointContext::getInstance()->next('indexAction');

$wait = new WaitGroup();

$subApi = $actionPoint->appendChild('subOne');

$wait->add();

go(function ()use($wait,$subApi){

\co::sleep(1);

$subApi->end();

$wait->done();

});

$subApi = $actionPoint->appendChild('subTwo');

$wait->add();

go(function ()use($wait,$subApi){

\co::sleep(0.3);

$subApi->end($subApi::END_FAIL);

$wait->done();

});

$wait->wait();

$actionPoint->end();

$this->response()->write('hello world');

}

}

以上每次请求会输出如下格式:

#

PointName:onRequest

Status:success

PointId:1561743038GyV4lnus

ParentId:

Depth:0

IsNext:false

Start:1561743038.7011

StartArg:{"uri":"http://127.0.0.1:9501/","get":[]}

End:1561743039.7152

EndArg:null

ChildCount:0

Children:None

NextPoint:

#

PointName:ControllerOnRequest

Status:success

PointId:15617430386f0OQDsS

ParentId:1561743038GyV4lnus

Depth:0

IsNext:true

Start:1561743038.7025

StartArg:null

End:1561743038.713

EndArg:null

ChildCount:0

Children:None

NextPoint:

#

PointName:indexAction

Status:success

PointId:1561743038XEmF0M49

ParentId:15617430386f0OQDsS

Depth:0

IsNext:true

Start:1561743038.7131

StartArg:null

End:1561743039.7151

EndArg:null

ChildCount:2

Children:

#

PointName:subOne

Status:success

PointId:1561743038uIkzYgcS

ParentId:1561743038XEmF0M49

Depth:1

IsNext:false

Start:1561743038.7135

StartArg:null

End:1561743039.7151

EndArg:null

ChildCount:0

Children:None

NextPoint:None

#

PointName:subTwo

Status:fail

PointId:1561743038PslVSY4n

ParentId:1561743038XEmF0M49

Depth:1

IsNext:false

Start:1561743038.7136

StartArg:null

End:1561743039.0149

EndArg:null

ChildCount:0

Children:None

NextPoint:None

NextPoint:None

Api调用链记录

$array = Point::toArray($point);

可以把一个入口点转为一个数组。例如我们可以在MYSQL数据库中存储以下关键结构:

CREATE TABLE `api_tracker_point_list` (

`pointd` varchar(18) NOT NULL,

`pointName` varchar(45) 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,

`status` varchar(10) NOT NULL,

PRIMARY KEY (`pointd`),

UNIQUE KEY `trackerId_UNIQUE` (`pointd`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

其余请求参数可以自己记录。

核心字段在pointId,parentId与isNext,status 这四个个字段,例如,我想得到哪次调用链超时,那么就是直接

where status = fail

如果想看哪次调用耗时多少,那么可以

where spendTime > 3

spendTime 是用startTime和endTime计算

相关仓库

EasySwoole之链路追踪 简单demo

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

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

相关文章

razor java,如何在Razor中声明局部变量?

我正在asp.net mvc 3中开发一个Web应用程序。我对它很新。 在使用剃刀的视图中,我想声明一些局部变量并在整个页面中使用它。 如何才能做到这一点?能够执行以下操作似乎相当微不足道:bool isUserConnected string.IsNullOrEmpty(Model.Creat…

amp 符号 php,php中引用符号(amp;)的使用详解_PHP教程

与C语言中的指针是有差别的.C语言中的指针里面存储的是变量的内容在内存中存放的地址变量的引用.PHP 的引用允许你用两个变量来指向同一个内容复制代码 代码如下:$a"ABC";$b &$a;echo $a;//这里输出:ABCecho $b;//这里输出:ABC…

oracle ora 00283,【案例】Oracle报错ORA-16433非归档丢失redo无法启动的恢复过程

天萃荷净Oracle研究中心案例分析:运维DBA反映Oracle数据库处理非归档模式,redo文件损坏常规修复无法正常open数据库。本站文章除注明转载外,均为本站原创: 转载自love wife & love life —Roger 的Oracle技术博客本文链接地址…

win7卸载oracle12c,Windows7上完全卸载Oracle 12c操作步骤

Windows7上完全卸载Oracle 12c操作步骤1.关闭Oracle所有的服务,按【winR】运行【services.msc】找到所有Oracle开头的服务(OracleVssWriterORCLOracleServiceORCLOracleOraDB12Home1TNSListenerOracleOraDB12Home1MTSRecoveryServiceOracleJobSchedulerORCL),点击停止。2.使用O…

图像灰度映射实验MATLAB,图像灰度变换实验报告

实验2a 图像的灰度变换一、实验目的:学会用Matlab软件对图像进行运算和灰度变换。二、实验内容:用、-、*、/、imabsdiff、imadd、imcomplment、imdivide、imlincomb、immultiply、imsubtract和imadjust等函数生成各类灰度变换图像。三、实验相关知识1、代…

oracle深度巡检指标,oracle DBA 巡检项目

11.Oracle审计-AUD$占用空间较大处理方案truncate 或者 delete sys.aud$ 表在delete 之前,可以先把aud$表exp备份一下,注意,不要直接exp,先创建一张临时表,然后将临时表exp。sql>create table audit_record tablesp…

eclipse oracle驱动位置,【求助】eclipse导入了Oracle的驱动包连不上Oracle

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼代码:package com.sp;import java.sql.*;//演示JDBC连接public class OraDemo2 {public static void main(String[] args) throws ReflectiveOperationException, SQLException {// TODO Auto-generated method stub//1…

oracle系统实验,实验1 启动Oracle系统

启动Oracle系统一、开启Oracle服务1、控制面板---管理工具----服务---或Oracle中的配置和移植工具—Oracle Administration Assistant for Windows 用右键单击“数据库中的SID名”,选择启动服务启动以下服务:OracleService 对应数据库实例OracleTNSListe…

linux怎样扩容目录,Linux系统下对目录扩容的方法介绍

1、现象:日志服务器当初考虑不周,分区划分不太合理:2、目标:将/home磁盘空间缩减 并将新的磁盘分区扩充到/根目录卸载/home分区并压缩分区卸载/home时 提示目标忙,fuser -m /home查看谁用/home时提示没有fuser命令[ro…

linux部署多个tomcat服务,Linux 一台服务器部署多个tomcat

linux系统下安装两个或多个tomcat编辑环境变量:vi /etc/profile加入以下代码(tomcat路径要配置自己实际的tomcat安装目录)##########first tomcat###########CATALINA_BASE/usr/local/tomcatCATALINA_HOME/usr/local/tomcatTOMCAT_HOME/usr/local/tomcatexport CATA…

在linux中编写shell脚本文件,如何编写简单的Shell脚本(Script)文件之Linux的基本操作...

如何编写简单的Shell脚本(Script)文件之Linux的基本操作新建一个文本文件包含所需要的脚本。举例,我会使用pico编辑器写一个脚本用来运行程序tar,带上必要的可选项可以用来解压从因特网下载下来的*.tar的文件(我好像总是记不住tar的所有参赛)。滑动轴承 …

Linux钩子拦截删除文件,在Linux中保存钩子文件

您可以尝试FILE_PRELOAD utility,它们会生成带钩子的C代码,编译和LD_PRELOAD它。在简短的看了一下之后,你可以感觉到如何轻松地挂接linux。起点是this tutorial。例如,如果你想改变文件/ tmp的“公开征集” /一些带有的/ tmp/repl…

Linux内核怎么优化,linux 内核该怎么优化

Linux系统下,TCP连接断开后,会以TIME_WAIT状态保留一定的时间,然后才会释放端口。当并发请求过多的时候,就会产生大量的TIME_WAIT状态的连接,无法及时断开的话,会占用大量的端口资源和服务器资源。这个时候…

编译linux内核适用的编译器,编译Linux内核时,CC,LD和CC [M]输出的代码是什么?...

所以一般情况下,你只需要 git grep cmd.* CODE找到CODE。获取scripts/Makefile.build定义的所有代码 make | grep -E ^ | sort -uk1,1CC和CC [M]名单: quiet_cmd_cc_o_c CC $(quiet_modtag) [email protected]cmd_cc_o_c $(CC) $(c_flags) -c -o [em…

红旗linux修改个人密码,LINUX红旗5.0的用户名和密码!

怎样卸载、安装红旗linux本二,安装红旗Linux桌面版 4。0将光驱设为第一启动盘,放入第一张安装光盘后重新启动电脑,如果你的光驱支持自启动, 如无意外将出现如下图1如果不进行操作,在10秒后自动进入下一画面,显示如下图2所示一启动就能使用鼠标了,比效方便;软件协议,只能选同意,…

linux多线程九宫格,项目实战:Qt九宫格图片资源浏览器(支持window、linux、兼容各国产系统,支持子文件夹,多选,全选,图片预览,行数与列数设置等)...

需求做嵌入式设备,需求九宫格图片资源浏览器:1.设置根目录;2.可拖动;3.可设置列数与行数;4.点击文件夹可以进入文件夹;5.点击图片可以浏览图片;6.支持触摸屏上下拽拖浏览;7.支持长安…

linux mdev -s没有运行,mdev详解

一、概述mdev是busybox提供的一个工具,用在嵌入式系统中,相当于简化版的udev,作用是在系统启动和热插拔或动态加载驱动程序时,自动创建设备节点。文件系统中的/dev目录下的设备节点都是由mdev创建的。在加载驱动过程中&#xff0c…

linux x86-64下,Linux x86_64下安装Flash Player 9

家里 Linux 安装已经有几天了,可是用 Firefox 浏览网页总是看不到 Flash。到了 Adobe 官方去下载了 Flash 插件,结果安装的时候说它不支持 x86_64,安装计划就一直搁浅。天天上网看见“缺失插件”的框框,非常不爽,所以就…

window连接树莓派linux桌面,远程连接Raspberry Pi(树莓派)图形用户界面(X Window)

背景:有的时候,我们希望能远程连接一台linux的图形界面用来管理机器,这里需要用到tightvncserver和xtightvncviewer两个工具我的树莓派的ip是10.141.247.134 另一台机器为作client去链接树莓派的ip为10.141.247.121. 先在树莓派的机器上安装tightvncs…

linux小红帽系统能用微信,小红帽腾讯QQ微信登录版-小红帽腾讯版v1.0.3 安卓版-腾牛安卓网...

小红帽腾讯版是一款专为广大喜爱玩童话类手游的玩家打造的欧美风游戏,这款游戏有着最为精致的游戏画面,黑色风格的童话故事,带领玩家领略不一样的童年世界,给您带来最佳的游戏体验!小红帽腾讯版简介《小红帽》是一款改…