diff --git a/src/Trace/SpanData.php b/src/Trace/SpanData.php index a0889cac1..2f9e9f6d9 100644 --- a/src/Trace/SpanData.php +++ b/src/Trace/SpanData.php @@ -136,6 +136,14 @@ class SpanData */ private $kind; + /** + * An optional value to de-dup the stackTrace array. Represented as a + * hexadecimal string. + * + * @var string + */ + private $stackTraceHashId; + /** * Instantiate a new SpanData instance. * @@ -303,6 +311,21 @@ public function stackTrace() return $this->stackTrace; } + /** + * Return a hash id for this span's stackTrace in hexadecimal + * + * @return string + */ + public function stackTraceHashId() + { + if (!isset($this->stackTraceHashId)) { + // take the lower 16 digits of the md5 + $md5 = md5(serialize($this->stackTrace)); + $this->stackTraceHashId = substr($md5, 16); + } + return $this->stackTraceHashId; + } + /** * Whether or not this span is in the same process as its parent. * diff --git a/tests/unit/Trace/SpanDataTest.php b/tests/unit/Trace/SpanDataTest.php index 711cb6b05..2ef4f330c 100644 --- a/tests/unit/Trace/SpanDataTest.php +++ b/tests/unit/Trace/SpanDataTest.php @@ -70,4 +70,22 @@ public function spanDataOptions() ['kind', Span::KIND_SERVER] ]; } + + public function testStackTraceHashIdIsRepeatable() + { + $stackTrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + $startTime = new \DateTime(); + $endTime = new \DateTime(); + $spanData = new SpanData('span-name', 'aaa', 'bbb', $startTime, $endTime, [ + 'stackTrace' => $stackTrace + ]); + + $spanData2 = new SpanData('span-name2', 'aaa', 'bbb', $startTime, $endTime, [ + 'stackTrace' => $stackTrace + ]); + + $hashId = $spanData->stackTraceHashId(); + $this->assertInternalType('string', $hashId); + $this->assertEquals($hashId, $spanData2->stackTraceHashId()); + } }