aboutsummaryrefslogtreecommitdiff
path: root/kamon-testkit/src/main/scala/kamon/testkit/SpanInspector.scala
diff options
context:
space:
mode:
Diffstat (limited to 'kamon-testkit/src/main/scala/kamon/testkit/SpanInspector.scala')
-rw-r--r--kamon-testkit/src/main/scala/kamon/testkit/SpanInspector.scala61
1 files changed, 61 insertions, 0 deletions
diff --git a/kamon-testkit/src/main/scala/kamon/testkit/SpanInspector.scala b/kamon-testkit/src/main/scala/kamon/testkit/SpanInspector.scala
new file mode 100644
index 00000000..f23fba98
--- /dev/null
+++ b/kamon-testkit/src/main/scala/kamon/testkit/SpanInspector.scala
@@ -0,0 +1,61 @@
+package kamon.testkit
+
+import kamon.trace.{Span, SpanContext}
+import kamon.trace.Span.FinishedSpan
+import kamon.util.Clock
+
+import scala.reflect.ClassTag
+import scala.util.Try
+
+class SpanInspector(span: Span) {
+ private val (realSpan, spanData) = Try {
+ val realSpan = span match {
+ case _: Span.Local => span
+ }
+
+ val spanData = invoke[Span.Local, FinishedSpan](realSpan, "toFinishedSpan", classOf[Long] -> Long.box(Clock.microTimestamp()))
+ (realSpan, spanData)
+ }.getOrElse((null, null))
+
+ def isEmpty: Boolean =
+ realSpan == null
+
+ def spanTag(key: String): Option[Span.TagValue] =
+ spanData.tags.get(key)
+
+ def spanTags(): Map[String, Span.TagValue] =
+ spanData.tags
+
+ def metricTags(): Map[String, String] =
+ getField[Span.Local, Map[String, String]](realSpan, "customMetricTags")
+
+ def startTimestamp(): Long =
+ getField[Span.Local, Long](realSpan, "startTimestampMicros")
+
+ def context(): SpanContext =
+ spanData.context
+
+ def operationName(): String =
+ spanData.operationName
+
+
+
+
+ private def getField[T, R](target: Any, fieldName: String)(implicit classTag: ClassTag[T]): R = {
+ val toFinishedSpanMethod = classTag.runtimeClass.getDeclaredField(fieldName)
+ toFinishedSpanMethod.setAccessible(true)
+ toFinishedSpanMethod.get(target).asInstanceOf[R]
+ }
+
+ private def invoke[T, R](target: Any, fieldName: String, parameters: (Class[_], AnyRef)*)(implicit classTag: ClassTag[T]): R = {
+ val parameterClasses = parameters.map(_._1)
+ val parameterInstances = parameters.map(_._2)
+ val toFinishedSpanMethod = classTag.runtimeClass.getDeclaredMethod(fieldName, parameterClasses: _*)
+ toFinishedSpanMethod.setAccessible(true)
+ toFinishedSpanMethod.invoke(target, parameterInstances: _*).asInstanceOf[R]
+ }
+}
+
+object SpanInspector {
+ def apply(span: Span): SpanInspector = new SpanInspector(span)
+}