diff --git a/.circleci/config.yml b/.circleci/config.yml index e338abb4..1fd21015 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ version: 2 jobs: test: docker: - - image: circleci/php:5-node-browsers + - image: circleci/php:7.1-node-browsers steps: - checkout - restore_cache: diff --git a/composer.json b/composer.json index 95ca556d..3b7b105d 100644 --- a/composer.json +++ b/composer.json @@ -3,10 +3,12 @@ "description": "LightStep instrumentation API", "license": "MIT", "require": { - "ruafozy/mersenne-twister": "^1.3", - "google/protobuf": ">=3.6.1", + "php": "^7.1", "ext-bcmath": "*", - "psr/log": "^1.0" + "google/protobuf": ">=3.6.1", + "opentracing/opentracing": "^1.0.0-beta6", + "psr/log": "^1.0", + "ruafozy/mersenne-twister": "^1.3" }, "require-dev": { "phpdocumentor/phpdocumentor": "^2.8.5", @@ -24,4 +26,4 @@ "config": { "sort-packages": true } -} \ No newline at end of file +} diff --git a/lib/Client/ClientSpan.php b/lib/Client/ClientSpan.php index 40479141..042e4460 100644 --- a/lib/Client/ClientSpan.php +++ b/lib/Client/ClientSpan.php @@ -6,12 +6,11 @@ use Lightstep\Collector\Span; use Lightstep\Collector\SpanContext; use Google\Protobuf\Timestamp; -use LightStepBase\Tracer; require_once(dirname(__FILE__) . "/Util.php"); require_once(dirname(__FILE__) . "/../../thrift/CroutonThrift/Types.php"); -class ClientSpan implements \LightStepBase\Span { +class ClientSpan implements \OpenTracing\Span { protected $_tracer = NULL; @@ -76,11 +75,24 @@ public function setEndMicros($start) { return $this; } - public function finish() { - $this->_tracer->_finishSpan($this); + public function getOperationName() { + return $this->_operation; } - public function setOperationName($name) { + public function getContext() { + return new ClientSpanContext( + $this->traceGUID(), + $this->guid(), + true, + $this->getBaggage() + ); + } + + public function finish($finishTime = NULL) { + $this->_tracer->_finishSpan($this, $finishTime); + } + + public function overwriteOperationName($name) { $this->_operation = $name; return $this; } @@ -90,11 +102,6 @@ public function addTraceJoinId($key, $value) { return $this; } - public function setEndUserId($id) { - $this->addTraceJoinId(LIGHTSTEP_JOIN_KEY_END_USER_ID, $id); - return $this; - } - public function setTags($fields) { foreach ($fields as $key => $value) { $this->setTag($key, $value); @@ -107,7 +114,7 @@ public function setTag($key, $value) { return $this; } - public function setBaggageItem($key, $value) { + public function addBaggageItem($key, $value) { $this->_baggage[$key] = $value; return $this; } @@ -153,7 +160,7 @@ public function logEvent($event, $payload = NULL) { ]); } - public function log($fields) { + public function log(array $fields = [], $timestamp = NULL) { $record = [ 'span_guid' => strval($this->_guid), ]; @@ -163,7 +170,9 @@ public function log($fields) { $record['event'] = strval($fields['event']); } - if (!empty($fields['timestamp'])) { + if ($timestamp) { + $record['timestamp_micros'] = intval(1000 * $timestamp); + } else if (!empty($fields['timestamp'])) { $record['timestamp_micros'] = intval(1000 * $fields['timestamp']); } // no need to verify value of fields['payload'] as it will be checked by _rawLogRecord @@ -333,4 +342,10 @@ public function toProto() { 'references' => $references, ]); } + + /** Deprecated */ + public function setEndUserId($id) { + $this->addTraceJoinId("LIGHTSTEP_JOIN_KEY_END_USER_ID", $id); + return $this; + } } diff --git a/lib/Client/ClientSpanContext.php b/lib/Client/ClientSpanContext.php new file mode 100644 index 00000000..d48d795d --- /dev/null +++ b/lib/Client/ClientSpanContext.php @@ -0,0 +1,82 @@ +traceId = $traceId; + $this->spanId = $spanId; + $this->isSampled = $isSampled; + $this->baggageItems = $baggageItems; + } + + public function getTraceId(): string + { + return $this->traceId; + } + + public function getSpanId(): string + { + return $this->spanId; + } + + public function isSampled(): bool + { + return $this->isSampled; + } + + public function getBaggage(): array + { + return $this->baggageItems; + } + + /** + * {@inheritdoc} + */ + public function getIterator(): ArrayIterator + { + return new ArrayIterator($this->baggageItems); + } + + /** + * {@inheritdoc} + */ + public function getBaggageItem($key): ?string + { + return array_key_exists($key, $this->baggageItems) ? strval($this->baggageItems[$key]) : null; + } + + /** + * {@inheritdoc} + */ + public function withBaggageItem($key, $value): ?SpanContext + { + return new self($this->traceId, $this->spanId, $this->isSampled, array_merge($this->bagaggeItems, [$key => $value])); + } + +} \ No newline at end of file diff --git a/lib/Client/ClientTracer.php b/lib/Client/ClientTracer.php index 43e80f00..133e03b3 100644 --- a/lib/Client/ClientTracer.php +++ b/lib/Client/ClientTracer.php @@ -1,13 +1,12 @@ _spanRecords = []; } + /** + * + * + * OpenTracing API TODO Noop for now + */ + + //public function getScopeManager(): ScopeManager; + public function getScopeManager() {} + //public function getActiveSpan(): ?Span; + public function getActiveSpan() {} + //public function startActiveSpan(string $operationName, $options = []): Scope; + public function startActiveSpan($operationName, $options = []) {} + //public function extract(string $format, $carrier): ?SpanContext; + + // end TODO + + public function startSpan($operationName, $fields = NULL) { if (!$this->_enabled) { return new NoOpSpan; } $span = new ClientSpan($this, $this->_options['max_payload_depth']); - $span->setOperationName($operationName); + $span->overwriteOperationName($operationName); $span->setStartMicros($this->_util->nowMicros()); if ($fields != NULL) { - if (isset($fields['parent'])) { - $span->setParent($fields['parent']); + if (isset($fields['child_of']) || isset($fields['parent'])) { + $parent = isset($fields['child_of']) ? $fields['child_of'] : $fields['parent']; + + if ($parent instanceof ClientSpanContext) { + // Update Trace ID and Parent ID + $span->setTraceGUID($parent->getTraceId()); + $span->setParentGUID($parent->getSpanId()); + } else if ($parent instanceof ClientSpan) { + // Otherwise handle as usual + $span->setParent($parent); + } } if (isset($fields['tags'])) { $span->setTags($fields['tags']); } - if (isset($fields['startTime'])) { - $span->setStartMicros($fields['startTime'] * 1000); + if (isset($fields['start_time'])) { + $span->setStartMicros($fields['start_time'] * 1000); } } return $span; @@ -245,14 +270,10 @@ public function startSpan($operationName, $fields = NULL) { /** * Copies the span data into the given carrier object. */ - public function inject(Span $span, $format, &$carrier) { + public function inject(\OpenTracing\SpanContext $spanContext, $format, &$carrier) { switch ($format) { - case LIGHTSTEP_FORMAT_TEXT_MAP: - $this->injectToArray($span, $carrier); - break; - - case LIGHTSTEP_FORMAT_BINARY: - throw new \Exception('FORMAT_BINARY not yet implemented'); + case Formats\TEXT_MAP: + $this->injectToArray($spanContext, $carrier); break; default: @@ -261,16 +282,17 @@ public function inject(Span $span, $format, &$carrier) { } } - protected function injectToArray(Span $span, &$carrier) { - $carrier[CARRIER_TRACER_STATE_PREFIX . 'spanid'] = $span->guid(); - $traceGUID = $span->traceGUID(); + protected function injectToArray(\OpenTracing\SpanContext $spanContext, &$carrier) { + $carrier[OT_CARRIER_TRACER_PREFIX . 'spanid'] = $spanContext->getSpanId(); + $traceGUID = $spanContext->getTraceId(); if ($traceGUID) { - $carrier[CARRIER_TRACER_STATE_PREFIX . 'traceid'] = $traceGUID; + $carrier[OT_CARRIER_TRACER_PREFIX . 'traceid'] = $traceGUID; } - $carrier[CARRIER_TRACER_STATE_PREFIX . 'sampled'] = 'true'; + // Always set to true + $carrier[OT_CARRIER_TRACER_PREFIX . 'sampled'] = 'true'; - foreach ($span->getBaggage() as $key => $value) { - $carrier[CARRIER_BAGGAGE_PREFIX . $key] = $value; + foreach ($spanContext->getBaggage() as $key => $value) { + $carrier[OT_CARRIER_BAGGAGE_PREFIX . $key] = $value; } } @@ -279,18 +301,14 @@ protected function injectToArray(Span $span, &$carrier) { */ public function join($operationName, $format, $carrier) { $span = new ClientSpan($this, $this->_options['max_payload_depth']); - $span->setOperationName($operationName); + $span->overwriteOperationName($operationName); $span->setStartMicros($this->_util->nowMicros()); switch ($format) { - case LIGHTSTEP_FORMAT_TEXT_MAP: + case Formats\TEXT_MAP: $this->joinFromArray($span, $carrier); break; - case LIGHTSTEP_FORMAT_BINARY: - throw new \Exception('FORMAT_BINARY not yet implemented'); - break; - default: $this->_debugRecordError('Unknown inject format'); break; @@ -298,11 +316,11 @@ public function join($operationName, $format, $carrier) { return $span; } - protected function joinFromArray(Span $span, $carrier) { + protected function joinFromArray(ClientSpan $span, $carrier) { foreach ($carrier as $rawKey => $value) { $key = strtolower($rawKey); - if ($this->_startsWith($key, CARRIER_TRACER_STATE_PREFIX)) { - $shortKey = substr($key, strlen(CARRIER_TRACER_STATE_PREFIX)); + if ($this->_startsWith($key, OT_CARRIER_TRACER_PREFIX)) { + $shortKey = substr($key, strlen(OT_CARRIER_TRACER_PREFIX)); switch ($shortKey) { case 'traceid': $span->setTraceGUID($value); @@ -311,8 +329,8 @@ protected function joinFromArray(Span $span, $carrier) { $span->setParentGUID($value); break; } - } else if ($this->_startsWith($key, CARRIER_BAGGAGE_PREFIX)) { - $shortKey = substr($key, strlen(CARRIER_BAGGAGE_PREFIX)); + } else if ($this->_startsWith($key, OT_CARRIER_BAGGAGE_PREFIX)) { + $shortKey = substr($key, strlen(OT_CARRIER_BAGGAGE_PREFIX)); $span->setBaggageItem($shortKey, $value); } else { // By convention, LightStep join() ignores unrecognized key-value @@ -321,6 +339,53 @@ protected function joinFromArray(Span $span, $carrier) { } } + /** + * Creates a new SpanContext from the given carrier object and specified format. + */ + public function extract($format, $carrier) { + switch($format) { + case Formats\TEXT_MAP: + return $this->extractTextMap($carrier); + break; + + default: + $this->_debugRecordError('Unknown inject format'); + break; + } + } + + /** + * Creates a new SpanContext for Lightstep from the given carrier object. + */ + protected function extractTextMap($carrier) { + $traceid = ''; + $spanid = ''; + $baggageItems = array(); + foreach ($carrier as $rawkey => $value) { + $key = strtolower($rawkey); + if ($this->_startsWith($key, OT_CARRIER_TRACER_PREFIX)) { + $shortKey = substr($key, strlen(OT_CARRIER_TRACER_PREFIX)); + switch($shortKey) { + case 'traceid': + $traceid = $value; + break; + case 'spanid': + $spanid = $value; + } + } else if ($this->_startsWith($key, OT_CARRIER_BAGGAGE_PREFIX)) { + $shortKey = substr($key, strlen(OT_CARRIER_BAGGAGE_PREFIX)); + $baggageItems = array_merge($baggageItems, [$shortKey => $value]); + } + } + return new ClientSpanContext( + $traceid, + $spanid, + true, + $baggageItems + ); + } + + protected function _startsWith($haystack, $needle) { return (substr($haystack, 0, strlen($needle)) === $needle); } @@ -454,12 +519,17 @@ public function _generateUUIDString() { /** * Internal use only. */ - public function _finishSpan(ClientSpan $span) { + public function _finishSpan(ClientSpan $span, $finishTime = NULL) { if (!$this->_enabled) { return; } - $span->setEndMicros($this->_util->nowMicros()); + if ($finishTime) { + $span->setEndMicros(intval(1000 * $timestamp)); + } else { + $span->setEndMicros($this->_util->nowMicros()); + } + $success = Util::pushIfSpaceAllows( $this->_spanRecords, $span, diff --git a/lib/Client/NoOpSpan.php b/lib/Client/NoOpSpan.php index 2e8195c9..b7f51f76 100644 --- a/lib/Client/NoOpSpan.php +++ b/lib/Client/NoOpSpan.php @@ -4,31 +4,32 @@ require_once(dirname(__FILE__) . "/Util.php"); require_once(dirname(__FILE__) . "/../../thrift/CroutonThrift/Types.php"); -class NoOpSpan implements \LightStepBase\Span { +class NoOpSpan implements \OpenTracing\Span { public function guid() { return ""; } public function setRuntimeGUID($guid) {} public function traceGUID() { return ""; } public function setTraceGUID($traceGUID) {} - public function setOperationName($name) {} + public function overwriteOperationName($name) {} public function addTraceJoinId($key, $value) {} public function setEndUserId($id) {} + public function getContext() {} + public function getOperationName() {} public function tracer() { return LightStep::getInstance(); } public function setTag($key, $value) {} - public function setBaggageItem($key, $value) {} + public function addBaggageItem($key, $value) {} public function getBaggageItem($key) {} public function getBaggage() { return []; } public function logEvent($event, $payload = NULL) {} - public function log($fields) {} + public function log(array $fields = [], $timestamp = NULL) {} public function setParent($span) {} public function setParentGUID($parentGUID) {} - - public function finish() {} + public function finish($finishTime = NULL) {} public function infof($fmt) {} public function warnf($fmt) {} diff --git a/lib/LightStep.php b/lib/LightStep.php index 4e5920ef..04005bfb 100644 --- a/lib/LightStep.php +++ b/lib/LightStep.php @@ -1,6 +1,7 @@ startSpan($operationName, $fields); diff --git a/test/ClientTracerTest.php b/test/ClientTracerTest.php index 12ac4a5a..1f4dfa7e 100644 --- a/test/ClientTracerTest.php +++ b/test/ClientTracerTest.php @@ -155,4 +155,64 @@ public function testSendDataInPlainText() { $this->assertSame(80, $port); } } + + public function testInject() { + $tracer = $this->createTestTracer("test_group", "1234567890"); + $span = $tracer->startSpan("hello/world"); + + $carrier = array(); + $tracer->inject($span->getContext(), \OpenTracing\Formats\TEXT_MAP, $carrier); + $this->assertEquals($carrier['ot-tracer-spanid'], $span->guid()); + $this->assertEquals($carrier['ot-tracer-traceid'], $span->traceGUID()); + $this->assertEquals($carrier['ot-tracer-sampled'], 'true'); + $span->finish(); + } + + public function testInjectAndExtract() { + $tracer = $this->createTestTracer("test_group", "1234567890"); + $span = $tracer->startSpan("hello/world"); + + $carrier = array(); + $tracer->inject($span->getContext(), \OpenTracing\Formats\TEXT_MAP, $carrier); + $span->finish(); + + $spanContext = $tracer->extract(\OpenTracing\Formats\TEXT_MAP, $carrier); + $this->assertEquals($spanContext->getTraceId(),$span->traceGUID()); + $this->assertEquals($spanContext->getSpanId(),$span->guid()); + $this->assertEquals($spanContext->isSampled(),true); + } + + public function testInjectExtractWithBaggage() { + $tracer = $this->createTestTracer("test_group", "1234567890"); + $span = $tracer->startSpan("hello/world"); + $span->addBaggageItem("fruit", "apple"); + $span->addBaggageItem("number", 5); + $span->addBaggageItem("boolean", true); + $span->finish(); + + $carrier = array(); + $tracer->inject($span->getContext(), \OpenTracing\Formats\TEXT_MAP, $carrier); + $span->finish(); + + $spanContext = $tracer->extract(\OpenTracing\Formats\TEXT_MAP, $carrier); + $this->assertEquals(count($spanContext->getBaggage()), 3); + $this->assertEquals($spanContext->getBaggageItem("fruit"), "apple"); + $this->assertEquals($spanContext->getBaggageItem("number"), 5); + $this->assertEquals($spanContext->getBaggageItem("boolean"), true); + } + + public function testStartSpanFromSpanContext() { + $tracer = $this->createTestTracer("test_group", "1234567890"); + $span = $tracer->startSpan("hello/world"); + + $carrier = array(); + $tracer->inject($span->getContext(), \OpenTracing\Formats\TEXT_MAP, $carrier); + $span->finish(); + + $spanContext = $tracer->extract(\OpenTracing\Formats\TEXT_MAP, $carrier); + $child = $tracer->startSpan("hello/child", ["child_of" => $spanContext]); + $this->assertEquals($child->traceGUID(),$span->traceGUID()); + $this->assertEquals($child->getParentGUID(),$span->guid()); + } + } diff --git a/test/ProtoTypesTest.php b/test/ProtoTypesTest.php index d84409a8..15fa2d1a 100644 --- a/test/ProtoTypesTest.php +++ b/test/ProtoTypesTest.php @@ -17,7 +17,7 @@ public function testAuthToProto() { public function testClientSpanToProto() { $tracer = new \LightStepBase\Client\ClientTracer(); $span = new \LightStepBase\Client\ClientSpan($tracer, 5); - $span->setOperationName("my_operation"); + $span->overwriteOperationName("my_operation"); $span->setStartMicros(1538476581123456); $span->setEndMicros(1538476581124456); $span->setParentGUID("513887a3b3f460d8"); @@ -147,7 +147,7 @@ public function testReportRequestToProto() { $tracer = new \LightStepBase\Client\ClientTracer(); $span = new \LightStepBase\Client\ClientSpan($tracer, 5); - $span->setOperationName("my_operation"); + $span->overwriteOperationName("my_operation"); $span->setStartMicros(1538476581123456); $span->setEndMicros(1538476581124456); $span->setParentGUID("513887a3b3f460d8"); diff --git a/test/SpanTest.php b/test/SpanTest.php index 593eb4e8..13f444d6 100644 --- a/test/SpanTest.php +++ b/test/SpanTest.php @@ -2,12 +2,23 @@ class SpanTest extends BaseLightStepTest { - public function testSpanSetOperation() { + public function testSpanGetOperation() { $tracer = $this->createTestTracer("test_group", "1234567890"); $span = $tracer->startSpan("server/query"); $span->finish(); - $this->assertEquals($this->peek($span, "_operation"), "server/query"); + $this->assertEquals($span->getOperationName(), "server/query"); + } + + public function testSpanOverwriteOperation() { + $tracer = $this->createTestTracer("test_group", "1234567890"); + $span = $tracer->startSpan("server/query"); + $this->assertEquals($span->getOperationName(), "server/query"); + + $span->overwriteOperationName("client/query"); + $this->assertEquals($span->getOperationName(), "client/query"); + + $span->finish(); } public function testSpanStartEndMicros() { @@ -32,18 +43,9 @@ public function testSpanStartEndMicros() { // a lot of precision from usleep() here. $this->assertGreaterThan(100, $avg); $this->assertLessThan(1000, $avg); - } - - public function testSpanJoinIds() { - $tracer = $this->createTestTracer("test_group", "1234567890"); - $span = $tracer->startSpan("join_id_span"); + } - $span->addTraceJoinId("number", "one"); - $this->assertEquals(count($this->peek($span, "_joinIds")), 1); - - $span->setEndUserId("mr_jones"); - $this->assertEquals(count($this->peek($span, "_joinIds")), 2); - } + // TODO: Test span with explicit finish public function testSpanLogging() { $tracer = $this->createTestTracer("test_group", "1234567890"); @@ -54,15 +56,15 @@ public function testSpanLogging() { $span->finish(); } - public function testSpanAttributes() { + public function testSpanTags() { $tracer = $this->createTestTracer("test_group", "1234567890"); - $span = $tracer->startSpan("attributes_span"); - $span->setTag("test_attribute_1", "value 1"); - $span->setTag("test_attribute_2", "value 2"); + $span = $tracer->startSpan("tags_span"); + $span->setTag("test_tag_1", "value 1"); + $span->setTag("test_tag_2", "value 2"); $this->assertEquals(count($this->peek($span, "_tags")), 2); - $span->setTag("test_attribute_3", "value 3"); + $span->setTag("test_tag_3", "value 3"); $this->assertEquals(count($this->peek($span, "_tags")), 3); @@ -109,6 +111,21 @@ public function testStartSpanWithParent() { $parent->finish(); } + public function testStartSpanWithParent2() { + $tracer = $this->createTestTracer("test_group", "1234567890"); + + $parent = $tracer->startSpan('parent'); + $this->assertTrue(strlen($parent->traceGUID()) > 0); + $this->assertTrue(strlen($parent->guid()) > 0); + + $child = $tracer->startSpan('child', array('child_of' => $parent)); + $this->assertEquals($child->traceGUID(), $parent->traceGUID()); + $this->assertEquals($child->getParentGUID(), $parent->guid()); + + $child->finish(); + $parent->finish(); + } + public function testSetParent() { // NOTE: setParent() is not part of the OpenTracing API. (Reminder this // is a unit test so non-API calls are ok!) @@ -130,7 +147,7 @@ public function testSetParent() { public function testSpanThriftRecord() { $tracer = $this->createTestTracer("test_group", "1234567890"); $span = $tracer->startSpan("hello/world"); - $span->setEnduserId("dinosaur_sr"); + //$span->setEnduserId("dinosaur_sr"); $span->setTag("Titanosaurus", "sauropod"); $span->finish(); @@ -140,11 +157,52 @@ public function testSpanThriftRecord() { $this->assertTrue(is_string($arr["trace_guid"])); $this->assertTrue(is_string($arr["runtime_guid"])); $this->assertTrue(is_string($arr["span_name"])); - $this->assertEquals(1, count($arr["join_ids"])); - $this->assertTrue(is_string($arr["join_ids"][0]["TraceKey"])); - $this->assertTrue(is_string($arr["join_ids"][0]["Value"])); $this->assertTrue(is_string($arr["attributes"][0]["Key"])); $this->assertTrue(is_string($arr["attributes"][0]["Value"])); + + // $this->assertEquals(1, count($arr["join_ids"])); + // $this->assertTrue(is_string($arr["join_ids"][0]["TraceKey"])); + // $this->assertTrue(is_string($arr["join_ids"][0]["Value"])); + } + + public function testSpanContext() { + $tracer = $this->createTestTracer("test_group", "1234567890"); + $span = $tracer->startSpan("hello/world"); + $span->finish(); + + $spanContext = $span->getContext(); + $this->assertEquals($spanContext->getTraceId(), $span->traceGUID()); + $this->assertEquals($spanContext->getSpanId(), $span->guid()); + $this->assertTrue($spanContext->isSampled()); + $this->assertEquals($spanContext->getBaggage(), array()); + } + + public function testSpanContextWithBaggage() { + $tracer = $this->createTestTracer("test_group", "1234567890"); + $span = $tracer->startSpan("hello/world"); + $span->addBaggageItem("fruit", "apple"); + $span->addBaggageItem("number", 5); + $span->addBaggageItem("boolean", true); + $span->finish(); + + $spanContext = $span->getContext(); + $this->assertEquals(count($spanContext->getBaggage()), 3); + $this->assertEquals($spanContext->getBaggageItem("fruit"), "apple"); + $this->assertEquals($spanContext->getBaggageItem("number"), 5); + $this->assertEquals($spanContext->getBaggageItem("boolean"), true); + } + + /** Depreceated Tests (Due to Join not being a valid alternative to extract) */ + + public function testSpanJoinIds() { + $tracer = $this->createTestTracer("test_group", "1234567890"); + $span = $tracer->startSpan("join_id_span"); + + $span->addTraceJoinId("number", "one"); + $this->assertEquals(count($this->peek($span, "_joinIds")), 1); + + $span->setEndUserId("mr_jones"); + $this->assertEquals(count($this->peek($span, "_joinIds")), 2); } public function testInjectJoin() { @@ -152,13 +210,13 @@ public function testInjectJoin() { $span = $tracer->startSpan("hello/world"); $carrier = array(); - $tracer->inject($span, LIGHTSTEP_FORMAT_TEXT_MAP, $carrier); + $tracer->inject($span->getContext(), \OpenTracing\Formats\TEXT_MAP, $carrier); $this->assertEquals($carrier['ot-tracer-spanid'], $span->guid()); $this->assertEquals($carrier['ot-tracer-traceid'], $span->traceGUID()); $this->assertEquals($carrier['ot-tracer-sampled'], 'true'); $span->finish(); - $child = $tracer->join('child', LIGHTSTEP_FORMAT_TEXT_MAP, $carrier); + $child = $tracer->join('child', \OpenTracing\Formats\TEXT_MAP, $carrier); $this->assertEquals($child->traceGUID(), $span->traceGUID()); $this->assertEquals($child->getParentGUID(), $span->guid()); $child->finish();