aboutsummaryrefslogtreecommitdiff
path: root/kamon-core/src/main/scala/kamon/trace/Tracer.scala
blob: 84aafe68c56be0d792ff0598569fe43c23eb3417 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package kamon.trace

import java.util.concurrent.atomic.AtomicLong

import io.opentracing.propagation.Format
import io.opentracing.util.ThreadLocalActiveSpanSource
import kamon.ReporterRegistryImpl
import kamon.metric.RecorderRegistry
import kamon.util.Clock

class Tracer(metrics: RecorderRegistry, reporterRegistry: ReporterRegistryImpl) extends io.opentracing.Tracer {
  private val traceCounter = new AtomicLong()
  private val spanCounter = new AtomicLong()
  private val activeSpanSource = new ThreadLocalActiveSpanSource()


  override def buildSpan(operationName: String): io.opentracing.Tracer.SpanBuilder =
    new SpanBuilder(operationName, spanCounter.incrementAndGet())

  override def extract[C](format: Format[C], carrier: C): io.opentracing.SpanContext =
    sys.error("Extracting not implemented yet.")

  override def inject[C](spanContext: io.opentracing.SpanContext, format: Format[C], carrier: C): Unit =
    sys.error("Injecting not implemented yet.")

  override def activeSpan(): io.opentracing.ActiveSpan =
    activeSpanSource.activeSpan()

  override def makeActive(span: io.opentracing.Span): io.opentracing.ActiveSpan =
    activeSpanSource.makeActive(span)


  private[kamon] def newTraceID: Long =
    traceCounter.incrementAndGet()

  private class SpanBuilder(operationName: String, spanID: Long) extends io.opentracing.Tracer.SpanBuilder {
    private var traceID = 0L
    private var startTimestamp = 0L
    private var parentID = 0L
    private var initialTags = Map.empty[String, String]

    override def start(): io.opentracing.Span =
      startManual()

    override def asChildOf(parent: io.opentracing.SpanContext): io.opentracing.Tracer.SpanBuilder = {
      parent match {
        case kamonSpanContext: kamon.trace.SpanContext =>
          traceID = kamonSpanContext.traceID
          parentID = kamonSpanContext.spanID
        case _ => sys.error("Can't extract the parent ID from a non-kamon SpanContext")
      }
      this
    }

    override def asChildOf(parent: io.opentracing.BaseSpan[_]): io.opentracing.Tracer.SpanBuilder = {
      parent.context() match {
        case kamonSpanContext: kamon.trace.SpanContext =>
          traceID = kamonSpanContext.traceID
          parentID = kamonSpanContext.spanID
        case _ => sys.error("Can't extract the parent ID from a non-kamon SpanContext")
      }
      this
    }

    override def addReference(referenceType: String, referencedContext: io.opentracing.SpanContext): io.opentracing.Tracer.SpanBuilder = {
      if(referenceType != null && referenceType.equals(io.opentracing.References.CHILD_OF)) {
        referencedContext match {
          case kamonSpanContext: kamon.trace.SpanContext =>
            traceID = kamonSpanContext.traceID
            parentID = kamonSpanContext.spanID
          case _ => sys.error("Can't extract the parent ID from a non-kamon SpanContext")
        }
      }
      this
    }

    override def withTag(key: String, value: String): io.opentracing.Tracer.SpanBuilder = {
      initialTags = initialTags + (key -> value)
      this
    }

    override def withTag(key: String, value: Boolean): io.opentracing.Tracer.SpanBuilder = {
      initialTags = initialTags + (key -> value.toString)
      this
    }

    override def withTag(key: String, value: Number): io.opentracing.Tracer.SpanBuilder = {
      initialTags = initialTags + (key -> value.toString)
      this
    }

    override def startManual(): Span = {
      if(traceID == 0L) traceID = Tracer.this.newTraceID
      val startTimestampMicros = if(startTimestamp != 0L) startTimestamp else Clock.microTimestamp()
      new Span(new SpanContext(traceID, spanID, parentID), operationName, startTimestampMicros, metrics, reporterRegistry)
    }

    override def withStartTimestamp(microseconds: Long): io.opentracing.Tracer.SpanBuilder = {
      startTimestamp = microseconds
      this
    }

    override def startActive(): io.opentracing.ActiveSpan = {
      Tracer.this.makeActive(startManual())
    }

    override def ignoreActiveSpan(): io.opentracing.Tracer.SpanBuilder = ???
  }

}