TraceLog

2019-03-10 23:25:00
CJL
原创
1870
<?php
/**
 * 记录调用日志
 * User: chujilu
 */
class TraceLog
{
    private static $logger;
    private static $traceId;
    private static $spanId;
    private static $tmpSpanId;
    private static $zipkinOpen = true;
    private static $zipkinHost = 'http://*.*.*.*:9411';
    private static $data = array();
    //type = cs sr ss cr sa ca
    public static function info($type = 'cs', $tags = array(), $annotations = array(), $remoteEndpoint = array())
    {
        $traceId = self::getTraceId();
        $spanId = ($type == 'cs' || $type == 'cr' || $type == 'ca') ? self::getTmpSpanId() : self::getSpanId();
        self::zipkin($traceId, $spanId, $type, $tags, $annotations, $remoteEndpoint);
        return true;
    }
    public static function getTraceId()
    {
        if (kempty(self::$traceId)) {
            $traceId = isset($_GET['userTraceId']) ? $_GET['userTraceId'] : '';
            if (kempty($traceId)) {
                $traceId = self::generateTraceId();
            }
            self::$traceId = $traceId;
        }
        return self::$traceId;
    }
    public static function generateTraceId()
    {
        return base_convert(self::timestamp(), 10, 16);
    }
    public static function getTmpSpanId()
    {
        if (kempty(self::$tmpSpanId)) {
            self::$tmpSpanId = self::generateTraceId();
        }
        return self::$tmpSpanId;
    }
    public static function getNewTmpSpanId()
    {
        self::$tmpSpanId = self::generateTraceId();
        return self::$tmpSpanId;
    }
    public static function getSpanId()
    {
        if (empty(self::$spanId)) {
            self::$spanId = isset($_GET['userSpanId']) ? $_GET['userSpanId'] : '';
        }
        if (empty(self::$spanId)) {
            self::$spanId = self::generateTraceId();
        }
        return self::$spanId;
    }
    public static function zipkin($traceId, $spanId, $type, $tags, $annotations, $remoteEndpoint)
    {
        $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
        $port = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : '';
        $ip = Util::getIp(); //ip need adjust
        $op = XRequest::getValue('op'); //action name need adjust
        $query = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
        $firstType = substr($type, 0, 1);
        $secondType = substr($type, 1, 2);
        if ($firstType == 'c') {
            $kind = 'CLIENT';
        } else {
            $kind = 'SERVER';
        }
        if (!isset(self::$data[$spanId])) {
            $span = [
                "traceId" => $traceId,
                "name" => $op,
                "id" => $spanId,
                "kind" => $kind,
                "timestamp" => self::timestamp(),
                "duration" => 0,
                "debug" => true,
                "shared" => true,
                "parentId" => self::getSpanId(),
                'localEndpoint' => [
                    "serviceName" => $host,
                    "ipv4" => $ip,
                    "port" => $port,
                ],
                "annotations" => [
                ],
                "tags" => [
                    "{$kind}_queryParams" => $query,
                ]
            ];
        } else {
            $span = self::$data[$spanId];
        }
        $span['annotations'][] = [
            "timestamp" => self::timestamp(),
            "value" => $type,
        ];
        if ($kind == 'SERVER') {
            //$span['shared'] = false;
        }
        if (!kempty($remoteEndpoint)) {
            $span['remoteEndpoint'] = [
                "serviceName" => isset($remoteEndpoint['serviceName']) ? $remoteEndpoint['serviceName'] : '',
                "ipv4" => isset($remoteEndpoint['ipv4']) ? $remoteEndpoint['ipv4'] : '',
                "port" => isset($remoteEndpoint['port']) ? $remoteEndpoint['port'] : '',
            ];
        }
        if ($type == 'cr' || $type == 'ss') {
            $span['duration'] = self::timestamp() - $span['timestamp'];
        }
        if (!kempty($tags)) {
            foreach ($tags as $key => $value) {
                $span['tags'][$key] = $value;
            }
        }
        if (!kempty($annotations)) {
            foreach ($annotations as $key => $value) {
                $span['annotations'][] = [
                    "timestamp" => $value,
                    "value" => $key,
                ];
            }
        }
        self::$data[$spanId] = $span;
        if ($type == 'ss') {
            self::postZipkinSpans(array_values(self::$data));
        }
    }
    public static function postZipkinSpans(array $spans)
    {
        if (!self::$zipkinOpen) return false;
        $url = self::$zipkinHost . '/api/v2/spans';
        $ch = curl_init($url);
        $payload = json_encode($spans);
        curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
        curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
        $result = curl_exec($ch);
        if(!kempty($result)) self::getLogger()->info(json_encode($spans) . $result);
        curl_close($ch);
    }
    public static function timestamp() {
        return (int)(microtime(true) * 1000 * 1000);
    }
}


发表评论
评论通过审核后显示。
流量统计