From 782f67a67f9c62480d8189294c8f3d673b6bdf22 Mon Sep 17 00:00:00 2001 From: Ilya Burtsev Date: Fri, 25 Aug 2023 09:16:59 +0700 Subject: [PATCH] Support of 128bit trace id's. Support of Jaeger thrift compact over UDP protocol. And other minor fixes. Fix followed issues: https://github.com/jonahgeorge/jaeger-client-php/issues/129 https://github.com/jonahgeorge/jaeger-client-php/issues/120 https://github.com/jonahgeorge/jaeger-client-php/issues/42 --- src/Jaeger/Codec/TextCodec.php | 11 +++++---- src/Jaeger/Config.php | 20 +++++++++++++++- src/Jaeger/Constants.php | 1 + src/Jaeger/Mapper/SpanToJaegerMapper.php | 24 +++++++++++++++++-- .../ReporterFactory/JaegerReporterFactory.php | 8 ++++--- tests/Jaeger/Codec/TextCodecTest.php | 16 ++++++++++--- .../Jaeger/Mapper/SpanToJaegerMapperTest.php | 5 +++- tests/Jaeger/TracerTest.php | 2 +- 8 files changed, 72 insertions(+), 15 deletions(-) diff --git a/src/Jaeger/Codec/TextCodec.php b/src/Jaeger/Codec/TextCodec.php index d437f38..a7e0825 100644 --- a/src/Jaeger/Codec/TextCodec.php +++ b/src/Jaeger/Codec/TextCodec.php @@ -90,14 +90,14 @@ public function extract($carrier) $baggage = null; $debugId = null; - foreach ($carrier as $key => $value) { + foreach ((array)$carrier as $key => $value) { $ucKey = strtolower($key); if ($ucKey === $this->traceIdHeader) { if ($this->urlEncoding) { $value = urldecode($value); } - list($traceId, $spanId, $parentId, $flags) = + [$traceId, $spanId, $parentId, $flags] = $this->spanContextFromString($value); } elseif ($this->startsWith($ucKey, $this->baggagePrefix)) { if ($this->urlEncoding) { @@ -143,7 +143,10 @@ public function extract($carrier) private function spanContextToString($traceId, $spanId, $parentId, $flags) { $parentId = $parentId ?? 0; - return sprintf('%x:%x:%x:%x', $traceId, $spanId, $parentId, $flags); + if (is_int($traceId)) { + $traceId = sprintf('%016x', $traceId); + } + return sprintf('%s:%x:%x:%x', $traceId, $spanId, $parentId, $flags); } /** @@ -163,7 +166,7 @@ private function spanContextFromString($value): array } return [ - CodecUtility::hexToInt64($parts[0]), + $parts[0], CodecUtility::hexToInt64($parts[1]), CodecUtility::hexToInt64($parts[2]), $parts[3], diff --git a/src/Jaeger/Config.php b/src/Jaeger/Config.php index 28fb972..de08f3f 100644 --- a/src/Jaeger/Config.php +++ b/src/Jaeger/Config.php @@ -25,6 +25,7 @@ class Config const ZIPKIN_OVER_COMPACT_UDP = "zipkin_over_compact_udp"; const JAEGER_OVER_BINARY_UDP = "jaeger_over_binary_udp"; + const JAEGER_OVER_COMPACT_UDP = "jaeger_over_compact_udp"; const JAEGER_OVER_BINARY_HTTP = "jaeger_over_binary_http"; const IPV6 = "IPv6"; @@ -35,7 +36,12 @@ class Config */ public static function getAvailableDispatchModes() { - return [self::ZIPKIN_OVER_COMPACT_UDP, self::JAEGER_OVER_BINARY_UDP, self::JAEGER_OVER_BINARY_HTTP]; + return [ + self::ZIPKIN_OVER_COMPACT_UDP, + self::JAEGER_OVER_BINARY_UDP, + self::JAEGER_OVER_BINARY_HTTP, + self::JAEGER_OVER_COMPACT_UDP, + ]; } /** @@ -175,6 +181,14 @@ private function getLogging(): bool return (bool)($this->config['logging'] ?? false); } + /** + * @return string + */ + public function getDispatchMode(): string + { + return $this->config['dispatch_mode']; + } + /** * @return ReporterInterface */ @@ -182,6 +196,7 @@ private function getReporter(): ReporterInterface { switch ($this->config["dispatch_mode"]) { case self::JAEGER_OVER_BINARY_UDP: + case self::JAEGER_OVER_COMPACT_UDP: $reporter = (new JaegerReporterFactory($this))->createReporter(); break; case self::ZIPKIN_OVER_COMPACT_UDP: @@ -271,6 +286,9 @@ public function getLocalAgentReportingPort(): int case self::JAEGER_OVER_BINARY_UDP: $port = DEFAULT_JAEGER_UDP_BINARY_REPORTING_PORT; break; + case self::JAEGER_OVER_COMPACT_UDP: + $port = DEFAULT_JAEGER_UDP_COMPACT_REPORTING_PORT; + break; case self::JAEGER_OVER_BINARY_HTTP: $port = DEFAULT_JAEGER_HTTP_BINARY_REPORTING_PORT; break; diff --git a/src/Jaeger/Constants.php b/src/Jaeger/Constants.php index 1e4be65..7a8a86d 100644 --- a/src/Jaeger/Constants.php +++ b/src/Jaeger/Constants.php @@ -87,6 +87,7 @@ const DEFAULT_ZIPKIN_UDP_COMPACT_REPORTING_PORT = 5775; const DEFAULT_JAEGER_UDP_BINARY_REPORTING_PORT = 6832; +const DEFAULT_JAEGER_UDP_COMPACT_REPORTING_PORT = 6831; const DEFAULT_JAEGER_HTTP_BINARY_REPORTING_PORT = 14268; const DEFAULT_SAMPLING_PORT = 5778; diff --git a/src/Jaeger/Mapper/SpanToJaegerMapper.php b/src/Jaeger/Mapper/SpanToJaegerMapper.php index da58719..283fae6 100644 --- a/src/Jaeger/Mapper/SpanToJaegerMapper.php +++ b/src/Jaeger/Mapper/SpanToJaegerMapper.php @@ -2,6 +2,7 @@ namespace Jaeger\Mapper; +use Jaeger\Codec\CodecUtility; use Jaeger\Span; use Jaeger\Thrift\Agent\Zipkin\AnnotationType; use Jaeger\Thrift\Agent\Zipkin\BinaryAnnotation; @@ -155,9 +156,11 @@ public function mapSpanToJaeger(Span $span) : JaegerThriftSpan ]); } + [$low, $high] = $this->extractTraceIdFromString($span->getContext()->getTraceId()); + return new JaegerThriftSpan([ - "traceIdLow" => (int)$span->getContext()->getTraceId(), - "traceIdHigh" => 0, + "traceIdLow" => $low, + "traceIdHigh" => $high, "spanId" => (int)$span->getContext()->getSpanId(), "parentSpanId" => (int)$span->getContext()->getParentId(), "operationName" => $span->getOperationName(), @@ -168,4 +171,21 @@ public function mapSpanToJaeger(Span $span) : JaegerThriftSpan "logs" => $logs ]); } + + private function extractTraceIdFromString(?string $id): array + { + if ($id === null) { + return [0, 0]; + } + + if (strlen($id) > 16) { + $traceIdLow = CodecUtility::hexToInt64(substr($id, -16, 16)); + $traceIdHigh = CodecUtility::hexToInt64(substr($id, 0, 16)); + } else { + $traceIdLow = (int) CodecUtility::hexToInt64($id); + $traceIdHigh = 0; + } + + return [$traceIdLow, $traceIdHigh]; + } } diff --git a/src/Jaeger/ReporterFactory/JaegerReporterFactory.php b/src/Jaeger/ReporterFactory/JaegerReporterFactory.php index 9865884..eda8639 100644 --- a/src/Jaeger/ReporterFactory/JaegerReporterFactory.php +++ b/src/Jaeger/ReporterFactory/JaegerReporterFactory.php @@ -2,7 +2,7 @@ namespace Jaeger\ReporterFactory; -use Jaeger\AgentClient\HttpAgentClient; +use Jaeger\Config; use Jaeger\Reporter\JaegerReporter; use Jaeger\Reporter\ReporterInterface; use Jaeger\Sender\JaegerSender; @@ -10,11 +10,12 @@ use Jaeger\ThriftUdpTransport; use Thrift\Exception\TTransportException; use Thrift\Protocol\TBinaryProtocol; +use Thrift\Protocol\TCompactProtocol; use Thrift\Transport\TBufferedTransport; class JaegerReporterFactory extends AbstractReporterFactory implements ReporterFactoryInterface { - public function createReporter() : ReporterInterface + public function createReporter(): ReporterInterface { $udp = new ThriftUdpTransport( $this->config->getLocalAgentReportingHost(), @@ -34,7 +35,8 @@ public function createReporter() : ReporterInterface } catch (TTransportException $e) { $this->config->getLogger()->warning($e->getMessage()); } - $protocol = new TBinaryProtocol($transport); + $protocol = $this->config->getDispatchMode() === Config::JAEGER_OVER_COMPACT_UDP ? + new TCompactProtocol($transport) : new TBinaryProtocol($transport); $client = new AgentClient($protocol); $this->config->getLogger()->debug('Initializing UDP Jaeger Tracer with Jaeger.Thrift over Binary protocol'); $sender = new JaegerSender($client, $this->config->getLogger()); diff --git a/tests/Jaeger/Codec/TextCodecTest.php b/tests/Jaeger/Codec/TextCodecTest.php index 79a1dd9..0c4c4e6 100644 --- a/tests/Jaeger/Codec/TextCodecTest.php +++ b/tests/Jaeger/Codec/TextCodecTest.php @@ -29,6 +29,16 @@ public function testCanInjectSimpleContextInCarrier(): void $this->assertCount(1 , $carrier); $this->assertArrayHasKey(TRACE_ID_HEADER, $carrier); + $this->assertSame('trace-id:0:0:0', $carrier[TRACE_ID_HEADER]); + } + + public function testTraceIdConvertToHex(): void + { + $context = new SpanContext(3003082921159205154, 'span-id', null, null); + $carrier = []; + + $this->textCodec->inject($context, $carrier); + $this->assertSame('29ad18017abca122:0:0:0', $carrier[TRACE_ID_HEADER]); } /** @@ -95,7 +105,7 @@ public function carrierDataProvider(): array [ TRACE_ID_HEADER => '32834e4115071776:f7802330248418d:f123456789012345:1' ], - "3639838965278119798", + "32834e4115071776", "1114643325879075213", "-1070935975401544891", 1, @@ -107,7 +117,7 @@ public function carrierDataProvider(): array TRACE_ID_HEADER => '32834e4115071776:f7802330248418d:f123456789012345:1', BAGGAGE_HEADER_PREFIX . 'baggage-1' => 'https://testdomain.sk', ], - "3639838965278119798", + "32834e4115071776", "1114643325879075213", "-1070935975401544891", 1, @@ -119,7 +129,7 @@ public function carrierDataProvider(): array TRACE_ID_HEADER => '32834e4115071776:f7802330248418d:f123456789012345:1', BAGGAGE_HEADER_PREFIX . 'baggage-1' => 'https%3A%2F%2Ftestdomain.sk', ], - "3639838965278119798", + "32834e4115071776", "1114643325879075213", "-1070935975401544891", 1, diff --git a/tests/Jaeger/Mapper/SpanToJaegerMapperTest.php b/tests/Jaeger/Mapper/SpanToJaegerMapperTest.php index d536cb6..f732b14 100644 --- a/tests/Jaeger/Mapper/SpanToJaegerMapperTest.php +++ b/tests/Jaeger/Mapper/SpanToJaegerMapperTest.php @@ -34,7 +34,7 @@ class SpanToJaegerMapperTest extends \PHPUnit\Framework\TestCase public function setUp(): void { $this->tracer = new Tracer($this->serviceName, new NullReporter, new ConstSampler); - $this->context = new SpanContext(0, 0, 0, SAMPLED_FLAG); + $this->context = new SpanContext('5f2c2ea76d359a165f2c2ea76d35b26b', 0, 0, SAMPLED_FLAG); } /** @@ -61,6 +61,9 @@ public function shouldProperlyInitializeAtConstructTime(): void $mapper = new SpanToJaegerMapper(); $thriftSpan = $mapper->mapSpanToJaeger($span); + $this->assertSame(6857907629205068310, $thriftSpan->traceIdHigh); + $this->assertSame(6857907629205074539, $thriftSpan->traceIdLow); + $index = 0; $this->assertEquals($thriftSpan->tags[$index]->key, "component"); $this->assertEquals($thriftSpan->tags[$index]->vType, TagType::STRING); diff --git a/tests/Jaeger/TracerTest.php b/tests/Jaeger/TracerTest.php index 3e7b4c0..ab0a021 100644 --- a/tests/Jaeger/TracerTest.php +++ b/tests/Jaeger/TracerTest.php @@ -185,7 +185,7 @@ public function shouldInjectSpanContextToCarrier(): void $this->tracer->inject($spanContext, TEXT_MAP, $carrier); $this->assertCount(1, $carrier); - $this->assertEquals('0:0:0:0', $carrier[TRACE_ID_HEADER]); + $this->assertEquals('0000000000000000:0:0:0', $carrier[TRACE_ID_HEADER]); } /** @test */