forked from kamon-io/Kamon
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
246 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,9 @@ | ||
Kamon | ||
===== | ||
|
||
|
||
|
||
|
||
/metrics/actorsystem/{actorsystem-name}/dispatcher/{dispatcher-name}/ | ||
For each dispatcher, show: | ||
- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,30 @@ | ||
package akka | ||
|
||
import org.aspectj.lang.annotation._ | ||
import akka.dispatch.MonitorableThreadFactory | ||
import kamon.metric.Metrics | ||
import scala.concurrent.forkjoin.ForkJoinPool | ||
import com.codahale.metrics.Gauge | ||
|
||
@Aspect("perthis(poolMonitor(*))") | ||
@Aspect("perthis(poolMonitor(scala.concurrent.forkjoin.ForkJoinPool))") | ||
class PoolMonitorAspect { | ||
println("Created PoolMonitorAspect") | ||
|
||
|
||
@Pointcut("execution(scala.concurrent.forkjoin.ForkJoinPool.new(..)) && this(pool)") | ||
protected def poolMonitor(pool:scala.concurrent.forkjoin.ForkJoinPool):Unit = {} | ||
protected def poolMonitor(pool: scala.concurrent.forkjoin.ForkJoinPool):Unit = {} | ||
|
||
@After("poolMonitor(pool)") | ||
def beforePoolInstantiation(pool: scala.concurrent.forkjoin.ForkJoinPool):Unit = { | ||
pool.getFactory match { | ||
case m: MonitorableThreadFactory => registerForMonitoring(pool, m.name) | ||
} | ||
} | ||
|
||
def registerForMonitoring(fjp: ForkJoinPool, name: String) { | ||
Metrics.registry.register(s"/metrics/actorsystem/{actorsystem-name}/dispatcher/$name", | ||
new Gauge[Long] { | ||
def getValue: Long = fjp.getPoolSize | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
src/main/scala/kamon/instrumentation/DispatcherInstrumentation.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package akka.dispatch | ||
|
||
import org.aspectj.lang.annotation._ | ||
import java.util.concurrent._ | ||
import scala.concurrent.forkjoin.ForkJoinPool | ||
import org.aspectj.lang.ProceedingJoinPoint | ||
import java.util | ||
import akka.dispatch.NamedExecutorServiceFactoryDelegate | ||
import kamon.metric.{MetricDirectory, ExecutorServiceMetricCollector} | ||
|
||
|
||
case class NamedExecutorServiceFactoryDelegate(actorSystemName: String, dispatcherName: String, delegate: ExecutorServiceFactory) extends ExecutorServiceFactory { | ||
def createExecutorService: ExecutorService = delegate.createExecutorService | ||
} | ||
|
||
@Aspect | ||
class ExecutorServiceFactoryProviderInstrumentation { | ||
|
||
@Pointcut("execution(* akka.dispatch.ExecutorServiceFactoryProvider+.createExecutorServiceFactory(..)) && args(id, threadFactory)") | ||
def factoryMethodCall(id: String, threadFactory: ThreadFactory) = {} | ||
|
||
@Around("factoryMethodCall(id, threadFactory)") | ||
def enrichFactoryCreationWithNames(pjp: ProceedingJoinPoint, id: String, threadFactory: ThreadFactory): ExecutorServiceFactory = { | ||
val delegate = pjp.proceed(Array[AnyRef](id, threadFactory)).asInstanceOf[ExecutorServiceFactory] // Safe Cast | ||
|
||
val actorSystemName = threadFactory match { | ||
case m: MonitorableThreadFactory => m.name | ||
case _ => "Unknown" // Find an alternative way to find the actor system name in case we start seeing "Unknown" as the AS name. | ||
} | ||
|
||
new NamedExecutorServiceFactoryDelegate(actorSystemName, id, delegate) | ||
} | ||
|
||
} | ||
|
||
|
||
@Aspect | ||
class NamedExecutorServiceFactoryDelegateInstrumentation { | ||
|
||
@Pointcut("execution(* akka.dispatch.NamedExecutorServiceFactoryDelegate.createExecutorService()) && this(namedFactory)") | ||
def factoryMethodCall(namedFactory: NamedExecutorServiceFactoryDelegate) = {} | ||
|
||
@Around("factoryMethodCall(namedFactory)") | ||
def enrichExecutorServiceWithMetricNameRoot(pjp: ProceedingJoinPoint, namedFactory: NamedExecutorServiceFactoryDelegate): ExecutorService = { | ||
val delegate = pjp.proceed(Array[AnyRef](namedFactory)).asInstanceOf[ExecutorService] | ||
val executorFullName = MetricDirectory.nameForDispatcher(namedFactory.actorSystemName, namedFactory.dispatcherName) | ||
|
||
ExecutorServiceMetricCollector.register(executorFullName, delegate) | ||
|
||
new NamedExecutorServiceDelegate(executorFullName, delegate) | ||
} | ||
} | ||
|
||
case class NamedExecutorServiceDelegate(fullName: String, delegate: ExecutorService) extends ExecutorService { | ||
def shutdown() = { | ||
ExecutorServiceMetricCollector.deregister(fullName) | ||
delegate.shutdown() | ||
} | ||
def shutdownNow(): util.List[Runnable] = delegate.shutdownNow() | ||
def isShutdown: Boolean = delegate.isShutdown | ||
def isTerminated: Boolean = delegate.isTerminated | ||
def awaitTermination(timeout: Long, unit: TimeUnit): Boolean = delegate.awaitTermination(timeout, unit) | ||
def submit[T](task: Callable[T]): Future[T] = delegate.submit(task) | ||
def submit[T](task: Runnable, result: T): Future[T] = delegate.submit(task, result) | ||
def submit(task: Runnable): Future[_] = delegate.submit(task) | ||
def invokeAll[T](tasks: util.Collection[_ <: Callable[T]]): util.List[Future[T]] = delegate.invokeAll(tasks) | ||
def invokeAll[T](tasks: util.Collection[_ <: Callable[T]], timeout: Long, unit: TimeUnit): util.List[Future[T]] = delegate.invokeAll(tasks, timeout, unit) | ||
def invokeAny[T](tasks: util.Collection[_ <: Callable[T]]): T = delegate.invokeAny(tasks) | ||
def invokeAny[T](tasks: util.Collection[_ <: Callable[T]], timeout: Long, unit: TimeUnit): T = delegate.invokeAny(tasks, timeout, unit) | ||
def execute(command: Runnable) = delegate.execute(command) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
src/main/scala/kamon/metric/ExecutorServiceMetricCollector.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package kamon.metric | ||
|
||
import java.util.concurrent.{ThreadPoolExecutor, ExecutorService} | ||
import scala.concurrent.forkjoin.ForkJoinPool | ||
import com.codahale.metrics.{Metric, MetricFilter} | ||
|
||
object ExecutorServiceMetricCollector extends ForkJoinPoolMetricCollector with ThreadPoolExecutorMetricCollector { | ||
|
||
def register(fullName: String, executorService: ExecutorService) = executorService match { | ||
case fjp: ForkJoinPool => registerForkJoinPool(fullName, fjp) | ||
case tpe: ThreadPoolExecutor => registerThreadPoolExecutor(fullName, tpe) | ||
case _ => // If it is a unknown Executor then just do nothing. | ||
} | ||
|
||
def deregister(fullName: String) = { | ||
Metrics.registry.removeMatching(new MetricFilter { | ||
def matches(name: String, metric: Metric): Boolean = name.startsWith(fullName) | ||
}) | ||
} | ||
} | ||
|
||
|
||
trait ForkJoinPoolMetricCollector { | ||
import GaugeGenerator._ | ||
import BasicExecutorMetricNames._ | ||
|
||
|
||
def registerForkJoinPool(fullName: String, fjp: ForkJoinPool) = { | ||
val forkJoinPoolGauge = newNumericGaugeFor(fjp) _ | ||
|
||
val allMetrics = Map( | ||
fullName + queueSize -> forkJoinPoolGauge(_.getQueuedTaskCount.toInt), | ||
fullName + poolSize -> forkJoinPoolGauge(_.getPoolSize), | ||
fullName + activeThreads -> forkJoinPoolGauge(_.getActiveThreadCount) | ||
) | ||
|
||
allMetrics.foreach(kv => Metrics.registry.register(kv._1, kv._2)) | ||
} | ||
} | ||
|
||
trait ThreadPoolExecutorMetricCollector { | ||
import GaugeGenerator._ | ||
import BasicExecutorMetricNames._ | ||
|
||
def registerThreadPoolExecutor(fullName: String, tpe: ThreadPoolExecutor) = { | ||
val tpeGauge = newNumericGaugeFor(tpe) _ | ||
|
||
val allMetrics = Map( | ||
fullName + queueSize -> tpeGauge(_.getQueue.size()), | ||
fullName + poolSize -> tpeGauge(_.getPoolSize), | ||
fullName + activeThreads -> tpeGauge(_.getActiveCount) | ||
) | ||
|
||
allMetrics.foreach(kv => Metrics.registry.register(kv._1, kv._2)) | ||
} | ||
} | ||
|
||
|
||
object BasicExecutorMetricNames { | ||
val queueSize = "queueSize" | ||
val poolSize = "poolSize" | ||
val activeThreads = "activeThreads" | ||
} | ||
|
||
|
||
|
||
|
Oops, something went wrong.