鏈路追蹤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.pswp.cn/news/530510.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/530510.shtml
英文地址,請注明出處:http://en.pswp.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 安卓版-騰牛安卓網...

小紅帽騰訊版是一款專為廣大喜愛玩童話類手游的玩家打造的歐美風游戲,這款游戲有著最為精致的游戲畫面,黑色風格的童話故事,帶領玩家領略不一樣的童年世界,給您帶來最佳的游戲體驗!小紅帽騰訊版簡介《小紅帽》是一款改…