diff options
author | Ivan Topolnak <ivantopo@gmail.com> | 2013-06-14 18:33:23 -0300 |
---|---|---|
committer | Ivan Topolnak <ivantopo@gmail.com> | 2013-06-14 18:33:23 -0300 |
commit | 658bdd03a3b549cf7225197388e1e18b01723f1f (patch) | |
tree | c88228d013324519d29aad6edebaa1fd65145c28 /src/main/scala/kamon/instrumentation/ActorRefTellInstrumentation.scala | |
parent | 80725fd14a728c6afcc9d8b3ac7c4bd10e8bd05e (diff) | |
download | Kamon-658bdd03a3b549cf7225197388e1e18b01723f1f.tar.gz Kamon-658bdd03a3b549cf7225197388e1e18b01723f1f.tar.bz2 Kamon-658bdd03a3b549cf7225197388e1e18b01723f1f.zip |
minor cleanup, still working in metrics
Diffstat (limited to 'src/main/scala/kamon/instrumentation/ActorRefTellInstrumentation.scala')
-rw-r--r-- | src/main/scala/kamon/instrumentation/ActorRefTellInstrumentation.scala | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/main/scala/kamon/instrumentation/ActorRefTellInstrumentation.scala b/src/main/scala/kamon/instrumentation/ActorRefTellInstrumentation.scala new file mode 100644 index 00000000..b345eaae --- /dev/null +++ b/src/main/scala/kamon/instrumentation/ActorRefTellInstrumentation.scala @@ -0,0 +1,74 @@ +package kamon.instrumentation + +import org.aspectj.lang.annotation.{Before, Around, Pointcut, Aspect} +import org.aspectj.lang.ProceedingJoinPoint +import akka.actor.{Props, ActorSystem, ActorRef} +import kamon.{Kamon, TraceContext} +import akka.dispatch.Envelope +import com.codahale.metrics.{ExponentiallyDecayingReservoir, Histogram} +import kamon.metric.{MetricDirectory, Metrics} + +case class TraceableMessage(traceContext: Option[TraceContext], message: Any, timeStamp: Long = System.nanoTime()) + + +@Aspect +class ActorRefTellInstrumentation { + import ProceedingJoinPointPimp._ + + @Pointcut("execution(* akka.actor.ScalaActorRef+.$bang(..)) && !within(akka.pattern.PromiseActorRef) && args(message, sender)") + def sendingMessageToActorRef(message: Any, sender: ActorRef) = {} + + @Around("sendingMessageToActorRef(message, sender)") + def around(pjp: ProceedingJoinPoint, message: Any, sender: ActorRef): Unit = pjp.proceedWith(TraceableMessage(Kamon.context, message)) +} + + +@Aspect("perthis(actorCellCreation(..))") +class ActorCellInvokeInstrumentation { + + val latencyHistogram: Histogram = new Histogram(new ExponentiallyDecayingReservoir) + var shouldTrack = false + + @Pointcut("execution(akka.actor.ActorCell.new(..)) && args(system, ref, props, parent)") + def actorCellCreation(system: ActorSystem, ref: ActorRef, props: Props, parent: ActorRef): Unit = {} + + @Before("actorCellCreation(system, ref, props, parent)") + def registerMetricsInRegistry(system: ActorSystem, ref: ActorRef, props: Props, parent: ActorRef): Unit = { + val actorName = MetricDirectory.nameForActor(ref) + val histogramName = MetricDirectory.nameForMailbox(system.name, actorName) + + // TODO: Find a better way to filter the thins we don't want to measure. + if(system.name != "kamon" && actorName.startsWith("/user")) { + Metrics.registry.register(histogramName + "/cell", latencyHistogram) + shouldTrack = true + } + } + + + + @Pointcut("execution(* akka.actor.ActorCell.invoke(*)) && args(envelope)") + def invokingActorBehaviourAtActorCell(envelope: Envelope) = {} + + + @Around("invokingActorBehaviourAtActorCell(envelope)") + def around(pjp: ProceedingJoinPoint, envelope: Envelope): Unit = { + import ProceedingJoinPointPimp._ + + envelope match { + case Envelope(TraceableMessage(ctx, msg, timeStamp), sender) => { + latencyHistogram.update(System.nanoTime() - timeStamp) + + val originalEnvelope = envelope.copy(message = msg) + ctx match { + case Some(c) => { + Kamon.set(c) + pjp.proceedWith(originalEnvelope) + Kamon.clear + } + case None => pjp.proceedWith(originalEnvelope) + } + } + case _ => pjp.proceed + } + } +} |