zoukankan      html  css  js  c++  java
  • PHP实现opentracing jaeger链路追踪

    开发环境:

    php >= 5.6

    linux环境 必须安装thrift

    omposer require opentracing/opentracing  1.0.0-beta5
    composer require jukylin/jaeger-php v2.1.3

     下面展示一个进程内和跨进程的访问

    http代码中分别请求了crm.ichunt.com,baidu.com;在访问了baidu.com嵌套了子span访问ichunt.com;接下来访问http2.php

    http2代码中 访问了ichunt.com和crm.ichunt.com

    <?php
    /*
     * Copyright (c) 2019, The Jaeger Authors
     *
     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
     * in compliance with the License. You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software distributed under the License
     * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
     * or implied. See the License for the specific language governing permissions and limitations under
     * the License.
     */
    
    require_once './vendor/autoload.php';
    
    use JaegerConfig;
    use GuzzleHttpClient;
    use OpenTracingFormats;
    use OpenTracingReference;
    
    unset($_SERVER['argv']);
    
    set_time_limit(0);
    //init server span start
    $config = Config::getInstance();
    $config->gen128bit();
    $config::$propagator = JaegerConstantsPROPAGATOR_JAEGER;
    $tracer = $config->initTracer('example-php', '192.168.1.234:6831');
    $injectTarget = [];
    $spanContext = $tracer->extract(FormatsTEXT_MAP, $_SERVER);
    echo sprintf("parent-spanContext %s <br>",print_r($spanContext,true));
    if(!$spanContext){
        $serverSpan = $tracer->startSpan('example HTTP');
    }else{
        $serverSpan = $tracer->startSpan('example HTTP', ['references' => [
            Reference::create(Reference::FOLLOWS_FROM, $spanContext),
            Reference::create(Reference::CHILD_OF, $spanContext)
        ]]);
    }
    $serverSpan->addBaggageItem("version", "1.8.9");
    $serverSpan->setTag("serverSpan-key","serverSpan-value");
    $tracer->inject($serverSpan->getContext(), FormatsTEXT_MAP, $_SERVER);
    //init server span end
    $clientTracer = $config->initTracer('HTTP');
    
    
    
    
    
    
    //client span1 start
    $injectTarget1 = [];
    $spanContext1 = $clientTracer->extract(FormatsTEXT_MAP, $_SERVER);
    echo sprintf("spanContext1 %s <br>",print_r($spanContext1,true));
    $clientSpan1 = $clientTracer->startSpan('request1', ['child_of' => $spanContext1]);
    $clientTracer->inject($clientSpan1->spanContext, FormatsTEXT_MAP, $injectTarget1);
    
    $method = 'GET';
    $url = 'http://baidu.com/';
    $client = new Client();
    $res = $client->request($method, $url,['headers' => $injectTarget1]);
    
    $clientSpan1->setTag('http.status_code', 200);
    $clientSpan1->setTag('http.method', 'GET');
    $clientSpan1->setTag('http.url', $url);
    $clientSpan1->addBaggageItem("event","event-HTTP1-value");
    $clientSpan1->log(['message' => "HTTP1 ". $method .' '. $url .' end !']);
    $clientSpan1->finish();
    //client span1 end
    
    //--------------------------------------------------------------------------------------------
    
    //client span2 start
    $injectTarget2 = [];
    $spanContext2 = $clientTracer->extract(FormatsTEXT_MAP,$_SERVER);
    echo sprintf("spanContext2 %s <br>",print_r($spanContext2,true));
    $clientSpan2 = $clientTracer->startSpan('request2',['references' => [
        Reference::create(Reference::FOLLOWS_FROM, $clientSpan1->spanContext),
        Reference::create(Reference::CHILD_OF, $spanContext1)
    ]]);
    $clientTracer->inject($clientSpan2->spanContext, FormatsTEXT_MAP, $injectTarget2);
    $method = 'GET';
    //$url = 'http://192.168.1.169:8088/http2.php';
    $url = 'http://ichunt.com/';
    $client = new Client();
    $res = $client->request($method, $url, ['headers' => $injectTarget2]);
    $clientSpan2->setTag('http.status_code', 200);
    $clientSpan2->setTag('http.method', 'GET');
    $clientSpan2->setTag('http.url', $url);
    $clientSpan2->log(['message' => "HTTP2 ". $method .' '. $url .' end !']);
    $clientSpan2->finish();
    ////client span2 end
    
    
    //--------------------------------------------------------------------------------------------
    
    
    
    //client span3 start
    $injectTarget3 = [];
    $spanContext3 = $clientTracer->extract(FormatsTEXT_MAP,$_SERVER);
    echo sprintf("spanContext3 %s <br>",print_r($spanContext3,true));
    $clientSpan3 = $clientTracer->startSpan('request3',
        ['references' => [
            Reference::create(Reference::FOLLOWS_FROM, $spanContext3),
            Reference::create(Reference::CHILD_OF, $spanContext3)
        ]]);
    $clientTracer->inject($clientSpan3->spanContext, FormatsTEXT_MAP, $injectTarget3);
    $method = 'GET';
    $url = 'http://crm.ichunt.net/';
    $client = new Client();
    $res = $client->request($method, $url, ['headers' => $injectTarget3]);
    
    $clientSpan3->setTag('http.status_code', 200);
    $clientSpan3->setTag('http.method', 'GET');
    $clientSpan3->setTag('http.url', $url);
    
    $clientSpan3->log(['message' => "HTTP2 ". $method .' '. $url .' end !']);
    $clientSpan3->finish();
    ////client span3 end
    
    
    //--------------------------------------------------------------------------------------------
    
    //client span2 start
    $injectTarget4 = [];
    $spanContext4 = $clientTracer->extract(FormatsTEXT_MAP, $_SERVER);
    echo sprintf("spanContext4 %s <br>",print_r($spanContext4,true));
    $clientSpan4 = $clientTracer->startSpan('request4',
        ['references' => [
            Reference::create(Reference::FOLLOWS_FROM, $spanContext4),
            Reference::create(Reference::CHILD_OF, $spanContext4)
        ]]);
    
    $clientTracer->inject($clientSpan4->spanContext, FormatsTEXT_MAP, $injectTarget4);
    
    $method = 'GET';
    $url = 'http://192.168.1.169/http2.php';
    $client = new Client();
    $res = $client->request($method, $url, ['headers' => $injectTarget4]);
    
    $clientSpan4->setTag('http.status_code', 200);
    $clientSpan4->setTag('http.method', 'GET');
    $clientSpan4->setTag('http.url', $url);
    
    $clientSpan4->log(['message' => "HTTP2 ". $method .' '. $url .' end !']);
    $clientSpan4->finish();
    //client span2 end
    
    
    
    
    
    
    
    
    
    
    
    
    
    ////server span end
    $serverSpan->finish();
    //trace flush
    $config->flush();
    
    echo "success
    ";
    http.php
    <?php
    /*
     * Copyright (c) 2019, The Jaeger Authors
     *
     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
     * in compliance with the License. You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software distributed under the License
     * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
     * or implied. See the License for the specific language governing permissions and limitations under
     * the License.
     */
    
    require_once './vendor/autoload.php';
    
    use JaegerConfig;
    use GuzzleHttpClient;
    use OpenTracingFormats;
    use OpenTracingReference;
    
    unset($_SERVER['argv']);
    
    
    function getAllHeaders()
    {
        $headers = array();
    
        $copy_server = array(
            'CONTENT_TYPE'   => 'Content-Type',
            'CONTENT_LENGTH' => 'Content-Length',
            'CONTENT_MD5'    => 'Content-Md5',
        );
    
        foreach ($_SERVER as $key => $value) {
            if (substr($key, 0, 5) === 'HTTP_') {
                $key = substr($key, 5);
                if (!isset($copy_server[$key]) || !isset($_SERVER[$key])) {
                    $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key))));
                    $headers[$key] = $value;
                }
            } elseif (isset($copy_server[$key])) {
                $headers[$copy_server[$key]] = $value;
            }
        }
    
        if (!isset($headers['Authorization'])) {
            if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
                $headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
            } elseif (isset($_SERVER['PHP_AUTH_USER'])) {
                $basic_pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
                $headers['Authorization'] = 'Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $basic_pass);
            } elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) {
                $headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST'];
            }
        }
    
        return $headers;
    }
    
    $config = Config::getInstance();
    $config->gen128bit();
    $config::$propagator = JaegerConstantsPROPAGATOR_JAEGER;
    $tracer = $config->initTracer('http2-php', '192.168.1.234:6831');
    $spanContext = $tracer->extract(FormatsTEXT_MAP, getAllHeaders());
    if(!$spanContext){
        $serverSpan = $tracer->startSpan('Istio2');
    }else{
        $serverSpan = $tracer->startSpan('Istio2', ['references' => [
            Reference::create(Reference::FOLLOWS_FROM, $spanContext),
            Reference::create(Reference::CHILD_OF, $spanContext)
        ]]);
    }
    $serverSpan->setTag("parent","parent-span");
    $serverSpan->log(["parent"=>"parent-log"]);
    $tracer->inject($serverSpan->getContext(), FormatsTEXT_MAP, $_SERVER);
    
    $clientTracer = $config->initTracer('HTTP');
    
    
    //-------------------------
    $injectTarget2 = [];
    $spanContext = $clientTracer->extract(FormatsTEXT_MAP, $_SERVER);
    print_r($spanContext);
    if(!$spanContext){
        $clientSpan2 = $clientTracer->startSpan('request2');
    }else{
        $clientSpan2 = $clientTracer->startSpan('request2', ['references' => [
            Reference::create(Reference::FOLLOWS_FROM, $serverSpan->spanContext),
            Reference::create(Reference::CHILD_OF, $spanContext)
        ]]);
    }
    
    $clientTracer->inject($clientSpan2->spanContext, FormatsTEXT_MAP, $injectTarget2);
    $method = 'GET';
    $url = 'http://ichunt.com/';
    $client = new Client();
    $res = $client->request($method, $url, ['headers' => $injectTarget2]);
    $clientSpan2->setTag('http.status_code', 200);
    $clientSpan2->setTag('http.method', 'GET');
    $clientSpan2->setTag('http.url', $url);
    $clientSpan2->log(['message' => "HTTP2 ". $method .' '. $url .' end !']);
    $clientSpan2->finish();
    //---------------------------------------
    
    
    //client span3 start
    $injectTarget3 = [];
    $spanContext3 = $clientTracer->extract(FormatsTEXT_MAP,$_SERVER);
    print_r($spanContext3);
    if(!$spanContext3){
        $clientSpan3 = $clientTracer->startSpan('request3');
    }else{
        $clientSpan3 = $clientTracer->startSpan('request3',
            ['references' => [
                Reference::create(Reference::FOLLOWS_FROM, $spanContext3),
                Reference::create(Reference::CHILD_OF, $spanContext3)
            ]]);
    }
    $clientTracer->inject($clientSpan3->spanContext, FormatsTEXT_MAP, $injectTarget3);
    $method = 'GET';
    $url = 'http://crm.ichunt.net/';
    $client = new Client();
    $res = $client->request($method, $url, ['headers' => $injectTarget3]);
    
    $clientSpan3->setTag('http.status_code', 200);
    $clientSpan3->setTag('http.method', 'GET');
    $clientSpan3->setTag('http.url', $url);
    
    $clientSpan3->log(['message' => "HTTP2 ". $method .' '. $url .' end !']);
    $clientSpan3->finish();
    ////client span3 end
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    ////server span end
    $serverSpan->finish();
    //trace flush
    $config->flush();
    
    echo "success
    ";
    http2.php

     

    对上面代码进行封装:

    JaegerInject.php
    <?phpnamespace CommonService;
    
    use JaegerConfig as Jconfing;
    use OpenTracingFormats;
    use OpenTracingReference;
    
    
    class JaegerInject
    {
    
        protected $dsn = '192.168.1.234:6831';
    
        protected $serviceName;
        protected $spanList = [];
        protected $client;
        protected $tracer;
        protected $clientTracer;
    
        public function __construct($serviceName = 'opentarcing-php',$parentSpanName="")
        {
            $this->serviceName = $serviceName;
            unset($_SERVER['argv']);
            $this->client = Jconfing::getInstance();
            Jconfing::$propagator = JaegerConstantsPROPAGATOR_JAEGER;
            $this->client->gen128bit();
            $this->tracer = $this->client->initTracer($this->serviceName, $this->dsn);
            $parentContext = $this->tracer->extract(FormatsTEXT_MAP, $this->getAllHeaders());
            if (!$parentContext) {
                $serverSpan = $this->tracer->startSpan($parentSpanName);
            } else {
                $serverSpan = $this->tracer->startSpan($parentSpanName, ['references' => [
                    Reference::create(Reference::FOLLOWS_FROM, $parentContext),
                    Reference::create(Reference::CHILD_OF, $parentContext)
                ]]);
            }
            $serverSpan->setTag("parent","123");
            $this->tracer->inject($serverSpan->getContext(),FormatsTEXT_MAP, $_SERVER);
            $this->clientTracer = $this->client->initTracer('HTTP');
            $this->spanList[$parentSpanName]=[
                "current_span"=>$serverSpan,
                "parent_context"=>$parentContext
            ];
        }
    
    
        public function getSpanName($spanName){
            return isset($this->spanList[$spanName]) ? $this->spanList[$spanName]["current_span"] : "";
        }
    
            public function setTag($spanName,$key="",$value=""){
            if(!isset($this->spanList[$spanName])){
                return ;
            }
            $info = $this->spanList[$spanName];
            $span = $info['current_span'];
            $span->setTag($key,$value);
        }
    
    
        public function log($spanName,$key="",$value=""){
            if(!isset($this->spanList[$spanName])){
                return ;
            }
            $info = $this->spanList[$spanName];
            $span = $info['current_span'];
            $span->log([$key=>$value]);
        }
    
    
        public function start($spanName,$parentSpan="")
        {
            $spanContext = $this->clientTracer->extract(FormatsTEXT_MAP, $_SERVER);
            $clientrSpan = null;
            $parentSpanIsObj = $parentSpan && gettype($parentSpan) == "object";
            if (!$spanContext) {
                $clientrSpan = $this->tracer->startSpan($spanName);
            } else {
                $clientrSpan = $this->tracer->startSpan($spanName, ['references' => [
                    Reference::create(Reference::FOLLOWS_FROM, $parentSpanIsObj ? $parentSpan->spanContext :$spanContext),
                    Reference::create(Reference::CHILD_OF, $spanContext)
                ]]);
            }
    
            $this->spanList[$spanName]=[
                "current_span"=>$clientrSpan,
                "parent_context"=>$parentSpanIsObj ? $parentSpan->spanContext :$spanContext,
            ];
        }
    
    
        public function inject($spanName)
        {
            $info = $this->spanList[$spanName];
            $span = $info['current_span'];
            $injectHeaders = [];
            $this->clientTracer->inject($span->getContext(), FormatsTEXT_MAP, $injectHeaders);
            return $injectHeaders;
        }
    
    
        public function finish( $spanName, array $spanList = [])
        {
            $info = $this->spanList[$spanName];
    
            $span = $info['current_span'];
            $parentContext = $info['parent_context'];
    
            $span->setTag('parentSpan', $parentContext ? $parentContext->spanIdToString() : '');
            foreach($spanList ?: [] as $k => $v){
                $span->setTag($k, $v);
            }
            $span->finish();
        }
    
    
    
    
    
        private function getAllHeaders()
        {
            $headers = array();
    
            $copy_server = array(
                'CONTENT_TYPE'   => 'Content-Type',
                'CONTENT_LENGTH' => 'Content-Length',
                'CONTENT_MD5'    => 'Content-Md5',
            );
    
            foreach ($_SERVER as $key => $value) {
                if (substr($key, 0, 5) === 'HTTP_') {
                    $key = substr($key, 5);
                    if (!isset($copy_server[$key]) || !isset($_SERVER[$key])) {
                        $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key))));
                        $headers[$key] = $value;
                    }
                } elseif (isset($copy_server[$key])) {
                    $headers[$copy_server[$key]] = $value;
                }
            }
    
            if (!isset($headers['Authorization'])) {
                if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
                    $headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
                } elseif (isset($_SERVER['PHP_AUTH_USER'])) {
                    $basic_pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
                    $headers['Authorization'] = 'Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $basic_pass);
                } elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) {
                    $headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST'];
                }
            }
    
            return $headers;
        }
    
        public function __destruct()
        {
            $this->client->flush();
        }
    
    }
    public function opentarcing_one(){
            $jaeger = new CommonServiceJaegerInject("opentarcing-php","opentarcing_one");
            $jaeger->setTag("opentarcing_one","事件","创建订单");
            $jaeger->log("opentarcing_one","请求参数",json_encode(cookie()));
    
    
            $spanName = "order-admin";
            $jaeger->start($spanName);
            $injectHeaders = $jaeger->inject($spanName);
            $client =  new GuzzleHttpClient;
            $method = 'GET';
            $url = 'http://crm.ichunt.net/';
            $res = $client->request($method, $url, ['headers' => $injectHeaders]);
    
            $jaeger->finish($spanName, ['time' => date('Y-m-d H:i:s')]);
    
    
            $spanName = "ichunt-api";
            $jaeger->start($spanName);
            $injectHeaders = $jaeger->inject($spanName);
            $client =  new GuzzleHttpClient;
            $method = 'GET';
            $url = 'http://order.ichunt.net/';
            $res = $client->request($method, $url, ['headers' => $injectHeaders]);
            $jaeger->finish($spanName, ['time' => date('Y-m-d H:i:s')]);
    
    
    
            //--------------crm.net-----下包含子span---crm.child.net------------------------------
            $spanName = "crm.net";
            $jaeger->start($spanName);
            $injectHeaders = $jaeger->inject($spanName);
            $client =  new GuzzleHttpClient;
            $method = 'GET';
            $url = 'http://label.ichunt.net/';
            $res = $client->request($method, $url, ['headers' => $injectHeaders]);
            $jaeger->finish($spanName, ['time' => date('Y-m-d H:i:s')]);
    
    
            $spanName = "crm.child.net";
            $parentSpanName = $jaeger->getSpanName("crm.net");
            $jaeger->start($spanName,$parentSpanName);
            $injectHeaders = $jaeger->inject($spanName);
            $client =  new GuzzleHttpClient;
            $method = 'GET';
            $url = 'http://crm.ichunt.net/';
            $res = $client->request($method, $url, ['headers' => $injectHeaders]);
            $jaeger->finish($spanName, ['time' => date('Y-m-d H:i:s')]);
    
            //----------------crm.net-----下包含子span---crm.child.net-------------------------------
    
    
    
            $spanName = "跨进程访问http2.php";
            $jaeger->start($spanName);
    
            $injectHeaders = $jaeger->inject($spanName);
            $client =  new GuzzleHttpClient;
            $method = 'GET';
            $url = 'http://api.liexin.com/order/test/opentarcing_two';
            $jar = new GuzzleHttpCookieCookieJar();
            $cookieJar = $jar->fromArray(cookie(), "liexin.com");
            $res = $client->request($method, $url, ['headers' => $injectHeaders,"cookies"=>$cookieJar]);
    //        dump(cookie());
    //        $res = post_curl($url,[],$injectHeaders);
    
            $jaeger->finish($spanName, ['time' => date('Y-m-d H:i:s')]);
    
    
        }
    
        public function opentarcing_two()
        {
            $jaeger = new CommonServiceJaegerInject("opentarcing-php","opentarcing_two");
    
            $spanName = "crm.net";
            $jaeger->start($spanName);
            $injectHeaders = $jaeger->inject($spanName);
            $client =  new GuzzleHttpClient;
            $method = 'GET';
            $url = 'http://label.ichunt.net/';
            $res = $client->request($method, $url, ['headers' => $injectHeaders]);
            $jaeger->finish($spanName, ['time' => date('Y-m-d H:i:s')]);
    
    
            $spanName = "crm.child.net";
            $parentSpanName = $jaeger->getSpanName("crm.net");
            $jaeger->start($spanName,$parentSpanName);
            $injectHeaders = $jaeger->inject($spanName);
            $client =  new GuzzleHttpClient;
            $method = 'GET';
            $url = 'http://crm.ichunt.net/';
            $res = $client->request($method, $url, ['headers' => $injectHeaders]);
            $jaeger->finish($spanName, ['time' => date('Y-m-d H:i:s')]);
    
        }

     

    生产场景使用后优化代码

    上述代码在生产实践中发现每次实例化一个JaegerInject对象就会创建一个udp请求;

    优化目的:一次请求创建一次udp请求

    建议:使用中尽量能使用同一个JaegerInject对象

    checkPhpUname方法 为了防止windows电脑上无法运行thirft
    /*
     * 判断运行环境是否是linux
     */
    function checkPhpUname(){
        $os_name = PHP_OS;
        if(strpos($os_name,"Linux")!==false){
            return true;
        }else{
            return false;
        }
    }
    <?php
    namespace CommonService;
    
    use JaegerConfig as Jconfing;
    use OpenTracingFormats;
    use OpenTracingReference;
    
    
    class JaegerInject
    {
    
        protected $dsn = '192.168.1.234:6831';
    
        protected $serviceName;
        public static $spanList = [];
        protected $client;
        protected $tracer;
        protected $clientTracer;
        protected $uname;//开发环境 window mac  linux
        public static $parentSpanName = null;
        public static $instance = null;
    
    
    
        private function __construct(){
    
        }
    
    
        private function __clone(){
    
        }
    
        public static function getInstance()
        {
            if(! (self::$instance instanceof self) )
            {
                self::$instance = new self();
            }
            return self::$instance;
        }
    
    
        protected  function getClientIp()
        {
            $ip = '0.0.0.0';
            if (getenv('HTTP_CLIENT_IP')) {
                $ip = getenv('HTTP_CLIENT_IP');
            }
            if (getenv('HTTP_X_REAL_IP')) {
                $ip = getenv('HTTP_X_REAL_IP');
            } elseif (getenv('HTTP_X_FORWARDED_FOR')) {
                $ip = getenv('HTTP_X_FORWARDED_FOR');
                $ips = explode(',', $ip);
                $ip = $ips[0];
            } elseif (getenv('REMOTE_ADDR')) {
                $ip = getenv('REMOTE_ADDR');
            }
    
            return $ip;
        }
    
    
        public function getSpanName($spanName){
            if(!$this->uname){
                return "";
            }
    
            return isset(static::$spanList[$spanName]) ? static::$spanList[$spanName]["current_span"] : "";
        }
    
    
        public function setTag($spanName,$key="",$value=""){
            if(!$this->uname){
                return "";
            }
            if(!isset(static::$spanList[$spanName])){
                return ;
            }
            $info = static::$spanList[$spanName];
            $span = $info['current_span'];
            $span->setTag($key,$value);
        }
    
    
        /*
         * 记录链路追踪日志
         */
        public function log($spanName,$key="",$value=""){
            if(!$this->uname){
                return "";
            }
            if(!isset(static::$spanList[$spanName])){
                return ;
            }
            $info = static::$spanList[$spanName];
            $span = $info['current_span'];
            if($key && $value){
                $span->log([$key=>$value]);
            }else if($key && !$value){
                $span->log(["message"=>$key]);
            }
        }
    
    
        /*
         * 創建父span
         */
        public function init($parentSpanName=""){
    
            $this->serviceName = C("OPENTRACING_JAEGER_SERVERNAME");
            $this->client = Jconfing::getInstance();
            Jconfing::$propagator = JaegerConstantsPROPAGATOR_JAEGER;
            $this->client->gen128bit();
            $this->tracer = $this->client->initTracer($this->serviceName, C("OPENTRACING_JAEGER_DNS"));
    
            if(!static::$parentSpanName && !$parentSpanName){
                static::$parentSpanName = "未知的spanName";
                if(isset($_SERVER['REQUEST_URI']) && $_SERVER['REQUEST_URI']){
                    $requestUrl = explode("?",$_SERVER['REQUEST_URI']);
                    static::$parentSpanName = !empty($requestUrl) ? $requestUrl[0] : static::$parentSpanName;
                }
    
            }
    
            if($parentSpanName && !static::$parentSpanName){
                static::$parentSpanName =  $parentSpanName;
            }
    
            if(!isset(static::$spanList[static::$parentSpanName])) {
                if(!checkPhpUname()){
                    $this->uname = false;
                    return ;
                }else{
                    $this->uname = true;
                }
                $this->startPrentSpan();
            }
        }
    
    
        public function simpleInit($parentSpanName="",$spanName=""){
            $this->init($parentSpanName);
            $this->start($spanName);
            $injectHeaders = $this->inject($spanName);
            return $injectHeaders;
        }
    
        public function simpleInject($spanName,$preSpanName=""){
            if($preSpanName){
                $preSpanName = $this->getSpanName($preSpanName);
            }
            $this->start($spanName,$preSpanName);
            $injectHeaders = $this->inject($spanName);
            return $injectHeaders;
        }
    
        protected function startPrentSpan(){
            $parentSpanName = static::$parentSpanName;
            $parentContext = $this->tracer->extract(FormatsTEXT_MAP, $this->getAllHeaders());
    //        dump($parentContext);
            if (!$parentContext) {
                $serverSpan = $this->tracer->startSpan($parentSpanName);
            } else {
                $serverSpan = $this->tracer->startSpan($parentSpanName, ['references' => [
                    Reference::create(Reference::FOLLOWS_FROM, $parentContext),
                    Reference::create(Reference::CHILD_OF, $parentContext)
                ]]);
            }
            $serverSpan->setTag("http_host",$this->getClientIp());
            $serverSpan->setTag("time",date("Y-m-d H:i:s"));
            if(isset($_SERVER['REQUEST_SCHEME'])){
                $serverSpan->setTag("request_scheme",$_SERVER['REQUEST_SCHEME']);
            }
            if(isset($_SERVER['REQUEST_URI'])){
                $serverSpan->setTag("request_uri",$_SERVER['REQUEST_URI']);
            }
    
            if(!empty($_REQUEST)){
                $serverSpan->log(["request_params"=>json_encode($_REQUEST)]);
            }
    
            $this->tracer->inject($serverSpan->getContext(),FormatsTEXT_MAP, $_SERVER);
            $this->clientTracer = $this->client->initTracer('HTTP');
            static::$spanList[$parentSpanName]=[
                "current_span"=>$serverSpan,
                "parent_context"=>$parentContext
            ];
        }
    
    
        /*
         * 創建子span
         */
        public function start($spanName,$parentSpan="")
        {
            if(!$this->uname){
                return ;
            }
    
            $spanContext = $this->clientTracer->extract(FormatsTEXT_MAP, $_SERVER);
            $clientrSpan = null;
            $parentSpanIsObj = $parentSpan && gettype($parentSpan) == "object";
            if (!$spanContext) {
                $clientrSpan = $this->tracer->startSpan($spanName);
            } else {
                $clientrSpan = $this->tracer->startSpan($spanName, ['references' => [
                    Reference::create(Reference::FOLLOWS_FROM, $parentSpanIsObj ? $parentSpan->spanContext :$spanContext),
                    Reference::create(Reference::CHILD_OF, $spanContext)
                ]]);
            }
    
            static::$spanList[$spanName]=[
                "current_span"=>$clientrSpan,
                "parent_context"=>$parentSpanIsObj ? $parentSpan->spanContext :$spanContext,
            ];
        }
    
    
        public function inject($spanName)
        {
            if(!$this->uname){
                return [];
            }
            if(!isset(static::$spanList[$spanName])){
                return [];
            }
            $info = static::$spanList[$spanName];
            $span = $info['current_span'];
            $injectHeaders = [];
            $this->clientTracer->inject($span->getContext(), FormatsTEXT_MAP, $injectHeaders);
            return $injectHeaders;
        }
    
    
        public function finish( $spanName, array $spanList = [])
        {
            if(!$this->uname){
                return;
            }
            if(!isset(static::$spanList[$spanName])){
                return;
            }
            $info = static::$spanList[$spanName];
    
            $span = $info['current_span'];
            $parentContext = $info['parent_context'];
    
            $span->setTag('parentSpan', $parentContext ? $parentContext->spanIdToString() : '');
            $span->setTag("time",date("Y-m-d H:i:s"));
            foreach($spanList ?: [] as $k => $v){
                $span->setTag($k, $v);
            }
            $span->finish();
        }
    
    
    
    
    
        private function getAllHeaders()
        {
            $headers = array();
    
            $copy_server = array(
                'CONTENT_TYPE'   => 'Content-Type',
                'CONTENT_LENGTH' => 'Content-Length',
                'CONTENT_MD5'    => 'Content-Md5',
            );
    
            foreach ($_SERVER as $key => $value) {
                if (substr($key, 0, 5) === 'HTTP_') {
                    $key = substr($key, 5);
                    if (!isset($copy_server[$key]) || !isset($_SERVER[$key])) {
                        $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key))));
                        $headers[$key] = $value;
                    }
                } elseif (isset($copy_server[$key])) {
                    $headers[$copy_server[$key]] = $value;
                }
            }
    
            if(isset($_SERVER["UBER-TRACE-ID"])){
                $headers["UBER-TRACE-ID"] = $_SERVER["UBER-TRACE-ID"];
            }
    
            if (!isset($headers['Authorization'])) {
                if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
                    $headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
                } elseif (isset($_SERVER['PHP_AUTH_USER'])) {
                    $basic_pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
                    $headers['Authorization'] = 'Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $basic_pass);
                } elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) {
                    $headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST'];
                }
            }
    
            return $headers;
        }
    
        public function __destruct()
        {
            if(!$this->uname){
                return ;
            }
            $this->client->flush();
        }
    
    }
    JaegerInject

    正常情况下在项目基类里面实例化一个对象 ,全局调用即可

    $this->opentracingJager = CommonServiceJaegerInject::getInstance();

    接下来在支付会调用使用:

    //顶级span
    $this->opentracingJager->init("pay");
    //....项目代码.........
    //添加tag标签
    $this->opentracingJager->setTag("pay","action","returnUrl");
    $this->opentracingJager->setTag("pay","remark",sprintf("--支付同步回调--"));
    //....项目代码.........
    //添加日志
    $this->opentracingJager->log("pay",sprintf("支付、充值同步回调异常:%s",json_encode($res)));
    //....项目代码.........
    
    
    //添加兄弟层span
    $this->opentracingJager->simpleInject("payment");
    $this->opentracingJager->log("payment","Pay->response()返回的数据",sprintf("%s",json_encode($arr)));
    //....项目代码.........
    $this->opentracingJager->finish("payment");
    
    
    
    
    //....项目代码.........
    $this->opentracingJager->finish("pay");
    
    
    
    
    
    //添加一个子span
    //上述代码中如果需要在payment span下面添加子节点
    $this->opentracingJager->init("xxx");
    //$jaeger->simpleInject("xxx","父span名字");
    $jaeger->simpleInject("xxx","payment");
    //添加tag标签
    $this->opentracingJager->setTag("xxx","action","123");
    $this->opentracingJager->setTag("xxx","remark",sprintf("--支付同步回调--"));
    //添加日志
    $this->opentracingJager->log("xxx",sprintf("支付、充值同步回调异常:%s",json_encode($res)));
    
    //....项目代码.........
    $this->opentracingJager->finish("xxx");
  • 相关阅读:
    linux中按行读取指定行
    linux常用配置文件
    linux虚拟机设置网络
    jenkins新建一个robot脚本的job
    jenkins中配置邮件发送
    jenkins中robot framework插件安装
    Jenkins subversion svn插件安装失败
    jenkins节点启动
    {"non_field_errors":["Unable to log in with provided credentials."]}% 无法使用提供的凭据登录
    路径模板
  • 原文地址:https://www.cnblogs.com/sunlong88/p/15103072.html
Copyright © 2011-2022 走看看