aboutsummaryrefslogtreecommitdiff
path: root/kamon-trace/src/main/scala/kamon/trace/instrumentation/AskPatternTracing.scala
blob: 625ed1ae9cf870e9d10f272e7391f1ae81fcb326 (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
package akka.pattern.tracing

import org.aspectj.lang.annotation.{After, AfterReturning, Pointcut, Aspect}
import akka.pattern.{AskTimeoutException, PromiseActorRef}
import akka.event.Logging.Warning
import scala.compat.Platform.EOL
import akka.actor.ActorRefProvider

@Aspect
class AskPatternTracing {

  class StackTraceCaptureException extends Throwable

  @Pointcut(value = "execution(* akka.pattern.PromiseActorRef$.apply(..)) && args(provider, *)", argNames = "provider")
  def promiseActorRefApply(provider: ActorRefProvider): Unit = {
    provider.settings.config.getBoolean("kamon.trace.ask-pattern-tracing")
  }

  @AfterReturning(pointcut = "promiseActorRefApply(provider)", returning = "promiseActor")
  def hookAskTimeoutWarning(provider: ActorRefProvider, promiseActor: PromiseActorRef): Unit = {
    val future = promiseActor.result.future
    val system = promiseActor.provider.guardian.underlying.system
    implicit val ec = system.dispatcher
    val stack = new StackTraceCaptureException

    future onFailure {
      case timeout: AskTimeoutException =>
        val stackString = stack.getStackTrace.drop(3).mkString("", EOL, EOL)

        system.eventStream.publish(Warning("AskPatternTracing", classOf[AskPatternTracing],
          "Timeout triggered for ask pattern registered at: " + stackString))
    }
  }
}