Published on

YII框架Jaeger链路追踪应用

Authors
  • avatar
    Name
    Liant
    Twitter

YII框架Jaeger链路追踪应用

安装composer依赖

composer require jonahgeorge/jaeger-client-php
  • 项目配置

.env增加Jaeger配置

TRACER_ENABLE_GUZZLE=true

TRACER_DRIVER="jaeger"

JAEGER_REPORTING_HOST="web-jaeger.test.com"

JAEGER_REPORTING_PORT=5775

JAEGER_REPORTING_SAMPLER_PARAM=0.1 #采样概率

request 追加定义

  1. app/config/main.php 中 配置使用自定义request组件

  2. common/web/Request.php 增加 $jaegerSpan && $jaegerRootSpan

JaegerClient

复制本仓库下的 Jaeger/Yii/JaegerClient.php 文件到 common/concrete/ 下

  • 项目中使用
<?php

use common\concrete\JaegerClient;


$Jaeger = new JaegerClient();

/**
 * 写入Jaeger
 * @param string $operationName 操作名称
 * @param string $tagKey 标签
 * @param string|bool|int|float $tagValue 标签值
 */
$Jaeger->write("http request",'get user info','10003');


/**
 * 获取Jaeger 传递下游 Header
 * @param array $headers
 */ 
$header = \Yii::$app->request->getHeaders()->toArray();
$Jaeger->getJaegerHeader($header);
print_r($header); // 调试:打印结果

  • 记录sql和redis
复制本仓库下的Jaeger/Yii/db/的两个类Dbcommand.php、RedisConnection.php到common/db下
(在原来的基础上面新增了两个触发事件,替换了框架原本的db\command.php 和 redis\connection.php)

1、在配置文件 common/configmain.php 新增 
// 替换mysql类
Yii::$container->set(Command::class, common\db\DbCommand::class);

2、在配置文件 common/config/main-local.php 修改
use common\db\RedisConnection;
 'redis'   => [
            // 替换redis的类
            'class'    => RedisConnection::class,
            ...
            ...
            ]
            
3、监听相关定义的事件
复制本仓库下的Jaeger/Yii/events/QueryRecord.php 事件类到common/components/events
配置文件中 common/config/main.php 修改   
'bootstrap'  => ['common\components\events\QueryRecord']

4、curl请求传递header下游
/*
 * 	curl
 * 入参
 * 	  url     请求路径
 * 	  type    POST || GET
 * 	  body    请求数据数组
 * 	  headers 请求头数组
 * 	  $timeout 超时时间
 * 	  $two_way 是否二次握手
 */
if (!function_exists('sendCurl')) {
    function sendCurl($url, $type = 'POST', $body = array(), $headers = array(), $timeout = 0)
    {
        $Jaeger = JaegerClient::getInstance();
        $span = $Jaeger->write("curl", [
            "http.url" => $url,
            "http.method" => $type,
            "http.headers" => json_encode($headers,JSON_UNESCAPED_UNICODE)
        ]);
        $jaegerHeaders = [];
        $Jaeger->getJaegerHeader($jaegerHeaders);
        $headers = array_merge($jaegerHeaders, $headers);
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $type);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        //curl超时设置 0 表示无限等待
        if ($timeout > 0) {
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        }
        $response = $jaegerResponse = curl_exec($ch);
        curl_close($ch);
        if (is_array($jaegerResponse) || is_object($jaegerResponse)){
            $jaegerResponse = json_encode($jaegerResponse,JSON_UNESCAPED_UNICODE);
        }
        if($span){
            $span->setTag("http.response", $jaegerResponse);
            $span->finish();
        }
        return $response;
    }
}
trace
trace
trace