OpenTracing Scala Akka instrumentation
OpenTracing instrumentation for Scala Akka.
Installation
build.sbt
libraryDependencies += "io.opentracing.contrib" % "opentracing-scala-akka" % "VERSION"
Usage
Tracer registration
Instantiate tracer and register it with GlobalTracer
:
val tracer: Tracer = ???
GlobalTracer.register(tracer)
Actor's Span propagation
User is responsible for finishing the Span
s. For this to work, classes must inherit from TracedAbstractActor
instead of Actor
, and messages must be wrapped using TracedMessage.wrap()
:
class MyActor extends TracedAbstractActor {
override def receive(): Receive = {
case _: String =>
sender().tell("ciao", self)
}
}
val scope = tracer.buildSpan("foo").startActive(true)
// scope.span() will be captured as part of TracedMessage.wrap(),
// and MyActor will receive the original 'myMessageObj` instance.
val future = ask(myActorRef, TracedMessage.wrap("hello"), timeout)
...
scope.close()
}
By default, TracedAbstractActor
/TracedMessage
use io.opentracing.util.GlobalTracer
to activate and fetch the Span
respectively, but it's possible to manually specify both the Tracer
used to activate and the captured Span
:
class MyActor(myTracer: Tracer) extends TracedAbstractActor {
override def receive(): Receive = {
case _: String =>
// TracedAbstractActor.tracer() returns the Tracer being used,
// either GlobalTracer
if (tracer().activeSpan() != null) {
// Use the active Span, to set tags, create children, finish it, etc.
tracer().activeSpan.finish()
}
...
}
override def tracer(): Tracer = myTracer
}
val span = tracer.buildSpan("foo").start()
val future = ask(myActorRef, TracedMessage.wrap(span, "hello"), timeout);