package kamon.instrumentation import akka.actor.{Props, ActorSystem, ActorRef} import akka.dispatch.{MessageDispatcher, Envelope} import kamon.{Tracer, TraceContext} import kamon.instrumentation.SimpleContextPassingInstrumentation.SimpleTraceMessage trait ActorInstrumentationConfiguration { def sendMessageTransformation(from: ActorRef, to: ActorRef, message: Any): Any def receiveInvokeInstrumentation(system: ActorSystem, self: ActorRef, props: Props, dispatcher: MessageDispatcher, parent: ActorRef): ActorReceiveInvokeInstrumentation } trait ActorReceiveInvokeInstrumentation { def preReceive(envelope: Envelope): (Envelope, Option[TraceContext]) } object ActorReceiveInvokeInstrumentation { val noopPreReceive = new ActorReceiveInvokeInstrumentation{ def preReceive(envelope: Envelope): (Envelope, Option[TraceContext]) = (envelope, None) } } class SimpleContextPassingInstrumentation extends ActorInstrumentationConfiguration { def sendMessageTransformation(from: ActorRef, to: ActorRef, message: Any): Any = SimpleTraceMessage(message, Tracer.context) def receiveInvokeInstrumentation(system: ActorSystem, self: ActorRef, props: Props, dispatcher: MessageDispatcher, parent: ActorRef): ActorReceiveInvokeInstrumentation = { new ActorReceiveInvokeInstrumentation { def preReceive(envelope: Envelope): (Envelope, Option[TraceContext]) = envelope match { case env @ Envelope(SimpleTraceMessage(msg, ctx), _) => (env.copy(message = msg), ctx) case anyOther => (anyOther, None) } } } } object SimpleContextPassingInstrumentation { case class SimpleTraceMessage(message: Any, context: Option[TraceContext]) }