aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Topolnjak <ivantopo@gmail.com>2015-02-12 11:30:06 +0100
committerIvan Topolnjak <ivantopo@gmail.com>2015-02-13 05:15:30 +0100
commitc6bb65535bcc3cc1ff3834a91473ee8dfa6145e8 (patch)
treed7dbe6a1007b168998f167ac74a98744542c6fa8
parent6729c9632245328a007332cdcce7d362584d735a (diff)
downloadKamon-c6bb65535bcc3cc1ff3834a91473ee8dfa6145e8.tar.gz
Kamon-c6bb65535bcc3cc1ff3834a91473ee8dfa6145e8.tar.bz2
Kamon-c6bb65535bcc3cc1ff3834a91473ee8dfa6145e8.zip
! all: Kamon now works as a single instance in a companion object.
-rw-r--r--kamon-akka-remote/src/main/scala/kamon/akka/instrumentation/RemotingInstrumentation.scala5
-rw-r--r--kamon-akka-remote/src/test/scala/kamon/akka/instrumentation/RemotingInstrumentationSpec.scala53
-rw-r--r--kamon-akka/src/main/scala/kamon/akka/instrumentation/ActorCellInstrumentation.scala11
-rw-r--r--kamon-akka/src/main/scala/kamon/akka/instrumentation/AskPatternInstrumentation.scala2
-rw-r--r--kamon-akka/src/main/scala/kamon/akka/instrumentation/DispatcherInstrumentation.scala9
-rw-r--r--kamon-akka/src/test/scala/kamon/akka/ActorMetricsSpec.scala (renamed from kamon-akka/src/test/scala/kamon/metric/ActorMetricsSpec.scala)62
-rw-r--r--kamon-akka/src/test/scala/kamon/akka/DispatcherMetricsSpec.scala (renamed from kamon-akka/src/test/scala/kamon/metric/DispatcherMetricsSpec.scala)116
-rw-r--r--kamon-akka/src/test/scala/kamon/akka/RouterMetricsSpec.scala (renamed from kamon-akka/src/test/scala/kamon/metric/RouterMetricsSpec.scala)49
-rw-r--r--kamon-akka/src/test/scala/kamon/akka/instrumentation/AskPatternInstrumentationSpec.scala2
-rw-r--r--kamon-core/src/main/scala/kamon/Kamon.scala76
-rw-r--r--kamon-core/src/main/scala/kamon/metric/MetricsExtension.scala61
-rw-r--r--kamon-core/src/main/scala/kamon/metric/MetricsExtensionSettings.scala35
-rw-r--r--kamon-core/src/main/scala/kamon/metric/SubscriptionsDispatcher.scala9
-rw-r--r--kamon-core/src/main/scala/kamon/metric/TickMetricSnapshotBuffer.scala2
-rw-r--r--kamon-core/src/main/scala/kamon/metric/UserMetrics.scala33
-rw-r--r--kamon-core/src/main/scala/kamon/metric/instrument/Instrument.scala19
-rw-r--r--kamon-core/src/main/scala/kamon/metric/instrument/RefreshScheduler.scala99
-rw-r--r--kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala6
-rw-r--r--kamon-core/src/main/scala/kamon/trace/TraceContext.scala11
-rw-r--r--kamon-core/src/main/scala/kamon/trace/TracerExtension.scala62
-rw-r--r--kamon-core/src/main/scala/kamon/trace/TracerExtensionSettings.scala6
-rw-r--r--kamon-core/src/main/scala/kamon/trace/TracingContext.scala5
-rw-r--r--kamon-core/src/main/scala/kamon/util/LazyActorRef.scala53
-rw-r--r--kamon-core/src/test/scala/kamon/metric/SubscriptionsProtocolSpec.scala3
-rw-r--r--kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala5
-rw-r--r--kamon-core/src/test/scala/kamon/metric/UserMetricsSpec.scala63
-rw-r--r--kamon-core/src/test/scala/kamon/metric/instrument/GaugeSpec.scala7
-rw-r--r--kamon-core/src/test/scala/kamon/metric/instrument/MinMaxCounterSpec.scala3
-rw-r--r--kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala28
-rw-r--r--kamon-core/src/test/scala/kamon/trace/SimpleTraceSpec.scala8
-rw-r--r--kamon-datadog/src/main/scala/kamon/datadog/Datadog.scala2
-rw-r--r--kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala34
-rw-r--r--kamon-jdbc/src/main/scala/kamon/jdbc/instrumentation/StatementInstrumentation.scala6
-rw-r--r--kamon-log-reporter/src/main/scala/kamon/logreporter/LogReporter.scala8
-rw-r--r--kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala4
-rw-r--r--kamon-newrelic/src/main/scala/kamon/newrelic/MetricReporter.scala2
-rw-r--r--kamon-newrelic/src/test/scala/kamon/newrelic/MetricReporterSpec.scala45
-rw-r--r--kamon-play/src/main/scala/kamon/play/Play.scala6
-rw-r--r--kamon-play/src/main/scala/kamon/play/instrumentation/RequestInstrumentation.scala17
-rw-r--r--kamon-play/src/main/scala/kamon/play/instrumentation/WSInstrumentation.scala3
-rw-r--r--kamon-play/src/test/scala/kamon/play/LoggerLikeInstrumentationSpec.scala3
-rw-r--r--kamon-play/src/test/scala/kamon/play/RequestInstrumentationSpec.scala15
-rw-r--r--kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala12
-rw-r--r--kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala6
-rw-r--r--kamon-spray/src/main/scala/kamon/spray/SprayExtension.scala6
-rw-r--r--kamon-spray/src/main/scala/kamon/spray/instrumentation/ClientRequestInstrumentation.scala7
-rw-r--r--kamon-spray/src/main/scala/kamon/spray/instrumentation/ServerRequestInstrumentation.scala9
-rw-r--r--kamon-spray/src/test/scala/kamon/spray/ClientRequestInstrumentationSpec.scala4
-rw-r--r--kamon-spray/src/test/scala/kamon/spray/SprayServerTracingSpec.scala2
-rw-r--r--kamon-statsd/src/main/scala/kamon/statsd/StatsD.scala2
-rw-r--r--kamon-statsd/src/test/scala/kamon/statsd/StatsDMetricSenderSpec.scala33
-rw-r--r--kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsExtension.scala2
-rw-r--r--kamon-system-metrics/src/main/scala/kamon/system/custom/ContextSwitchesMetrics.scala2
-rw-r--r--kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarMetricsUpdater.scala4
-rw-r--r--project/Projects.scala6
-rw-r--r--project/Settings.scala24
56 files changed, 674 insertions, 493 deletions
diff --git a/kamon-akka-remote/src/main/scala/kamon/akka/instrumentation/RemotingInstrumentation.scala b/kamon-akka-remote/src/main/scala/kamon/akka/instrumentation/RemotingInstrumentation.scala
index eb18ed87..32a3bcc9 100644
--- a/kamon-akka-remote/src/main/scala/kamon/akka/instrumentation/RemotingInstrumentation.scala
+++ b/kamon-akka-remote/src/main/scala/kamon/akka/instrumentation/RemotingInstrumentation.scala
@@ -5,7 +5,8 @@ import akka.remote.instrumentation.TraceContextAwareWireFormats.{ TraceContextAw
import akka.remote.{ RemoteActorRefProvider, Ack, SeqNo }
import akka.remote.WireFormats._
import akka.util.ByteString
-import kamon.trace.{ Tracer, TraceContext }
+import kamon.Kamon
+import kamon.trace.TraceContext
import kamon.util.MilliTimestamp
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation._
@@ -83,7 +84,7 @@ class RemotingInstrumentation {
if (ackAndEnvelope.hasEnvelope && ackAndEnvelope.getEnvelope.hasTraceContext) {
val remoteTraceContext = ackAndEnvelope.getEnvelope.getTraceContext
val system = provider.guardian.underlying.system
- val tracer = Tracer.get(system)
+ val tracer = Kamon.tracer
val ctx = tracer.newContext(
remoteTraceContext.getTraceName,
diff --git a/kamon-akka-remote/src/test/scala/kamon/akka/instrumentation/RemotingInstrumentationSpec.scala b/kamon-akka-remote/src/test/scala/kamon/akka/instrumentation/RemotingInstrumentationSpec.scala
index 367a7349..ccfde35a 100644
--- a/kamon-akka-remote/src/test/scala/kamon/akka/instrumentation/RemotingInstrumentationSpec.scala
+++ b/kamon-akka-remote/src/test/scala/kamon/akka/instrumentation/RemotingInstrumentationSpec.scala
@@ -16,23 +16,27 @@ import scala.concurrent.duration._
import scala.util.control.NonFatal
class RemotingInstrumentationSpec extends TestKitBase with WordSpecLike with Matchers with ImplicitSender {
- implicit lazy val system: ActorSystem = ActorSystem("remoting-spec-local-system", ConfigFactory.parseString(
- """
- |akka {
- | loggers = ["akka.event.slf4j.Slf4jLogger"]
- |
- | actor {
- | provider = "akka.remote.RemoteActorRefProvider"
- | }
- | remote {
- | enabled-transports = ["akka.remote.netty.tcp"]
- | netty.tcp {
- | hostname = "127.0.0.1"
- | port = 2552
- | }
- | }
- |}
- """.stripMargin))
+
+ implicit lazy val system: ActorSystem = {
+ Kamon.start()
+ ActorSystem("remoting-spec-local-system", ConfigFactory.parseString(
+ """
+ |akka {
+ | loggers = ["akka.event.slf4j.Slf4jLogger"]
+ |
+ | actor {
+ | provider = "akka.remote.RemoteActorRefProvider"
+ | }
+ | remote {
+ | enabled-transports = ["akka.remote.netty.tcp"]
+ | netty.tcp {
+ | hostname = "127.0.0.1"
+ | port = 2552
+ | }
+ | }
+ |}
+ """.stripMargin))
+ }
val remoteSystem: ActorSystem = ActorSystem("remoting-spec-remote-system", ConfigFactory.parseString(
"""
@@ -52,13 +56,12 @@ class RemotingInstrumentationSpec extends TestKitBase with WordSpecLike with Mat
|}
""".stripMargin))
- lazy val kamon = Kamon(system)
val RemoteSystemAddress = AddressFromURIString("akka.tcp://remoting-spec-remote-system@127.0.0.1:2553")
- import kamon.tracer.newContext
+ import Kamon.tracer
"The Remoting instrumentation" should {
"propagate the TraceContext when creating a new remote actor" in {
- TraceContext.withContext(newContext("deploy-remote-actor", "deploy-remote-actor-1")) {
+ TraceContext.withContext(tracer.newContext("deploy-remote-actor", "deploy-remote-actor-1")) {
system.actorOf(TraceTokenReplier.remoteProps(Some(testActor), RemoteSystemAddress), "remote-deploy-fixture")
}
@@ -68,7 +71,7 @@ class RemotingInstrumentationSpec extends TestKitBase with WordSpecLike with Mat
"propagate the TraceContext when sending a message to a remotely deployed actor" in {
val remoteRef = system.actorOf(TraceTokenReplier.remoteProps(None, RemoteSystemAddress), "remote-message-fixture")
- TraceContext.withContext(newContext("message-remote-actor", "message-remote-actor-1")) {
+ TraceContext.withContext(tracer.newContext("message-remote-actor", "message-remote-actor-1")) {
remoteRef ! "reply-trace-token"
}
@@ -80,7 +83,7 @@ class RemotingInstrumentationSpec extends TestKitBase with WordSpecLike with Mat
implicit val askTimeout = Timeout(10 seconds)
val remoteRef = system.actorOf(TraceTokenReplier.remoteProps(None, RemoteSystemAddress), "remote-ask-and-pipe-fixture")
- TraceContext.withContext(newContext("ask-and-pipe-remote-actor", "ask-and-pipe-remote-actor-1")) {
+ TraceContext.withContext(tracer.newContext("ask-and-pipe-remote-actor", "ask-and-pipe-remote-actor-1")) {
(remoteRef ? "reply-trace-token") pipeTo (testActor)
}
@@ -92,7 +95,7 @@ class RemotingInstrumentationSpec extends TestKitBase with WordSpecLike with Mat
remoteSystem.actorOf(TraceTokenReplier.props(None), "actor-selection-target-b")
val selection = system.actorSelection(RemoteSystemAddress + "/user/actor-selection-target-*")
- TraceContext.withContext(newContext("message-remote-actor-selection", "message-remote-actor-selection-1")) {
+ TraceContext.withContext(tracer.newContext("message-remote-actor-selection", "message-remote-actor-selection-1")) {
selection ! "reply-trace-token"
}
@@ -104,7 +107,7 @@ class RemotingInstrumentationSpec extends TestKitBase with WordSpecLike with Mat
"propagate the TraceContext a remotely supervised child fails" in {
val supervisor = system.actorOf(Props(new SupervisorOfRemote(testActor, RemoteSystemAddress)))
- TraceContext.withContext(newContext("remote-supervision", "remote-supervision-1")) {
+ TraceContext.withContext(tracer.newContext("remote-supervision", "remote-supervision-1")) {
supervisor ! "fail"
}
@@ -115,7 +118,7 @@ class RemotingInstrumentationSpec extends TestKitBase with WordSpecLike with Mat
remoteSystem.actorOf(TraceTokenReplier.props(None), "remote-routee")
val router = system.actorOf(RoundRobinGroup(List(RemoteSystemAddress + "/user/actor-selection-target-*")).props(), "router")
- TraceContext.withContext(newContext("remote-routee", "remote-routee-1")) {
+ TraceContext.withContext(tracer.newContext("remote-routee", "remote-routee-1")) {
router ! "reply-trace-token"
}
diff --git a/kamon-akka/src/main/scala/kamon/akka/instrumentation/ActorCellInstrumentation.scala b/kamon-akka/src/main/scala/kamon/akka/instrumentation/ActorCellInstrumentation.scala
index c961737d..7c722569 100644
--- a/kamon-akka/src/main/scala/kamon/akka/instrumentation/ActorCellInstrumentation.scala
+++ b/kamon-akka/src/main/scala/kamon/akka/instrumentation/ActorCellInstrumentation.scala
@@ -19,8 +19,9 @@ package akka.kamon.instrumentation
import akka.actor._
import akka.dispatch.{ Envelope, MessageDispatcher }
import akka.routing.RoutedActorCell
+import kamon.Kamon
import kamon.akka.{ RouterMetrics, ActorMetrics }
-import kamon.metric.{ Metrics, Entity }
+import kamon.metric.Entity
import kamon.trace._
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation._
@@ -33,7 +34,7 @@ class ActorCellInstrumentation {
@After("actorCellCreation(cell, system, ref, props, dispatcher, parent)")
def afterCreation(cell: ActorCell, system: ActorSystem, ref: ActorRef, props: Props, dispatcher: MessageDispatcher, parent: ActorRef): Unit = {
- Metrics.get(system).register(ActorMetrics, ref.path.elements.mkString("/")).map { registration ⇒
+ Kamon.metrics.register(ActorMetrics, ref.path.elements.mkString("/")).map { registration ⇒
val cellMetrics = cell.asInstanceOf[ActorCellMetrics]
cellMetrics.entity = registration.entity
@@ -89,14 +90,14 @@ class ActorCellInstrumentation {
def afterStop(cell: ActorCell): Unit = {
val cellMetrics = cell.asInstanceOf[ActorCellMetrics]
cellMetrics.recorder.map { _ ⇒
- Metrics.get(cell.system).unregister(cellMetrics.entity)
+ Kamon.metrics.unregister(cellMetrics.entity)
}
// The Stop can't be captured from the RoutedActorCell so we need to put this piece of cleanup here.
if (cell.isInstanceOf[RoutedActorCell]) {
val routedCellMetrics = cell.asInstanceOf[RoutedActorCellMetrics]
routedCellMetrics.routerRecorder.map { _ ⇒
- Metrics.get(cell.system).unregister(routedCellMetrics.routerEntity)
+ Kamon.metrics.unregister(routedCellMetrics.routerEntity)
}
}
}
@@ -123,7 +124,7 @@ class RoutedActorCellInstrumentation {
@After("routedActorCellCreation(cell, system, ref, props, dispatcher, routeeProps, supervisor)")
def afterRoutedActorCellCreation(cell: RoutedActorCell, system: ActorSystem, ref: ActorRef, props: Props, dispatcher: MessageDispatcher, routeeProps: Props, supervisor: ActorRef): Unit = {
- Metrics.get(system).register(RouterMetrics, ref.path.elements.mkString("/")).map { registration ⇒
+ Kamon.metrics.register(RouterMetrics, ref.path.elements.mkString("/")).map { registration ⇒
val cellMetrics = cell.asInstanceOf[RoutedActorCellMetrics]
cellMetrics.routerEntity = registration.entity
diff --git a/kamon-akka/src/main/scala/kamon/akka/instrumentation/AskPatternInstrumentation.scala b/kamon-akka/src/main/scala/kamon/akka/instrumentation/AskPatternInstrumentation.scala
index 28bfcae9..e1dcdf32 100644
--- a/kamon-akka/src/main/scala/kamon/akka/instrumentation/AskPatternInstrumentation.scala
+++ b/kamon-akka/src/main/scala/kamon/akka/instrumentation/AskPatternInstrumentation.scala
@@ -44,7 +44,7 @@ class AskPatternInstrumentation {
actor match {
// the AskPattern will only work for InternalActorRef's with these conditions.
case ref: InternalActorRef if !ref.isTerminated && timeout.duration.length > 0 ⇒
- val akkaExtension = ctx.lookupExtension(Akka)
+ val akkaExtension = Kamon.extension(Akka)
val future = pjp.proceed().asInstanceOf[Future[AnyRef]]
val system = ref.provider.guardian.underlying.system
diff --git a/kamon-akka/src/main/scala/kamon/akka/instrumentation/DispatcherInstrumentation.scala b/kamon-akka/src/main/scala/kamon/akka/instrumentation/DispatcherInstrumentation.scala
index f4bc31c4..7b15c443 100644
--- a/kamon-akka/src/main/scala/kamon/akka/instrumentation/DispatcherInstrumentation.scala
+++ b/kamon-akka/src/main/scala/kamon/akka/instrumentation/DispatcherInstrumentation.scala
@@ -22,8 +22,9 @@ import akka.actor.{ ActorSystem, ActorSystemImpl }
import akka.dispatch.ForkJoinExecutorConfigurator.AkkaForkJoinPool
import akka.dispatch._
import akka.kamon.instrumentation.LookupDataAware.LookupData
+import kamon.Kamon
import kamon.akka.{ AkkaDispatcherMetrics, ThreadPoolExecutorDispatcherMetrics, ForkJoinPoolDispatcherMetrics }
-import kamon.metric.{ Metrics, Entity }
+import kamon.metric.Entity
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation._
@@ -58,10 +59,10 @@ class DispatcherInstrumentation {
private def registerDispatcher(dispatcherName: String, executorService: ExecutorService, system: ActorSystem): Unit =
executorService match {
case fjp: AkkaForkJoinPool ⇒
- Metrics.get(system).register(ForkJoinPoolDispatcherMetrics.factory(fjp), dispatcherName)
+ Kamon.metrics.register(ForkJoinPoolDispatcherMetrics.factory(fjp), dispatcherName)
case tpe: ThreadPoolExecutor ⇒
- Metrics.get(system).register(ThreadPoolExecutorDispatcherMetrics.factory(tpe), dispatcherName)
+ Kamon.metrics.register(ThreadPoolExecutorDispatcherMetrics.factory(tpe), dispatcherName)
case others ⇒ // Currently not interested in other kinds of dispatchers.
}
@@ -119,7 +120,7 @@ class DispatcherInstrumentation {
import lazyExecutor.lookupData
if (lookupData.actorSystem != null)
- Metrics.get(lookupData.actorSystem).unregister(Entity(lookupData.dispatcherName, AkkaDispatcherMetrics.Category))
+ Kamon.metrics.unregister(Entity(lookupData.dispatcherName, AkkaDispatcherMetrics.Category))
}
}
diff --git a/kamon-akka/src/test/scala/kamon/metric/ActorMetricsSpec.scala b/kamon-akka/src/test/scala/kamon/akka/ActorMetricsSpec.scala
index 322abed2..19a71053 100644
--- a/kamon-akka/src/test/scala/kamon/metric/ActorMetricsSpec.scala
+++ b/kamon-akka/src/test/scala/kamon/akka/ActorMetricsSpec.scala
@@ -13,42 +13,44 @@
* =========================================================================================
*/
-package kamon.metric
+package kamon.akka
import java.nio.LongBuffer
-import kamon.Kamon
-import kamon.akka.ActorMetrics
-import kamon.metric.ActorMetricsTestActor._
-import kamon.metric.instrument.CollectionContext
-import org.scalatest.{ BeforeAndAfterAll, WordSpecLike, Matchers }
-import akka.testkit.{ ImplicitSender, TestProbe, TestKitBase }
import akka.actor._
+import akka.testkit.TestProbe
import com.typesafe.config.ConfigFactory
+import kamon.Kamon
+import kamon.akka.ActorMetricsTestActor._
+import kamon.metric.EntitySnapshot
+import kamon.metric.instrument.CollectionContext
+import kamon.testkit.BaseKamonSpec
+
import scala.concurrent.duration._
-class ActorMetricsSpec extends TestKitBase with WordSpecLike with Matchers with ImplicitSender with BeforeAndAfterAll {
- implicit lazy val system: ActorSystem = ActorSystem("actor-metrics-spec", ConfigFactory.parseString(
- """
- |kamon.metric {
- | tick-interval = 1 hour
- | default-collection-context-buffer-size = 10
- |
- | filters {
- | akka-actor {
- | includes = [ "user/tracked-*", "user/measuring-*", "user/clean-after-collect", "user/stop" ]
- | excludes = [ "user/tracked-explicitly-excluded", "user/non-tracked-actor" ]
- | }
- | }
- |
- | instrument-settings {
- | akka-actor.mailbox-size.refresh-interval = 1 hour
- | }
- |}
- |
- |akka.loglevel = OFF
- |
- """.stripMargin))
+class ActorMetricsSpec extends BaseKamonSpec("actor-metrics-spec") {
+ override lazy val config =
+ ConfigFactory.parseString(
+ """
+ |kamon.metric {
+ | tick-interval = 1 hour
+ | default-collection-context-buffer-size = 10
+ |
+ | filters {
+ | akka-actor {
+ | includes = [ "user/tracked-*", "user/measuring-*", "user/clean-after-collect", "user/stop" ]
+ | excludes = [ "user/tracked-explicitly-excluded", "user/non-tracked-actor" ]
+ | }
+ | }
+ |
+ | instrument-settings {
+ | akka-actor.mailbox-size.refresh-interval = 1 hour
+ | }
+ |}
+ |
+ |akka.loglevel = OFF
+ |
+ """.stripMargin)
"the Kamon actor metrics" should {
"respect the configured include and exclude filters" in new ActorMetricsFixtures {
@@ -163,7 +165,7 @@ class ActorMetricsSpec extends TestKitBase with WordSpecLike with Matchers with
def actorRecorderName(ref: ActorRef): String = ref.path.elements.mkString("/")
def actorMetricsRecorderOf(ref: ActorRef): Option[ActorMetrics] =
- Kamon(Metrics)(system).register(ActorMetrics, actorRecorderName(ref)).map(_.recorder)
+ Kamon.metrics.register(ActorMetrics, actorRecorderName(ref)).map(_.recorder)
def collectMetricsOf(ref: ActorRef): Option[EntitySnapshot] = {
Thread.sleep(5) // Just in case the test advances a bit faster than the actor being tested.
diff --git a/kamon-akka/src/test/scala/kamon/metric/DispatcherMetricsSpec.scala b/kamon-akka/src/test/scala/kamon/akka/DispatcherMetricsSpec.scala
index 2c530da9..209b5cf5 100644
--- a/kamon-akka/src/test/scala/kamon/metric/DispatcherMetricsSpec.scala
+++ b/kamon-akka/src/test/scala/kamon/akka/DispatcherMetricsSpec.scala
@@ -13,72 +13,73 @@
* =========================================================================================
*/
-package kamon.metric
+package kamon.akka
import java.nio.LongBuffer
-import akka.actor.{ PoisonPill, Props, ActorRef, ActorSystem }
+import akka.actor.{ ActorRef, ActorSystem }
import akka.dispatch.MessageDispatcher
import akka.testkit.{ TestKitBase, TestProbe }
import com.typesafe.config.ConfigFactory
import kamon.Kamon
-import kamon.akka.{ ForkJoinPoolDispatcherMetrics, ThreadPoolExecutorDispatcherMetrics }
-import kamon.metric.ActorMetricsTestActor.{ Pong, Ping }
import kamon.metric.instrument.CollectionContext
+import kamon.metric.{ EntityRecorder, EntitySnapshot }
+import kamon.testkit.BaseKamonSpec
import org.scalatest.{ BeforeAndAfterAll, Matchers, WordSpecLike }
-import scala.concurrent.{ Await, Future }
import scala.concurrent.duration._
+import scala.concurrent.{ Await, Future }
-class DispatcherMetricsSpec extends TestKitBase with WordSpecLike with Matchers with BeforeAndAfterAll {
- implicit lazy val system: ActorSystem = ActorSystem("dispatcher-metrics-spec", ConfigFactory.parseString(
- """
- |kamon.metric {
- | tick-interval = 1 hour
- | default-collection-context-buffer-size = 10
- |
- | filters = {
- | akka-dispatcher {
- | includes = [ "*" ]
- | excludes = [ "explicitly-excluded" ]
- | }
- | }
- |
- | default-instrument-settings {
- | gauge.refresh-interval = 1 hour
- | min-max-counter.refresh-interval = 1 hour
- | }
- |}
- |
- |explicitly-excluded {
- | type = "Dispatcher"
- | executor = "fork-join-executor"
- |}
- |
- |tracked-fjp {
- | type = "Dispatcher"
- | executor = "fork-join-executor"
- |
- | fork-join-executor {
- | parallelism-min = 8
- | parallelism-factor = 100.0
- | parallelism-max = 22
- | }
- |}
- |
- |tracked-tpe {
- | type = "Dispatcher"
- | executor = "thread-pool-executor"
- |
- | thread-pool-executor {
- | core-pool-size-min = 7
- | core-pool-size-factor = 100.0
- | max-pool-size-factor = 100.0
- | max-pool-size-max = 21
- | }
- |}
- |
- """.stripMargin))
+class DispatcherMetricsSpec extends BaseKamonSpec("dispatcher-metrics-spec") {
+ override lazy val config =
+ ConfigFactory.parseString(
+ """
+ |kamon.metric {
+ | tick-interval = 1 hour
+ | default-collection-context-buffer-size = 10
+ |
+ | filters = {
+ | akka-dispatcher {
+ | includes = [ "*" ]
+ | excludes = [ "explicitly-excluded" ]
+ | }
+ | }
+ |
+ | default-instrument-settings {
+ | gauge.refresh-interval = 1 hour
+ | min-max-counter.refresh-interval = 1 hour
+ | }
+ |}
+ |
+ |explicitly-excluded {
+ | type = "Dispatcher"
+ | executor = "fork-join-executor"
+ |}
+ |
+ |tracked-fjp {
+ | type = "Dispatcher"
+ | executor = "fork-join-executor"
+ |
+ | fork-join-executor {
+ | parallelism-min = 8
+ | parallelism-factor = 100.0
+ | parallelism-max = 22
+ | }
+ |}
+ |
+ |tracked-tpe {
+ | type = "Dispatcher"
+ | executor = "thread-pool-executor"
+ |
+ | thread-pool-executor {
+ | core-pool-size-min = 7
+ | core-pool-size-factor = 100.0
+ | max-pool-size-factor = 100.0
+ | max-pool-size-max = 21
+ | }
+ |}
+ |
+ """.stripMargin)
"the Kamon dispatcher metrics" should {
"respect the configured include and exclude filters" in {
@@ -95,6 +96,7 @@ class DispatcherMetricsSpec extends TestKitBase with WordSpecLike with Matchers
"record metrics for a dispatcher with thread-pool-executor" in {
implicit val tpeDispatcher = system.dispatchers.lookup("tracked-tpe")
+ refreshDispatcherInstruments(tpeDispatcher)
collectDispatcherMetrics(tpeDispatcher)
Await.result({
@@ -156,14 +158,10 @@ class DispatcherMetricsSpec extends TestKitBase with WordSpecLike with Matchers
}
- val collectionContext = new CollectionContext {
- val buffer: LongBuffer = LongBuffer.allocate(10000)
- }
-
def actorRecorderName(ref: ActorRef): String = ref.path.elements.mkString("/")
def findDispatcherRecorder(dispatcher: MessageDispatcher): Option[EntityRecorder] =
- Kamon(Metrics)(system).find(dispatcher.id, "akka-dispatcher")
+ Kamon.metrics.find(dispatcher.id, "akka-dispatcher")
def collectDispatcherMetrics(dispatcher: MessageDispatcher): EntitySnapshot =
findDispatcherRecorder(dispatcher).map(_.collect(collectionContext)).get
diff --git a/kamon-akka/src/test/scala/kamon/metric/RouterMetricsSpec.scala b/kamon-akka/src/test/scala/kamon/akka/RouterMetricsSpec.scala
index 5f6bbb4f..ec55648b 100644
--- a/kamon-akka/src/test/scala/kamon/metric/RouterMetricsSpec.scala
+++ b/kamon-akka/src/test/scala/kamon/akka/RouterMetricsSpec.scala
@@ -13,40 +13,41 @@
* =========================================================================================
*/
-package kamon.metric
+package kamon.akka
import java.nio.LongBuffer
import akka.actor._
import akka.routing._
-import akka.testkit.{ ImplicitSender, TestKitBase, TestProbe }
+import akka.testkit.TestProbe
import com.typesafe.config.ConfigFactory
import kamon.Kamon
-import kamon.akka.RouterMetrics
-import kamon.metric.RouterMetricsTestActor._
+import kamon.akka.RouterMetricsTestActor._
+import kamon.metric.EntitySnapshot
import kamon.metric.instrument.CollectionContext
-import org.scalatest.{ BeforeAndAfterAll, Matchers, WordSpecLike }
+import kamon.testkit.BaseKamonSpec
import scala.concurrent.duration._
-class RouterMetricsSpec extends TestKitBase with WordSpecLike with Matchers with ImplicitSender with BeforeAndAfterAll {
- implicit lazy val system: ActorSystem = ActorSystem("router-metrics-spec", ConfigFactory.parseString(
- """
- |kamon.metric {
- | tick-interval = 1 hour
- | default-collection-context-buffer-size = 10
- |
- | filters = {
- | akka-router {
- | includes = [ "user/tracked-*", "user/measuring-*", "user/stop-*" ]
- | excludes = [ "user/tracked-explicitly-excluded-*"]
- | }
- | }
- |}
- |
- |akka.loglevel = OFF
- |
- """.stripMargin))
+class RouterMetricsSpec extends BaseKamonSpec("router-metrics-spec") {
+ override lazy val config =
+ ConfigFactory.parseString(
+ """
+ |kamon.metric {
+ | tick-interval = 1 hour
+ | default-collection-context-buffer-size = 10
+ |
+ | filters = {
+ | akka-router {
+ | includes = [ "user/tracked-*", "user/measuring-*", "user/stop-*" ]
+ | excludes = [ "user/tracked-explicitly-excluded-*"]
+ | }
+ | }
+ |}
+ |
+ |akka.loglevel = OFF
+ |
+ """.stripMargin)
"the Kamon router metrics" should {
"respect the configured include and exclude filters" in new RouterMetricsFixtures {
@@ -204,7 +205,7 @@ class RouterMetricsSpec extends TestKitBase with WordSpecLike with Matchers with
}
def routerMetricsRecorderOf(routerName: String): Option[RouterMetrics] =
- Kamon(Metrics)(system).register(RouterMetrics, routerName).map(_.recorder)
+ Kamon.metrics.register(RouterMetrics, routerName).map(_.recorder)
def collectMetricsOf(routerName: String): Option[EntitySnapshot] = {
Thread.sleep(5) // Just in case the test advances a bit faster than the actor being tested.
diff --git a/kamon-akka/src/test/scala/kamon/akka/instrumentation/AskPatternInstrumentationSpec.scala b/kamon-akka/src/test/scala/kamon/akka/instrumentation/AskPatternInstrumentationSpec.scala
index 0d63a19e..44b90642 100644
--- a/kamon-akka/src/test/scala/kamon/akka/instrumentation/AskPatternInstrumentationSpec.scala
+++ b/kamon-akka/src/test/scala/kamon/akka/instrumentation/AskPatternInstrumentationSpec.scala
@@ -114,7 +114,7 @@ class AskPatternInstrumentationSpec extends BaseKamonSpec("ask-pattern-tracing-s
}
def setAskPatternTimeoutWarningMode(mode: String): Unit = {
- val target = Kamon(Akka)(system)
+ val target = Kamon(Akka)
val field = target.getClass.getDeclaredField("askPatternTimeoutWarning")
field.setAccessible(true)
field.set(target, mode)
diff --git a/kamon-core/src/main/scala/kamon/Kamon.scala b/kamon-core/src/main/scala/kamon/Kamon.scala
index 6fedc065..2bed4737 100644
--- a/kamon-core/src/main/scala/kamon/Kamon.scala
+++ b/kamon-core/src/main/scala/kamon/Kamon.scala
@@ -16,49 +16,61 @@ package kamon
import _root_.akka.actor
import _root_.akka.actor._
-import com.typesafe.config.Config
+import com.typesafe.config.{ ConfigFactory, Config }
import kamon.metric._
-import kamon.supervisor.ModuleSupervisor
-import kamon.trace.{ Tracer, TracerExtension }
+import kamon.trace.{ TracerExtensionImpl, TracerExtension }
-class Kamon(val actorSystem: ActorSystem) {
- val metrics: MetricsExtension = Metrics.get(actorSystem)
- val tracer: TracerExtension = Tracer.get(actorSystem)
- val userMetrics: UserMetricsExtension = UserMetrics.get(actorSystem)
+object Kamon {
+ trait Extension extends actor.Extension
- // This will cause all auto-start modules to initiate.
- ModuleSupervisor.get(actorSystem)
+ private case class KamonCoreComponents(
+ metrics: MetricsExtension,
+ tracer: TracerExtension,
+ userMetrics: UserMetricsExtension)
- def shutdown(): Unit =
- actorSystem.shutdown()
-}
+ @volatile private var _system: ActorSystem = _
+ @volatile private var _coreComponents: Option[KamonCoreComponents] = None
-object Kamon {
- trait Extension extends actor.Extension
- def apply[T <: Extension](key: ExtensionId[T])(implicit system: ActorSystem): T = key(system)
+ def start(config: Config): Unit = synchronized {
+ if (_coreComponents.isEmpty) {
+ val metrics = MetricsExtensionImpl(config)
+ val simpleMetrics = UserMetricsExtensionImpl(metrics)
+ val tracer = TracerExtensionImpl(metrics, config)
- def apply(): Kamon =
- apply("kamon")
+ _coreComponents = Some(KamonCoreComponents(metrics, tracer, simpleMetrics))
+ _system = ActorSystem("kamon", config)
- def apply(actorSystemName: String): Kamon =
- apply(ActorSystem(actorSystemName))
+ metrics.start(_system)
+ tracer.start(_system)
- def apply(actorSystemName: String, config: Config): Kamon =
- apply(ActorSystem(actorSystemName, config))
+ } else sys.error("Kamon has already been started.")
+ }
- def apply(system: ActorSystem): Kamon =
- new Kamon(system)
+ def start(): Unit =
+ start(ConfigFactory.load)
- def create(): Kamon =
- apply()
+ def metrics: MetricsExtension =
+ ifStarted(_.metrics)
- def create(actorSystemName: String): Kamon =
- apply(ActorSystem(actorSystemName))
+ def tracer: TracerExtension =
+ ifStarted(_.tracer)
- def create(actorSystemName: String, config: Config): Kamon =
- apply(ActorSystem(actorSystemName, config))
+ def userMetrics: UserMetricsExtension =
+ ifStarted(_.userMetrics)
- def create(system: ActorSystem): Kamon =
- new Kamon(system)
+ def apply[T <: Kamon.Extension](key: ExtensionId[T]): T =
+ ifStarted { _ ⇒
+ if (_system ne null)
+ key(_system)
+ else
+ sys.error("Cannot retrieve extensions while Kamon is being initialized.")
+ }
+
+ def extension[T <: Kamon.Extension](key: ExtensionId[T]): T =
+ apply(key)
+
+ private def ifStarted[T](thunk: KamonCoreComponents ⇒ T): T =
+ _coreComponents.map(thunk(_)) getOrElse (sys.error("Kamon has not been started yet."))
+
+}
-} \ No newline at end of file
diff --git a/kamon-core/src/main/scala/kamon/metric/MetricsExtension.scala b/kamon-core/src/main/scala/kamon/metric/MetricsExtension.scala
index 88352e21..87911352 100644
--- a/kamon-core/src/main/scala/kamon/metric/MetricsExtension.scala
+++ b/kamon-core/src/main/scala/kamon/metric/MetricsExtension.scala
@@ -16,25 +16,17 @@
package kamon.metric
-import akka.actor
+import com.typesafe.config.Config
import kamon.metric.SubscriptionsDispatcher.{ Unsubscribe, Subscribe }
-import kamon.Kamon
-import kamon.metric.instrument.{ InstrumentFactory, CollectionContext }
-import kamon.supervisor.ModuleSupervisor
+import kamon.metric.instrument.{ DefaultRefreshScheduler, InstrumentFactory, CollectionContext }
import scala.collection.concurrent.TrieMap
import akka.actor._
-import kamon.util.{ FastDispatch, TriemapAtomicGetOrElseUpdate }
-
-object Metrics extends ExtensionId[MetricsExtension] with ExtensionIdProvider {
- override def get(system: ActorSystem): MetricsExtension = super.get(system)
- def lookup(): ExtensionId[_ <: actor.Extension] = Metrics
- def createExtension(system: ExtendedActorSystem): MetricsExtension = new MetricsExtensionImpl(system)
-}
+import kamon.util.{ LazyActorRef, TriemapAtomicGetOrElseUpdate }
case class EntityRegistration[T <: EntityRecorder](entity: Entity, recorder: T)
-trait MetricsExtension extends Kamon.Extension {
+trait MetricsExtension {
def settings: MetricsExtensionSettings
def shouldTrack(entity: Entity): Boolean
def shouldTrack(entityName: String, category: String): Boolean =
@@ -63,16 +55,11 @@ trait MetricsExtension extends Kamon.Extension {
def instrumentFactory(category: String): InstrumentFactory
}
-class MetricsExtensionImpl(system: ExtendedActorSystem) extends MetricsExtension {
- import FastDispatch.Syntax
-
- val settings = MetricsExtensionSettings(system)
-
+private[kamon] class MetricsExtensionImpl(config: Config) extends MetricsExtension {
private val _trackedEntities = TrieMap.empty[Entity, EntityRecorder]
- private val _collectionContext = buildDefaultCollectionContext
- private val _metricsCollectionDispatcher = system.dispatchers.lookup(settings.metricCollectionDispatcher)
- private lazy val _subscriptions = ModuleSupervisor.get(system).createModule("subscriptions-dispatcher",
- SubscriptionsDispatcher.props(settings.tickInterval, collectSnapshots).withDispatcher(settings.metricCollectionDispatcher))
+ private val _subscriptions = new LazyActorRef
+
+ val settings = MetricsExtensionSettings(config)
def shouldTrack(entity: Entity): Boolean =
settings.entityFilters.get(entity.category).map {
@@ -110,10 +97,10 @@ class MetricsExtensionImpl(system: ExtendedActorSystem) extends MetricsExtension
find(Entity(name, category))
def subscribe(filter: SubscriptionFilter, subscriber: ActorRef, permanent: Boolean): Unit =
- _subscriptions.fastDispatch(Subscribe(filter, subscriber, permanent))(_metricsCollectionDispatcher)
+ _subscriptions.tell(Subscribe(filter, subscriber, permanent))
def unsubscribe(subscriber: ActorRef): Unit =
- _subscriptions.fastDispatch(Unsubscribe(subscriber))(_metricsCollectionDispatcher)
+ _subscriptions.tell(Unsubscribe(subscriber))
def buildDefaultCollectionContext: CollectionContext =
CollectionContext(settings.defaultCollectionContextBufferSize)
@@ -121,16 +108,34 @@ class MetricsExtensionImpl(system: ExtendedActorSystem) extends MetricsExtension
def instrumentFactory(category: String): InstrumentFactory =
settings.instrumentFactories.getOrElse(category, settings.defaultInstrumentFactory)
- /**
- * Collect and dispatch.
- */
- private def collectSnapshots(): Map[Entity, EntitySnapshot] = {
+ private[kamon] def collectSnapshots(collectionContext: CollectionContext): Map[Entity, EntitySnapshot] = {
val builder = Map.newBuilder[Entity, EntitySnapshot]
_trackedEntities.foreach {
- case (identity, recorder) ⇒ builder += ((identity, recorder.collect(_collectionContext)))
+ case (identity, recorder) ⇒ builder += ((identity, recorder.collect(collectionContext)))
}
builder.result()
}
+
+ /**
+ * Metrics Extension initialization.
+ */
+ private var _system: ActorSystem = null
+ private lazy val _start = {
+ _subscriptions.point(_system.actorOf(SubscriptionsDispatcher.props(settings.tickInterval, this), "metrics"))
+ settings.pointScheduler(DefaultRefreshScheduler(_system.scheduler, _system.dispatcher))
+ }
+
+ def start(system: ActorSystem): Unit = synchronized {
+ _system = system
+ _start
+ _system = null
+ }
+}
+
+private[kamon] object MetricsExtensionImpl {
+
+ def apply(config: Config) =
+ new MetricsExtensionImpl(config)
}
diff --git a/kamon-core/src/main/scala/kamon/metric/MetricsExtensionSettings.scala b/kamon-core/src/main/scala/kamon/metric/MetricsExtensionSettings.scala
index 84624336..9881ed00 100644
--- a/kamon-core/src/main/scala/kamon/metric/MetricsExtensionSettings.scala
+++ b/kamon-core/src/main/scala/kamon/metric/MetricsExtensionSettings.scala
@@ -16,9 +16,8 @@
package kamon.metric
-import akka.actor.ExtendedActorSystem
import com.typesafe.config.Config
-import kamon.metric.instrument.{ RefreshScheduler, InstrumentFactory, DefaultInstrumentSettings, InstrumentCustomSettings }
+import kamon.metric.instrument._
import kamon.util.GlobPathFilter
import scala.concurrent.duration.FiniteDuration
@@ -27,15 +26,19 @@ import scala.concurrent.duration.FiniteDuration
* Configuration settings for the Metrics extension, as read from the `kamon.metric` configuration key.
*/
case class MetricsExtensionSettings(
- tickInterval: FiniteDuration,
- defaultCollectionContextBufferSize: Int,
- trackUnmatchedEntities: Boolean,
- entityFilters: Map[String, EntityFilter],
- instrumentFactories: Map[String, InstrumentFactory],
- defaultInstrumentFactory: InstrumentFactory,
- metricCollectionDispatcher: String,
- refreshSchedulerDispatcher: String,
- refreshScheduler: RefreshScheduler)
+ tickInterval: FiniteDuration,
+ defaultCollectionContextBufferSize: Int,
+ trackUnmatchedEntities: Boolean,
+ entityFilters: Map[String, EntityFilter],
+ instrumentFactories: Map[String, InstrumentFactory],
+ defaultInstrumentFactory: InstrumentFactory,
+ refreshScheduler: RefreshScheduler) {
+
+ private[kamon] def pointScheduler(targetScheduler: RefreshScheduler): Unit = refreshScheduler match {
+ case lrs: LazyRefreshScheduler ⇒ lrs.point(targetScheduler)
+ case others ⇒
+ }
+}
/**
*
@@ -49,23 +52,21 @@ object MetricsExtensionSettings {
import kamon.util.ConfigTools.Syntax
import scala.concurrent.duration._
- def apply(system: ExtendedActorSystem): MetricsExtensionSettings = {
- val metricConfig = system.settings.config.getConfig("kamon.metric")
+ def apply(config: Config): MetricsExtensionSettings = {
+ val metricConfig = config.getConfig("kamon.metric")
val tickInterval = metricConfig.getFiniteDuration("tick-interval")
val collectBufferSize = metricConfig.getInt("default-collection-context-buffer-size")
val trackUnmatchedEntities = metricConfig.getBoolean("track-unmatched-entities")
val entityFilters = loadFilters(metricConfig.getConfig("filters"))
val defaultInstrumentSettings = DefaultInstrumentSettings.fromConfig(metricConfig.getConfig("default-instrument-settings"))
- val metricCollectionDispatcher = metricConfig.getString("dispatchers.metric-collection")
- val refreshSchedulerDispatcher = metricConfig.getString("dispatchers.refresh-scheduler")
- val refreshScheduler = RefreshScheduler(system.scheduler, system.dispatchers.lookup(refreshSchedulerDispatcher))
+ val refreshScheduler = new LazyRefreshScheduler
val instrumentFactories = loadInstrumentFactories(metricConfig.getConfig("instrument-settings"), defaultInstrumentSettings, refreshScheduler)
val defaultInstrumentFactory = new InstrumentFactory(Map.empty, defaultInstrumentSettings, refreshScheduler)
MetricsExtensionSettings(tickInterval, collectBufferSize, trackUnmatchedEntities, entityFilters, instrumentFactories,
- defaultInstrumentFactory, metricCollectionDispatcher, refreshSchedulerDispatcher, refreshScheduler)
+ defaultInstrumentFactory, refreshScheduler)
}
/**
diff --git a/kamon-core/src/main/scala/kamon/metric/SubscriptionsDispatcher.scala b/kamon-core/src/main/scala/kamon/metric/SubscriptionsDispatcher.scala
index f616be35..68b545a5 100644
--- a/kamon-core/src/main/scala/kamon/metric/SubscriptionsDispatcher.scala
+++ b/kamon-core/src/main/scala/kamon/metric/SubscriptionsDispatcher.scala
@@ -24,11 +24,12 @@ import scala.concurrent.duration.FiniteDuration
/**
* Manages subscriptions to metrics and dispatch snapshots on every tick to all subscribers.
*/
-private[kamon] class SubscriptionsDispatcher(interval: FiniteDuration, collector: () ⇒ Map[Entity, EntitySnapshot]) extends Actor {
+private[kamon] class SubscriptionsDispatcher(interval: FiniteDuration, metricsExtension: MetricsExtensionImpl) extends Actor {
var lastTick = MilliTimestamp.now
var oneShotSubscriptions = Map.empty[ActorRef, SubscriptionFilter]
var permanentSubscriptions = Map.empty[ActorRef, SubscriptionFilter]
val tickSchedule = context.system.scheduler.schedule(interval, interval, self, Tick)(context.dispatcher)
+ val collectionContext = metricsExtension.buildDefaultCollectionContext
def receive = {
case Tick ⇒ processTick()
@@ -38,7 +39,7 @@ private[kamon] class SubscriptionsDispatcher(interval: FiniteDuration, collector
}
def processTick(): Unit =
- dispatch(collector())
+ dispatch(metricsExtension.collectSnapshots(collectionContext))
def subscribe(filter: SubscriptionFilter, subscriber: ActorRef, permanent: Boolean): Unit = {
def addSubscription(storage: Map[ActorRef, SubscriptionFilter]): Map[ActorRef, SubscriptionFilter] =
@@ -80,8 +81,8 @@ private[kamon] class SubscriptionsDispatcher(interval: FiniteDuration, collector
}
object SubscriptionsDispatcher {
- def props(interval: FiniteDuration, collector: () ⇒ Map[Entity, EntitySnapshot]): Props =
- Props(new SubscriptionsDispatcher(interval, collector))
+ def props(interval: FiniteDuration, metricsExtension: MetricsExtensionImpl): Props =
+ Props(new SubscriptionsDispatcher(interval, metricsExtension))
case object Tick
case class Unsubscribe(subscriber: ActorRef)
diff --git a/kamon-core/src/main/scala/kamon/metric/TickMetricSnapshotBuffer.scala b/kamon-core/src/main/scala/kamon/metric/TickMetricSnapshotBuffer.scala
index 358dade8..dfc5d5f0 100644
--- a/kamon-core/src/main/scala/kamon/metric/TickMetricSnapshotBuffer.scala
+++ b/kamon-core/src/main/scala/kamon/metric/TickMetricSnapshotBuffer.scala
@@ -29,7 +29,7 @@ class TickMetricSnapshotBuffer(flushInterval: FiniteDuration, receiver: ActorRef
import MapMerge.Syntax
val flushSchedule = context.system.scheduler.schedule(flushInterval, flushInterval, self, FlushBuffer)(context.dispatcher)
- val collectionContext: CollectionContext = Kamon(Metrics)(context.system).buildDefaultCollectionContext
+ val collectionContext: CollectionContext = Kamon.metrics.buildDefaultCollectionContext
def receive = empty
diff --git a/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala b/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala
index e6ec5e99..e0818292 100644
--- a/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala
+++ b/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala
@@ -16,30 +16,13 @@
package kamon.metric
-import akka.actor
-import akka.actor.{ ActorSystem, ExtendedActorSystem, ExtensionIdProvider, ExtensionId }
-import kamon.Kamon
import kamon.metric.instrument.Gauge.CurrentValueCollector
import kamon.metric.instrument.Histogram.DynamicRange
import kamon.metric.instrument._
import scala.concurrent.duration.FiniteDuration
-object UserMetrics extends ExtensionId[UserMetricsExtension] with ExtensionIdProvider {
- override def get(system: ActorSystem): UserMetricsExtension = super.get(system)
- def lookup(): ExtensionId[_ <: actor.Extension] = UserMetrics
- def createExtension(system: ExtendedActorSystem): UserMetricsExtension = {
- val metricsExtension = Metrics.get(system)
- val instrumentFactory = metricsExtension.instrumentFactory(entity.category)
- val userMetricsExtension = new UserMetricsExtensionImpl(instrumentFactory)
-
- metricsExtension.register(entity, userMetricsExtension).recorder
- }
-
- val entity = Entity("user-metric", "user-metric")
-}
-
-trait UserMetricsExtension extends Kamon.Extension {
+trait UserMetricsExtension {
def histogram(name: String): Histogram
def histogram(name: String, dynamicRange: DynamicRange): Histogram
def histogram(name: String, unitOfMeasurement: UnitOfMeasurement): Histogram
@@ -86,7 +69,7 @@ trait UserMetricsExtension extends Kamon.Extension {
}
-class UserMetricsExtensionImpl(instrumentFactory: InstrumentFactory) extends GenericEntityRecorder(instrumentFactory) with UserMetricsExtension {
+private[kamon] class UserMetricsExtensionImpl(instrumentFactory: InstrumentFactory) extends GenericEntityRecorder(instrumentFactory) with UserMetricsExtension {
override def histogram(name: String): Histogram =
super.histogram(name)
@@ -206,4 +189,16 @@ class UserMetricsExtensionImpl(instrumentFactory: InstrumentFactory) extends Gen
override def removeCounter(key: CounterKey): Unit =
super.removeCounter(key)
+}
+
+private[kamon] object UserMetricsExtensionImpl {
+ val UserMetricEntity = Entity("user-metric", "user-metric")
+
+ def apply(metricsExtension: MetricsExtension): UserMetricsExtensionImpl = {
+ val instrumentFactory = metricsExtension.instrumentFactory(UserMetricEntity.category)
+ val userMetricsExtension = new UserMetricsExtensionImpl(instrumentFactory)
+
+ metricsExtension.register(UserMetricEntity, userMetricsExtension).recorder
+ }
+
} \ No newline at end of file
diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/Instrument.scala b/kamon-core/src/main/scala/kamon/metric/instrument/Instrument.scala
index 68d5c876..59b4b443 100644
--- a/kamon-core/src/main/scala/kamon/metric/instrument/Instrument.scala
+++ b/kamon-core/src/main/scala/kamon/metric/instrument/Instrument.scala
@@ -51,22 +51,3 @@ object CollectionContext {
}
}
-trait RefreshScheduler {
- def schedule(interval: FiniteDuration, refresh: () ⇒ Unit): Cancellable
-}
-
-object RefreshScheduler {
- val NoopScheduler = new RefreshScheduler {
- def schedule(interval: FiniteDuration, refresh: () ⇒ Unit): Cancellable = new Cancellable {
- override def isCancelled: Boolean = true
- override def cancel(): Boolean = true
- }
- }
-
- def apply(scheduler: Scheduler, dispatcher: MessageDispatcher): RefreshScheduler = new RefreshScheduler {
- def schedule(interval: FiniteDuration, refresh: () ⇒ Unit): Cancellable =
- scheduler.schedule(interval, interval)(refresh.apply())(dispatcher)
- }
-
- def create(scheduler: Scheduler, dispatcher: MessageDispatcher): RefreshScheduler = apply(scheduler, dispatcher)
-} \ No newline at end of file
diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/RefreshScheduler.scala b/kamon-core/src/main/scala/kamon/metric/instrument/RefreshScheduler.scala
new file mode 100644
index 00000000..adb08713
--- /dev/null
+++ b/kamon-core/src/main/scala/kamon/metric/instrument/RefreshScheduler.scala
@@ -0,0 +1,99 @@
+package kamon.metric.instrument
+
+import akka.actor.{ Scheduler, Cancellable }
+import org.HdrHistogram.WriterReaderPhaser
+
+import scala.collection.concurrent.TrieMap
+import scala.concurrent.ExecutionContext
+import scala.concurrent.duration.FiniteDuration
+
+trait RefreshScheduler {
+ def schedule(interval: FiniteDuration, refresh: () ⇒ Unit): Cancellable
+}
+
+/**
+ * Default implementation of RefreshScheduler that simply uses an [[akka.actor.Scheduler]] to schedule tasks to be run
+ * in the provided ExecutionContext.
+ */
+class DefaultRefreshScheduler(scheduler: Scheduler, dispatcher: ExecutionContext) extends RefreshScheduler {
+ def schedule(interval: FiniteDuration, refresh: () ⇒ Unit): Cancellable =
+ scheduler.schedule(interval, interval)(refresh.apply())(dispatcher)
+}
+
+object DefaultRefreshScheduler {
+ def apply(scheduler: Scheduler, dispatcher: ExecutionContext): RefreshScheduler =
+ new DefaultRefreshScheduler(scheduler, dispatcher)
+
+ def create(scheduler: Scheduler, dispatcher: ExecutionContext): RefreshScheduler =
+ apply(scheduler, dispatcher)
+}
+
+/**
+ * RefreshScheduler implementation that accumulates all the scheduled actions until it is pointed to another refresh
+ * scheduler. Once it is pointed, all subsequent calls to `schedule` will immediately be scheduled in the pointed
+ * scheduler.
+ */
+class LazyRefreshScheduler extends RefreshScheduler {
+ private val _schedulerPhaser = new WriterReaderPhaser
+ private val _backlog = new TrieMap[(FiniteDuration, () ⇒ Unit), RepointableCancellable]()
+ @volatile private var _target: Option[RefreshScheduler] = None
+
+ def schedule(interval: FiniteDuration, refresh: () ⇒ Unit): Cancellable = {
+ val criticalEnter = _schedulerPhaser.writerCriticalSectionEnter()
+ try {
+ _target.map { scheduler ⇒
+ scheduler.schedule(interval, refresh)
+
+ } getOrElse {
+ val entry = (interval, refresh)
+ val cancellable = new RepointableCancellable(entry)
+
+ _backlog.put(entry, cancellable)
+ cancellable
+ }
+
+ } finally {
+ _schedulerPhaser.writerCriticalSectionExit(criticalEnter)
+ }
+ }
+
+ def point(target: RefreshScheduler): Unit = try {
+ _schedulerPhaser.readerLock()
+
+ if (_target.isEmpty) {
+ _target = Some(target)
+ _schedulerPhaser.flipPhase(10000L)
+ _backlog.dropWhile {
+ case ((interval, refresh), repointableCancellable) ⇒
+ repointableCancellable.point(target.schedule(interval, refresh))
+ true
+ }
+ } else sys.error("A LazyRefreshScheduler cannot be pointed more than once.")
+ } finally { _schedulerPhaser.readerUnlock() }
+
+ class RepointableCancellable(entry: (FiniteDuration, () ⇒ Unit)) extends Cancellable {
+ private var _isCancelled = false
+ private var _cancellable: Option[Cancellable] = None
+
+ def isCancelled: Boolean = synchronized {
+ _cancellable.map(_.isCancelled).getOrElse(_isCancelled)
+ }
+
+ def cancel(): Boolean = synchronized {
+ _isCancelled = true
+ _cancellable.map(_.cancel()).getOrElse(_backlog.remove(entry).nonEmpty)
+ }
+
+ def point(cancellable: Cancellable): Unit = synchronized {
+ if (_cancellable.isEmpty) {
+ _cancellable = Some(cancellable)
+
+ if (_isCancelled)
+ cancellable.cancel()
+
+ } else sys.error("A RepointableCancellable cannot be pointed more than once.")
+
+ }
+ }
+}
+
diff --git a/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala b/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala
index e62178dd..5f7fdff5 100644
--- a/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala
+++ b/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala
@@ -18,16 +18,14 @@ package kamon.trace
import java.util.concurrent.ConcurrentLinkedQueue
-import akka.actor.{ ExtensionId, ActorSystem }
import akka.event.LoggingAdapter
-import kamon.Kamon.Extension
import kamon.metric.{ MetricsExtension, TraceMetrics }
import kamon.util.{ NanoInterval, RelativeNanoTimestamp }
import scala.annotation.tailrec
private[kamon] class MetricsOnlyContext(traceName: String, val token: String, izOpen: Boolean, val levelOfDetail: LevelOfDetail,
- val startTimestamp: RelativeNanoTimestamp, log: LoggingAdapter, metricsExtension: MetricsExtension, val actorSystem: ActorSystem)
+ val startTimestamp: RelativeNanoTimestamp, log: LoggingAdapter, metricsExtension: MetricsExtension)
extends TraceContext {
@volatile private var _name = traceName
@@ -48,8 +46,6 @@ private[kamon] class MetricsOnlyContext(traceName: String, val token: String, iz
def isOpen: Boolean = _isOpen
def addMetadata(key: String, value: String): Unit = {}
- def lookupExtension[T <: Extension](id: ExtensionId[T]): T = id(actorSystem)
-
def finish(): Unit = {
_isOpen = false
val traceElapsedTime = NanoInterval.since(startTimestamp)
diff --git a/kamon-core/src/main/scala/kamon/trace/TraceContext.scala b/kamon-core/src/main/scala/kamon/trace/TraceContext.scala
index ed8170a9..48e56153 100644
--- a/kamon-core/src/main/scala/kamon/trace/TraceContext.scala
+++ b/kamon-core/src/main/scala/kamon/trace/TraceContext.scala
@@ -17,12 +17,8 @@
package kamon.trace
import java.io.ObjectStreamException
-import akka.actor.{ ExtensionId, ActorSystem }
-import kamon.Kamon.Extension
-import kamon._
-import kamon.metric._
import kamon.trace.TraceContextAware.DefaultTraceContextAware
-import kamon.util.{ NanoInterval, RelativeNanoTimestamp }
+import kamon.util.RelativeNanoTimestamp
trait TraceContext {
def name: String
@@ -39,8 +35,6 @@ trait TraceContext {
def addMetadata(key: String, value: String)
def startTimestamp: RelativeNanoTimestamp
-
- def lookupExtension[T <: Kamon.Extension](id: ExtensionId[T]): T
}
object TraceContext {
@@ -99,9 +93,6 @@ case object EmptyTraceContext extends TraceContext {
def addMetadata(key: String, value: String): Unit = {}
def startTimestamp = new RelativeNanoTimestamp(0L)
- override def lookupExtension[T <: Extension](id: ExtensionId[T]): T =
- sys.error("Can't lookup extensions on a EmptyTraceContext.")
-
case object EmptySegment extends Segment {
val name: String = "empty-segment"
val category: String = "empty-category"
diff --git a/kamon-core/src/main/scala/kamon/trace/TracerExtension.scala b/kamon-core/src/main/scala/kamon/trace/TracerExtension.scala
index 41dcd6bc..be565154 100644
--- a/kamon-core/src/main/scala/kamon/trace/TracerExtension.scala
+++ b/kamon-core/src/main/scala/kamon/trace/TracerExtension.scala
@@ -20,20 +20,13 @@ import java.net.InetAddress
import java.util.concurrent.atomic.AtomicLong
import akka.actor._
-import akka.actor
-import kamon.Kamon
-import kamon.metric.{ Metrics, MetricsExtension }
-import kamon.util.{ NanoInterval, RelativeNanoTimestamp, NanoTimestamp, GlobPathFilter }
+import com.typesafe.config.Config
+import kamon.metric.MetricsExtension
+import kamon.util._
import scala.util.Try
-object Tracer extends ExtensionId[TracerExtension] with ExtensionIdProvider {
- override def get(system: ActorSystem): TracerExtension = super.get(system)
- def lookup(): ExtensionId[_ <: actor.Extension] = Tracer
- def createExtension(system: ExtendedActorSystem): TracerExtension = new TracerExtensionImpl(system)
-}
-
-trait TracerExtension extends Kamon.Extension {
+trait TracerExtension {
def newContext(name: String): TraceContext
def newContext(name: String, token: String): TraceContext
def newContext(name: String, token: String, timestamp: RelativeNanoTimestamp, isOpen: Boolean, isLocal: Boolean): TraceContext
@@ -42,14 +35,13 @@ trait TracerExtension extends Kamon.Extension {
def unsubscribe(subscriber: ActorRef): Unit
}
-class TracerExtensionImpl(system: ExtendedActorSystem) extends TracerExtension {
- private val _settings = TraceSettings(system)
- private val _metricsExtension = Metrics.get(system)
-
+private[kamon] class TracerExtensionImpl(metricsExtension: MetricsExtension, config: Config) extends TracerExtension {
+ private val _settings = TraceSettings(config)
private val _hostnamePrefix = Try(InetAddress.getLocalHost.getHostName).getOrElse("unknown-localhost")
private val _tokenCounter = new AtomicLong
- private val _subscriptions = system.actorOf(Props[TraceSubscriptions], "trace-subscriptions")
- private val _incubator = system.actorOf(Incubator.props(_subscriptions))
+
+ private val _subscriptions = new LazyActorRef
+ private val _incubator = new LazyActorRef
private def newToken: String =
_hostnamePrefix + "-" + String.valueOf(_tokenCounter.incrementAndGet())
@@ -66,7 +58,7 @@ class TracerExtensionImpl(system: ExtendedActorSystem) extends TracerExtension {
private def createTraceContext(traceName: String, token: String = newToken, startTimestamp: RelativeNanoTimestamp = RelativeNanoTimestamp.now,
isOpen: Boolean = true, isLocal: Boolean = true): TraceContext = {
- def newMetricsOnlyContext = new MetricsOnlyContext(traceName, token, isOpen, _settings.levelOfDetail, startTimestamp, null, _metricsExtension, system)
+ def newMetricsOnlyContext = new MetricsOnlyContext(traceName, token, isOpen, _settings.levelOfDetail, startTimestamp, null, metricsExtension)
if (_settings.levelOfDetail == LevelOfDetail.MetricsOnly || !isLocal)
newMetricsOnlyContext
@@ -74,20 +66,44 @@ class TracerExtensionImpl(system: ExtendedActorSystem) extends TracerExtension {
if (!_settings.sampler.shouldTrace)
newMetricsOnlyContext
else
- new TracingContext(traceName, token, true, _settings.levelOfDetail, isLocal, startTimestamp, null, _metricsExtension, this, system, dispatchTracingContext)
+ new TracingContext(traceName, token, true, _settings.levelOfDetail, isLocal, startTimestamp, null, metricsExtension, this, dispatchTracingContext)
}
}
- def subscribe(subscriber: ActorRef): Unit = _subscriptions ! TraceSubscriptions.Subscribe(subscriber)
- def unsubscribe(subscriber: ActorRef): Unit = _subscriptions ! TraceSubscriptions.Unsubscribe(subscriber)
+ def subscribe(subscriber: ActorRef): Unit =
+ _subscriptions.tell(TraceSubscriptions.Subscribe(subscriber))
+
+ def unsubscribe(subscriber: ActorRef): Unit =
+ _subscriptions.tell(TraceSubscriptions.Unsubscribe(subscriber))
private[kamon] def dispatchTracingContext(trace: TracingContext): Unit =
if (_settings.sampler.shouldReport(trace.elapsedTime))
if (trace.shouldIncubate)
- _incubator ! trace
+ _incubator.tell(trace)
else
- _subscriptions ! trace.generateTraceInfo
+ _subscriptions.tell(trace.generateTraceInfo)
+
+ /**
+ * Tracer Extension initialization.
+ */
+ private var _system: ActorSystem = null
+ private lazy val _start = {
+ val subscriptions = _system.actorOf(Props[TraceSubscriptions], "trace-subscriptions")
+ _subscriptions.point(subscriptions)
+ _incubator.point(_system.actorOf(Incubator.props(subscriptions)))
+ }
+
+ def start(system: ActorSystem): Unit = synchronized {
+ _system = system
+ _start
+ _system = null
+ }
+}
+
+private[kamon] object TracerExtensionImpl {
+ def apply(metricsExtension: MetricsExtension, config: Config) =
+ new TracerExtensionImpl(metricsExtension, config)
}
case class TraceInfo(name: String, token: String, timestamp: NanoTimestamp, elapsedTime: NanoInterval, metadata: Map[String, String], segments: List[SegmentInfo])
diff --git a/kamon-core/src/main/scala/kamon/trace/TracerExtensionSettings.scala b/kamon-core/src/main/scala/kamon/trace/TracerExtensionSettings.scala
index d360330d..7510ab7f 100644
--- a/kamon-core/src/main/scala/kamon/trace/TracerExtensionSettings.scala
+++ b/kamon-core/src/main/scala/kamon/trace/TracerExtensionSettings.scala
@@ -18,13 +18,13 @@ package kamon.trace
import java.util.concurrent.TimeUnit
-import akka.actor.ActorSystem
+import com.typesafe.config.Config
case class TraceSettings(levelOfDetail: LevelOfDetail, sampler: Sampler)
object TraceSettings {
- def apply(system: ActorSystem): TraceSettings = {
- val tracerConfig = system.settings.config.getConfig("kamon.trace")
+ def apply(config: Config): TraceSettings = {
+ val tracerConfig = config.getConfig("kamon.trace")
val detailLevel: LevelOfDetail = tracerConfig.getString("level-of-detail") match {
case "metrics-only" ⇒ LevelOfDetail.MetricsOnly
diff --git a/kamon-core/src/main/scala/kamon/trace/TracingContext.scala b/kamon-core/src/main/scala/kamon/trace/TracingContext.scala
index dd4c3c1a..3d324886 100644
--- a/kamon-core/src/main/scala/kamon/trace/TracingContext.scala
+++ b/kamon-core/src/main/scala/kamon/trace/TracingContext.scala
@@ -19,7 +19,6 @@ package kamon.trace
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.atomic.AtomicInteger
-import akka.actor.ActorSystem
import akka.event.LoggingAdapter
import kamon.util.{ NanoInterval, RelativeNanoTimestamp, NanoTimestamp }
import kamon.metric.MetricsExtension
@@ -28,8 +27,8 @@ import scala.collection.concurrent.TrieMap
private[trace] class TracingContext(traceName: String, token: String, izOpen: Boolean, levelOfDetail: LevelOfDetail,
isLocal: Boolean, startTimeztamp: RelativeNanoTimestamp, log: LoggingAdapter, metricsExtension: MetricsExtension,
- traceExtension: TracerExtensionImpl, system: ActorSystem, traceInfoSink: TracingContext ⇒ Unit)
- extends MetricsOnlyContext(traceName, token, izOpen, levelOfDetail, startTimeztamp, log, metricsExtension, system) {
+ traceExtension: TracerExtensionImpl, traceInfoSink: TracingContext ⇒ Unit)
+ extends MetricsOnlyContext(traceName, token, izOpen, levelOfDetail, startTimeztamp, log, metricsExtension) {
private val _openSegments = new AtomicInteger(0)
private val _startTimestamp = NanoTimestamp.now
diff --git a/kamon-core/src/main/scala/kamon/util/LazyActorRef.scala b/kamon-core/src/main/scala/kamon/util/LazyActorRef.scala
new file mode 100644
index 00000000..855bf1fc
--- /dev/null
+++ b/kamon-core/src/main/scala/kamon/util/LazyActorRef.scala
@@ -0,0 +1,53 @@
+package kamon.util
+
+import java.util
+import java.util.concurrent.ConcurrentLinkedQueue
+
+import akka.actor.{ Actor, ActorRef }
+import org.HdrHistogram.WriterReaderPhaser
+
+import scala.annotation.tailrec
+
+/**
+ * A LazyActorRef accumulates messages sent to an actor that doesn't exist yet. Once the actor is created and
+ * the LazyActorRef is pointed to it, all the accumulated messages are flushed and any new message sent to the
+ * LazyActorRef will immediately be sent to the pointed ActorRef.
+ *
+ * This is intended to be used during Kamon's initialization where some components need to use ActorRefs to work
+ * (like subscriptions and the trace incubator) but our internal ActorSystem is not yet ready to create the
+ * required actors.
+ */
+class LazyActorRef {
+ private val _refPhaser = new WriterReaderPhaser
+ private val _backlog = new ConcurrentLinkedQueue[(Any, ActorRef)]()
+ @volatile private var _target: Option[ActorRef] = None
+
+ def tell(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = {
+ val criticalEnter = _refPhaser.writerCriticalSectionEnter()
+ try {
+ _target.map(_.tell(message, sender)) getOrElse {
+ _backlog.add((message, sender))
+ }
+
+ } finally { _refPhaser.writerCriticalSectionExit(criticalEnter) }
+ }
+
+ def point(target: ActorRef): Unit = {
+ @tailrec def drain(q: util.Queue[(Any, ActorRef)]): Unit = if (!q.isEmpty) {
+ val (msg, sender) = q.poll()
+ target.tell(msg, sender)
+ drain(q)
+ }
+
+ try {
+ _refPhaser.readerLock()
+
+ if (_target.isEmpty) {
+ _target = Some(target)
+ _refPhaser.flipPhase(1000L)
+ drain(_backlog)
+
+ } else sys.error("A LazyActorRef cannot be pointed more than once.")
+ } finally { _refPhaser.readerUnlock() }
+ }
+}
diff --git a/kamon-core/src/test/scala/kamon/metric/SubscriptionsProtocolSpec.scala b/kamon-core/src/test/scala/kamon/metric/SubscriptionsProtocolSpec.scala
index 7dbcafd7..53ae5273 100644
--- a/kamon-core/src/test/scala/kamon/metric/SubscriptionsProtocolSpec.scala
+++ b/kamon-core/src/test/scala/kamon/metric/SubscriptionsProtocolSpec.scala
@@ -19,6 +19,7 @@ package kamon.metric
import akka.actor._
import akka.testkit.{ TestProbe, ImplicitSender }
import com.typesafe.config.ConfigFactory
+import kamon.Kamon
import kamon.metric.SubscriptionsDispatcher.TickMetricSnapshot
import kamon.testkit.BaseKamonSpec
import scala.concurrent.duration._
@@ -32,7 +33,7 @@ class SubscriptionsProtocolSpec extends BaseKamonSpec("subscriptions-protocol-sp
|}
""".stripMargin)
- val metricsModule = kamon.metrics
+ lazy val metricsModule = Kamon.metrics
import metricsModule.{ register, subscribe, unsubscribe }
"the Subscriptions messaging protocol" should {
diff --git a/kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala b/kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala
index 2e1f246d..0c9ced32 100644
--- a/kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala
+++ b/kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala
@@ -17,6 +17,7 @@
package kamon.metric
import com.typesafe.config.ConfigFactory
+import kamon.Kamon
import kamon.metric.instrument.Histogram.MutableRecord
import kamon.testkit.BaseKamonSpec
import kamon.util.MilliTimestamp
@@ -85,9 +86,9 @@ class TickMetricSnapshotBufferSpec extends BaseKamonSpec("trace-metrics-spec") w
}
trait SnapshotFixtures {
- val collectionContext = kamon.metrics.buildDefaultCollectionContext
+ val collectionContext = Kamon.metrics.buildDefaultCollectionContext
val testTraceIdentity = Entity("buffer-spec-test-trace", "trace")
- val traceRecorder = kamon.metrics.register(TraceMetrics, "buffer-spec-test-trace").get.recorder
+ val traceRecorder = Kamon.metrics.register(TraceMetrics, "buffer-spec-test-trace").get.recorder
val firstEmpty = TickMetricSnapshot(new MilliTimestamp(1000), new MilliTimestamp(2000), Map.empty)
val secondEmpty = TickMetricSnapshot(new MilliTimestamp(2000), new MilliTimestamp(3000), Map.empty)
diff --git a/kamon-core/src/test/scala/kamon/metric/UserMetricsSpec.scala b/kamon-core/src/test/scala/kamon/metric/UserMetricsSpec.scala
index 7b6cbebc..455518f8 100644
--- a/kamon-core/src/test/scala/kamon/metric/UserMetricsSpec.scala
+++ b/kamon-core/src/test/scala/kamon/metric/UserMetricsSpec.scala
@@ -17,6 +17,7 @@
package kamon.metric
import com.typesafe.config.ConfigFactory
+import kamon.Kamon
import kamon.metric.instrument.Histogram.DynamicRange
import kamon.testkit.BaseKamonSpec
import scala.concurrent.duration._
@@ -34,54 +35,54 @@ class UserMetricsSpec extends BaseKamonSpec("user-metrics-spec") {
"the UserMetrics extension" should {
"allow registering a fully configured Histogram and get the same Histogram if registering again" in {
- val histogramA = kamon.userMetrics.histogram("histogram-with-settings", DynamicRange(1, 10000, 2))
- val histogramB = kamon.userMetrics.histogram("histogram-with-settings", DynamicRange(1, 10000, 2))
+ val histogramA = Kamon.userMetrics.histogram("histogram-with-settings", DynamicRange(1, 10000, 2))
+ val histogramB = Kamon.userMetrics.histogram("histogram-with-settings", DynamicRange(1, 10000, 2))
histogramA shouldBe theSameInstanceAs(histogramB)
}
"return the original Histogram when registering a fully configured Histogram for second time but with different settings" in {
- val histogramA = kamon.userMetrics.histogram("histogram-with-settings", DynamicRange(1, 10000, 2))
- val histogramB = kamon.userMetrics.histogram("histogram-with-settings", DynamicRange(1, 50000, 2))
+ val histogramA = Kamon.userMetrics.histogram("histogram-with-settings", DynamicRange(1, 10000, 2))
+ val histogramB = Kamon.userMetrics.histogram("histogram-with-settings", DynamicRange(1, 50000, 2))
histogramA shouldBe theSameInstanceAs(histogramB)
}
"allow registering a Histogram that takes the default configuration from the kamon.metrics.precision settings" in {
- kamon.userMetrics.histogram("histogram-with-default-configuration")
+ Kamon.userMetrics.histogram("histogram-with-default-configuration")
}
"allow registering a Counter and get the same Counter if registering again" in {
- val counterA = kamon.userMetrics.counter("counter")
- val counterB = kamon.userMetrics.counter("counter")
+ val counterA = Kamon.userMetrics.counter("counter")
+ val counterB = Kamon.userMetrics.counter("counter")
counterA shouldBe theSameInstanceAs(counterB)
}
"allow registering a fully configured MinMaxCounter and get the same MinMaxCounter if registering again" in {
- val minMaxCounterA = kamon.userMetrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 10000, 2), 1 second)
- val minMaxCounterB = kamon.userMetrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 10000, 2), 1 second)
+ val minMaxCounterA = Kamon.userMetrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 10000, 2), 1 second)
+ val minMaxCounterB = Kamon.userMetrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 10000, 2), 1 second)
minMaxCounterA shouldBe theSameInstanceAs(minMaxCounterB)
}
"return the original MinMaxCounter when registering a fully configured MinMaxCounter for second time but with different settings" in {
- val minMaxCounterA = kamon.userMetrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 10000, 2), 1 second)
- val minMaxCounterB = kamon.userMetrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 50000, 2), 1 second)
+ val minMaxCounterA = Kamon.userMetrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 10000, 2), 1 second)
+ val minMaxCounterB = Kamon.userMetrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 50000, 2), 1 second)
minMaxCounterA shouldBe theSameInstanceAs(minMaxCounterB)
}
"allow registering a MinMaxCounter that takes the default configuration from the kamon.metrics.precision settings" in {
- kamon.userMetrics.minMaxCounter("min-max-counter-with-default-configuration")
+ Kamon.userMetrics.minMaxCounter("min-max-counter-with-default-configuration")
}
"allow registering a fully configured Gauge and get the same Gauge if registering again" in {
- val gaugeA = kamon.userMetrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second, {
+ val gaugeA = Kamon.userMetrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second, {
() ⇒ 1L
})
- val gaugeB = kamon.userMetrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second, {
+ val gaugeB = Kamon.userMetrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second, {
() ⇒ 1L
})
@@ -89,11 +90,11 @@ class UserMetricsSpec extends BaseKamonSpec("user-metrics-spec") {
}
"return the original Gauge when registering a fully configured Gauge for second time but with different settings" in {
- val gaugeA = kamon.userMetrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second, {
+ val gaugeA = Kamon.userMetrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second, {
() ⇒ 1L
})
- val gaugeB = kamon.userMetrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second, {
+ val gaugeB = Kamon.userMetrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second, {
() ⇒ 1L
})
@@ -101,26 +102,26 @@ class UserMetricsSpec extends BaseKamonSpec("user-metrics-spec") {
}
"allow registering a Gauge that takes the default configuration from the kamon.metrics.precision settings" in {
- kamon.userMetrics.gauge("gauge-with-default-configuration", {
+ Kamon.userMetrics.gauge("gauge-with-default-configuration", {
() ⇒ 2L
})
}
"allow un-registering user metrics" in {
- val counter = kamon.userMetrics.counter("counter-for-remove")
- val histogram = kamon.userMetrics.histogram("histogram-for-remove")
- val minMaxCounter = kamon.userMetrics.minMaxCounter("min-max-counter-for-remove")
- val gauge = kamon.userMetrics.gauge("gauge-for-remove", { () ⇒ 2L })
-
- kamon.userMetrics.removeCounter("counter-for-remove")
- kamon.userMetrics.removeHistogram("histogram-for-remove")
- kamon.userMetrics.removeMinMaxCounter("min-max-counter-for-remove")
- kamon.userMetrics.removeGauge("gauge-for-remove")
-
- counter should not be (theSameInstanceAs(kamon.userMetrics.counter("counter-for-remove")))
- histogram should not be (theSameInstanceAs(kamon.userMetrics.histogram("histogram-for-remove")))
- minMaxCounter should not be (theSameInstanceAs(kamon.userMetrics.minMaxCounter("min-max-counter-for-remove")))
- gauge should not be (theSameInstanceAs(kamon.userMetrics.gauge("gauge-for-remove", { () ⇒ 2L })))
+ val counter = Kamon.userMetrics.counter("counter-for-remove")
+ val histogram = Kamon.userMetrics.histogram("histogram-for-remove")
+ val minMaxCounter = Kamon.userMetrics.minMaxCounter("min-max-counter-for-remove")
+ val gauge = Kamon.userMetrics.gauge("gauge-for-remove", { () ⇒ 2L })
+
+ Kamon.userMetrics.removeCounter("counter-for-remove")
+ Kamon.userMetrics.removeHistogram("histogram-for-remove")
+ Kamon.userMetrics.removeMinMaxCounter("min-max-counter-for-remove")
+ Kamon.userMetrics.removeGauge("gauge-for-remove")
+
+ counter should not be (theSameInstanceAs(Kamon.userMetrics.counter("counter-for-remove")))
+ histogram should not be (theSameInstanceAs(Kamon.userMetrics.histogram("histogram-for-remove")))
+ minMaxCounter should not be (theSameInstanceAs(Kamon.userMetrics.minMaxCounter("min-max-counter-for-remove")))
+ gauge should not be (theSameInstanceAs(Kamon.userMetrics.gauge("gauge-for-remove", { () ⇒ 2L })))
}
}
}
diff --git a/kamon-core/src/test/scala/kamon/metric/instrument/GaugeSpec.scala b/kamon-core/src/test/scala/kamon/metric/instrument/GaugeSpec.scala
index bb494d0b..ec07d66c 100644
--- a/kamon-core/src/test/scala/kamon/metric/instrument/GaugeSpec.scala
+++ b/kamon-core/src/test/scala/kamon/metric/instrument/GaugeSpec.scala
@@ -17,6 +17,7 @@
package kamon.metric.instrument
import java.util.concurrent.atomic.AtomicLong
+import kamon.Kamon
import kamon.metric.instrument.Histogram.DynamicRange
import kamon.testkit.BaseKamonSpec
import scala.concurrent.duration._
@@ -48,7 +49,7 @@ class GaugeSpec extends BaseKamonSpec("gauge-spec") {
Thread.sleep(1.second.toMillis)
gauge.cleanup
- val snapshot = gauge.collect(kamon.metrics.buildDefaultCollectionContext)
+ val snapshot = gauge.collect(Kamon.metrics.buildDefaultCollectionContext)
snapshot.numberOfMeasurements should be(10L +- 1L)
snapshot.min should be(1)
@@ -58,7 +59,7 @@ class GaugeSpec extends BaseKamonSpec("gauge-spec") {
"not record the current value when doing a collection" in new GaugeFixture {
val (numberOfValuesRecorded, gauge) = createGauge(10 seconds)
- val snapshot = gauge.collect(kamon.metrics.buildDefaultCollectionContext)
+ val snapshot = gauge.collect(Kamon.metrics.buildDefaultCollectionContext)
snapshot.numberOfMeasurements should be(0)
numberOfValuesRecorded.get() should be(0)
}
@@ -67,7 +68,7 @@ class GaugeSpec extends BaseKamonSpec("gauge-spec") {
trait GaugeFixture {
def createGauge(refreshInterval: FiniteDuration = 100 millis): (AtomicLong, Gauge) = {
val recordedValuesCounter = new AtomicLong(0)
- val gauge = Gauge(DynamicRange(1, 100, 2), refreshInterval, kamon.metrics.settings.refreshScheduler, {
+ val gauge = Gauge(DynamicRange(1, 100, 2), refreshInterval, Kamon.metrics.settings.refreshScheduler, {
() ⇒ recordedValuesCounter.addAndGet(1)
})
diff --git a/kamon-core/src/test/scala/kamon/metric/instrument/MinMaxCounterSpec.scala b/kamon-core/src/test/scala/kamon/metric/instrument/MinMaxCounterSpec.scala
index 7a3d7aa3..7acfc229 100644
--- a/kamon-core/src/test/scala/kamon/metric/instrument/MinMaxCounterSpec.scala
+++ b/kamon-core/src/test/scala/kamon/metric/instrument/MinMaxCounterSpec.scala
@@ -19,6 +19,7 @@ import java.nio.LongBuffer
import akka.actor._
import akka.testkit.TestProbe
+import kamon.Kamon
import kamon.metric.instrument.Histogram.{ DynamicRange, MutableRecord }
import kamon.testkit.BaseKamonSpec
import scala.concurrent.duration._
@@ -109,7 +110,7 @@ class MinMaxCounterSpec extends BaseKamonSpec("min-max-counter-spec") {
val buffer: LongBuffer = LongBuffer.allocate(64)
}
- val mmCounter = MinMaxCounter(DynamicRange(1, 1000, 2), 1 hour, kamon.metrics.settings.refreshScheduler)
+ val mmCounter = MinMaxCounter(DynamicRange(1, 1000, 2), 1 hour, Kamon.metrics.settings.refreshScheduler)
mmCounter.cleanup // cancel the refresh schedule
def collectCounterSnapshot(): Histogram.Snapshot = mmCounter.collect(collectionContext)
diff --git a/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala b/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala
index 9142ff16..eab6b754 100644
--- a/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala
+++ b/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala
@@ -22,29 +22,39 @@ import com.typesafe.config.{ Config, ConfigFactory }
import kamon.Kamon
import kamon.metric.{ SubscriptionsDispatcher, EntitySnapshot, MetricsExtensionImpl }
import kamon.trace.TraceContext
+import kamon.util.LazyActorRef
import org.scalatest.{ BeforeAndAfterAll, Matchers, WordSpecLike }
+import scala.reflect.ClassTag
+
abstract class BaseKamonSpec(actorSystemName: String) extends TestKitBase with WordSpecLike with Matchers with ImplicitSender with BeforeAndAfterAll {
- lazy val kamon = Kamon(actorSystemName, config)
- lazy val collectionContext = kamon.metrics.buildDefaultCollectionContext
- implicit lazy val system: ActorSystem = kamon.actorSystem
+ lazy val collectionContext = Kamon.metrics.buildDefaultCollectionContext
+ implicit lazy val system: ActorSystem = {
+ Kamon.start(config.withFallback(ConfigFactory.load()))
+ ActorSystem(actorSystemName, config)
+ }
def config: Config =
- ConfigFactory.load()
+ ConfigFactory.empty()
def newContext(name: String): TraceContext =
- kamon.tracer.newContext(name)
+ Kamon.tracer.newContext(name)
def newContext(name: String, token: String): TraceContext =
- kamon.tracer.newContext(name, token)
+ Kamon.tracer.newContext(name, token)
def takeSnapshotOf(name: String, category: String): EntitySnapshot = {
- val recorder = kamon.metrics.find(name, category).get
+ val recorder = Kamon.metrics.find(name, category).get
recorder.collect(collectionContext)
}
- def flushSubscriptions(): Unit =
- system.actorSelection("/user/kamon/subscriptions-dispatcher") ! SubscriptionsDispatcher.Tick
+ def flushSubscriptions(): Unit = {
+ val subscriptionsField = Kamon.metrics.getClass.getDeclaredField("_subscriptions")
+ subscriptionsField.setAccessible(true)
+ val subscriptions = subscriptionsField.get(Kamon.metrics).asInstanceOf[LazyActorRef]
+
+ subscriptions.tell(SubscriptionsDispatcher.Tick)
+ }
override protected def afterAll(): Unit = system.shutdown()
}
diff --git a/kamon-core/src/test/scala/kamon/trace/SimpleTraceSpec.scala b/kamon-core/src/test/scala/kamon/trace/SimpleTraceSpec.scala
index 0cb4ce34..1d270106 100644
--- a/kamon-core/src/test/scala/kamon/trace/SimpleTraceSpec.scala
+++ b/kamon-core/src/test/scala/kamon/trace/SimpleTraceSpec.scala
@@ -40,7 +40,7 @@ class SimpleTraceSpec extends BaseKamonSpec("simple-trace-spec") {
"the simple tracing" should {
"send a TraceInfo when the trace has finished and all segments are finished" in {
- Kamon(Tracer)(system).subscribe(testActor)
+ Kamon.tracer.subscribe(testActor)
TraceContext.withContext(newContext("simple-trace-without-segments")) {
TraceContext.currentContext.startSegment("segment-one", "test-segment", "test").finish()
@@ -49,7 +49,7 @@ class SimpleTraceSpec extends BaseKamonSpec("simple-trace-spec") {
}
val traceInfo = expectMsgType[TraceInfo]
- Kamon(Tracer)(system).unsubscribe(testActor)
+ Kamon.tracer.unsubscribe(testActor)
traceInfo.name should be("simple-trace-without-segments")
traceInfo.segments.size should be(2)
@@ -58,7 +58,7 @@ class SimpleTraceSpec extends BaseKamonSpec("simple-trace-spec") {
}
"incubate the tracing context if there are open segments after finishing" in {
- Kamon(Tracer)(system).subscribe(testActor)
+ Kamon.tracer.subscribe(testActor)
val secondSegment = TraceContext.withContext(newContext("simple-trace-without-segments")) {
TraceContext.currentContext.startSegment("segment-one", "test-segment", "test").finish()
@@ -72,7 +72,7 @@ class SimpleTraceSpec extends BaseKamonSpec("simple-trace-spec") {
within(10 seconds) {
val traceInfo = expectMsgType[TraceInfo]
- Kamon(Tracer)(system).unsubscribe(testActor)
+ Kamon.tracer.unsubscribe(testActor)
traceInfo.name should be("simple-trace-without-segments")
traceInfo.segments.size should be(2)
diff --git a/kamon-datadog/src/main/scala/kamon/datadog/Datadog.scala b/kamon-datadog/src/main/scala/kamon/datadog/Datadog.scala
index b7375d9b..53ffd4e6 100644
--- a/kamon-datadog/src/main/scala/kamon/datadog/Datadog.scala
+++ b/kamon-datadog/src/main/scala/kamon/datadog/Datadog.scala
@@ -50,7 +50,7 @@ class DatadogExtension(system: ExtendedActorSystem) extends Kamon.Extension {
val subscriptions = datadogConfig.getConfig("subscriptions")
subscriptions.firstLevelKeys.map { subscriptionCategory ⇒
subscriptions.getStringList(subscriptionCategory).asScala.foreach { pattern ⇒
- Kamon(Metrics).subscribe(subscriptionCategory, pattern, datadogMetricsListener, permanently = true)
+ Kamon.metrics.subscribe(subscriptionCategory, pattern, datadogMetricsListener, permanently = true)
}
}
diff --git a/kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala b/kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala
index 1fcc0c5d..b35902f9 100644
--- a/kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala
+++ b/kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala
@@ -20,6 +20,7 @@ import akka.testkit.{ TestKitBase, TestProbe }
import akka.actor.{ Props, ActorRef, ActorSystem }
import kamon.Kamon
import kamon.metric.instrument._
+import kamon.testkit.BaseKamonSpec
import kamon.util.MilliTimestamp
import org.scalatest.{ Matchers, WordSpecLike }
import kamon.metric._
@@ -29,22 +30,21 @@ import java.lang.management.ManagementFactory
import java.net.InetSocketAddress
import com.typesafe.config.ConfigFactory
-class DatadogMetricSenderSpec extends TestKitBase with WordSpecLike with Matchers {
- implicit lazy val system: ActorSystem = ActorSystem("datadog-metric-sender-spec", ConfigFactory.parseString(
- """
- |kamon {
- | metrics {
- | disable-aspectj-weaver-missing-error = true
- | }
- |
- | datadog {
- | max-packet-size = 256 bytes
- | }
- |}
- |
- """.stripMargin))
-
- val collectionContext = Kamon(Metrics).buildDefaultCollectionContext
+class DatadogMetricSenderSpec extends BaseKamonSpec("datadog-metric-sender-spec") {
+ override lazy val config =
+ ConfigFactory.parseString(
+ """
+ |kamon {
+ | metrics {
+ | disable-aspectj-weaver-missing-error = true
+ | }
+ |
+ | datadog {
+ | max-packet-size = 256 bytes
+ | }
+ |}
+ |
+ """.stripMargin)
"the DataDogMetricSender" should {
"send latency measurements" in new UdpListenerFixture {
@@ -106,7 +106,7 @@ class DatadogMetricSenderSpec extends TestKitBase with WordSpecLike with Matcher
val testMaxPacketSize = system.settings.config.getBytes("kamon.datadog.max-packet-size")
def buildRecorder(name: String): (Entity, TestEntityRecorder) = {
- val registration = Kamon(Metrics).register(TestEntityRecorder, name).get
+ val registration = Kamon.metrics.register(TestEntityRecorder, name).get
(registration.entity, registration.recorder)
}
diff --git a/kamon-jdbc/src/main/scala/kamon/jdbc/instrumentation/StatementInstrumentation.scala b/kamon-jdbc/src/main/scala/kamon/jdbc/instrumentation/StatementInstrumentation.scala
index 386cf019..d169a4c7 100644
--- a/kamon-jdbc/src/main/scala/kamon/jdbc/instrumentation/StatementInstrumentation.scala
+++ b/kamon-jdbc/src/main/scala/kamon/jdbc/instrumentation/StatementInstrumentation.scala
@@ -17,9 +17,9 @@ package kamon.jdbc.instrumentation
import java.util.concurrent.TimeUnit.{ NANOSECONDS ⇒ nanos }
+import kamon.Kamon
import kamon.jdbc.{ JdbcExtension, Jdbc }
import kamon.jdbc.metric.StatementsMetrics
-import kamon.metric.Metrics
import kamon.trace.{ TraceContext, SegmentCategory }
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.{ Around, Aspect, Pointcut }
@@ -44,8 +44,8 @@ class StatementInstrumentation {
@Around("onExecuteStatement(sql) || onExecutePreparedStatement(sql) || onExecutePreparedCall(sql)")
def aroundExecuteStatement(pjp: ProceedingJoinPoint, sql: String): Any = {
TraceContext.map { ctx ⇒
- val metricsExtension = ctx.lookupExtension(Metrics)
- val jdbcExtension = ctx.lookupExtension(Jdbc)
+ val metricsExtension = Kamon.metrics
+ val jdbcExtension = Kamon(Jdbc)
implicit val statementRecorder = metricsExtension.register(StatementsMetrics, "jdbc-statements").map(_.recorder)
sql.replaceAll(CommentPattern, Empty) match {
diff --git a/kamon-log-reporter/src/main/scala/kamon/logreporter/LogReporter.scala b/kamon-log-reporter/src/main/scala/kamon/logreporter/LogReporter.scala
index dc977a52..d5b07f6d 100644
--- a/kamon-log-reporter/src/main/scala/kamon/logreporter/LogReporter.scala
+++ b/kamon-log-reporter/src/main/scala/kamon/logreporter/LogReporter.scala
@@ -35,13 +35,13 @@ class LogReporterExtension(system: ExtendedActorSystem) extends Kamon.Extension
val logReporterConfig = system.settings.config.getConfig("kamon.log-reporter")
val subscriber = system.actorOf(Props[LogReporterSubscriber], "kamon-log-reporter")
- Kamon(Metrics)(system).subscribe("trace", "**", subscriber, permanently = true)
- Kamon(Metrics)(system).subscribe("actor", "**", subscriber, permanently = true)
- Kamon(Metrics)(system).subscribe("user-metrics", "**", subscriber, permanently = true)
+ Kamon.metrics.subscribe("trace", "**", subscriber, permanently = true)
+ Kamon.metrics.subscribe("actor", "**", subscriber, permanently = true)
+ Kamon.metrics.subscribe("user-metrics", "**", subscriber, permanently = true)
val includeSystemMetrics = logReporterConfig.getBoolean("report-system-metrics")
if (includeSystemMetrics) {
- Kamon(Metrics)(system).subscribe("system-metric", "**", subscriber, permanently = true)
+ Kamon.metrics.subscribe("system-metric", "**", subscriber, permanently = true)
}
}
diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala
index 551bb546..3b1b8cb3 100644
--- a/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala
+++ b/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala
@@ -16,13 +16,13 @@
package kamon.newrelic
-import kamon.metric.{ UserMetrics, EntitySnapshot, Entity }
+import kamon.metric.{ UserMetricsExtensionImpl, EntitySnapshot, Entity }
import kamon.metric.instrument.CollectionContext
object CustomMetricExtractor extends MetricExtractor {
def extract(settings: AgentSettings, collectionContext: CollectionContext, metrics: Map[Entity, EntitySnapshot]): Map[MetricID, MetricData] = {
- metrics.get(UserMetrics.entity).map { allUserMetrics ⇒
+ metrics.get(UserMetricsExtensionImpl.UserMetricEntity).map { allUserMetrics ⇒
allUserMetrics.metrics.map {
case (key, snapshot) ⇒ Metric(snapshot, key.unitOfMeasurement, s"Custom/${key.name}", None)
}
diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/MetricReporter.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/MetricReporter.scala
index 51c1ad21..31c04f7a 100644
--- a/kamon-newrelic/src/main/scala/kamon/newrelic/MetricReporter.scala
+++ b/kamon-newrelic/src/main/scala/kamon/newrelic/MetricReporter.scala
@@ -19,7 +19,7 @@ import JsonProtocol._
class MetricReporter(settings: AgentSettings) extends Actor with ActorLogging with SprayJsonSupport {
import context.dispatcher
- val metricsExtension = Kamon(Metrics)(context.system)
+ val metricsExtension = Kamon.metrics
val collectionContext = metricsExtension.buildDefaultCollectionContext
val metricsSubscriber = {
val tickInterval = context.system.settings.config.getDuration("kamon.metric.tick-interval", TimeUnit.MILLISECONDS)
diff --git a/kamon-newrelic/src/test/scala/kamon/newrelic/MetricReporterSpec.scala b/kamon-newrelic/src/test/scala/kamon/newrelic/MetricReporterSpec.scala
index a8aa00d7..04380677 100644
--- a/kamon-newrelic/src/test/scala/kamon/newrelic/MetricReporterSpec.scala
+++ b/kamon-newrelic/src/test/scala/kamon/newrelic/MetricReporterSpec.scala
@@ -16,43 +16,44 @@
package kamon.newrelic
-import akka.actor.{ ActorRef, ActorSystem }
+import akka.actor.ActorRef
import akka.io.IO
import akka.testkit._
import akka.util.Timeout
import com.typesafe.config.ConfigFactory
-import kamon.metric.{ Entity, Metrics, TraceMetrics }
+import kamon.metric.{ Entity, TraceMetrics }
+import kamon.testkit.BaseKamonSpec
import kamon.util.MilliTimestamp
import kamon.Kamon
import kamon.metric.SubscriptionsDispatcher.TickMetricSnapshot
-import org.scalatest.{ Matchers, WordSpecLike }
import spray.can.Http
import spray.http.Uri.Query
import spray.http._
import spray.httpx.encoding.Deflate
-import spray.httpx.{ RequestBuilding, SprayJsonSupport }
+import spray.httpx.SprayJsonSupport
import testkit.AkkaExtensionSwap
import scala.concurrent.duration._
import spray.json._
-class MetricReporterSpec extends TestKitBase with WordSpecLike with Matchers with RequestBuilding with SprayJsonSupport {
+class MetricReporterSpec extends BaseKamonSpec("metric-reporter-spec") with SprayJsonSupport {
import kamon.newrelic.JsonProtocol._
- implicit lazy val system: ActorSystem = ActorSystem("metric-reporter-spec", ConfigFactory.parseString(
- """
- |akka {
- | loggers = ["akka.testkit.TestEventListener"]
- | loglevel = "INFO"
- |}
- |kamon {
- | metric {
- | tick-interval = 1 hour
- | }
- |
- | modules.kamon-newrelic.auto-start = no
- |}
- |
- """.stripMargin))
+ override lazy val config =
+ ConfigFactory.parseString(
+ """
+ |akka {
+ | loggers = ["akka.testkit.TestEventListener"]
+ | loglevel = "INFO"
+ |}
+ |kamon {
+ | metric {
+ | tick-interval = 1 hour
+ | }
+ |
+ | modules.kamon-newrelic.auto-start = no
+ |}
+ |
+ """.stripMargin)
val agentSettings = AgentSettings("1111111111", "kamon", "test-host", 1, Timeout(5 seconds), 1, 30 seconds, 1D)
val baseQuery = Query(
@@ -138,8 +139,8 @@ class MetricReporterSpec extends TestKitBase with WordSpecLike with Matchers wit
trait FakeTickSnapshotsFixture {
val testTraceID = Entity("example-trace", "trace")
- val recorder = Kamon(Metrics).register(TraceMetrics, testTraceID.name).get.recorder
- val collectionContext = Kamon(Metrics).buildDefaultCollectionContext
+ val recorder = Kamon.metrics.register(TraceMetrics, testTraceID.name).get.recorder
+ val collectionContext = Kamon.metrics.buildDefaultCollectionContext
def collectRecorder = recorder.collect(collectionContext)
diff --git a/kamon-play/src/main/scala/kamon/play/Play.scala b/kamon-play/src/main/scala/kamon/play/Play.scala
index 7ca81028..3c3e4fa7 100644
--- a/kamon-play/src/main/scala/kamon/play/Play.scala
+++ b/kamon-play/src/main/scala/kamon/play/Play.scala
@@ -20,7 +20,7 @@ import akka.actor.{ ExtendedActorSystem, Extension, ExtensionId, ExtensionIdProv
import akka.event.Logging
import kamon.Kamon
import kamon.http.HttpServerMetrics
-import kamon.metric.{ Entity, Metrics }
+import kamon.metric.Entity
import play.api.libs.ws.WSRequest
import play.api.mvc.RequestHeader
@@ -37,11 +37,11 @@ class PlayExtension(private val system: ExtendedActorSystem) extends Kamon.Exten
private val config = system.settings.config.getConfig("kamon.play")
val httpServerMetrics = {
- val metricsExtension = Metrics.get(system)
+ val metricsExtension = Kamon.metrics
val factory = metricsExtension.instrumentFactory(HttpServerMetrics.category)
val entity = Entity("play-server", HttpServerMetrics.category)
- Metrics.get(system).register(entity, new HttpServerMetrics(factory)).recorder
+ metricsExtension.register(entity, new HttpServerMetrics(factory)).recorder
}
val defaultDispatcher = system.dispatchers.lookup(config.getString("dispatcher"))
diff --git a/kamon-play/src/main/scala/kamon/play/instrumentation/RequestInstrumentation.scala b/kamon-play/src/main/scala/kamon/play/instrumentation/RequestInstrumentation.scala
index 38f499b4..e9b2d570 100644
--- a/kamon-play/src/main/scala/kamon/play/instrumentation/RequestInstrumentation.scala
+++ b/kamon-play/src/main/scala/kamon/play/instrumentation/RequestInstrumentation.scala
@@ -36,14 +36,13 @@ class RequestInstrumentation {
@After("call(* play.api.GlobalSettings.onStart(*)) && args(application)")
def afterApplicationStart(application: play.api.Application): Unit = {
- Kamon(Play)(Akka.system())
+ Kamon(Play)
}
@Before("call(* play.api.GlobalSettings.onRouteRequest(..)) && args(requestHeader)")
def beforeRouteRequest(requestHeader: RequestHeader): Unit = {
- implicit val system = Akka.system()
+ import Kamon.tracer
val playExtension = Kamon(Play)
- val tracer = Kamon(Tracer)
val defaultTraceName = playExtension.generateTraceName(requestHeader)
val token = if (playExtension.includeTraceToken) {
@@ -58,14 +57,14 @@ class RequestInstrumentation {
def aroundDoFilter(pjp: ProceedingJoinPoint, next: EssentialAction): Any = {
val essentialAction = (requestHeader: RequestHeader) ⇒ {
- val executor = Kamon(Play)(Akka.system()).defaultDispatcher
+ val playExtension = Kamon(Play)
+ val executor = playExtension.defaultDispatcher
def onResult(result: Result): Result = {
TraceContext.map { ctx ⇒
ctx.finish()
- val playExtension = ctx.lookupExtension(Play)
- recordHttpServerMetrics(result.header, ctx.name, playExtension)
+ recordHttpServerMetrics(result.header, ctx.name)
if (playExtension.includeTraceToken) result.withHeaders(playExtension.traceTokenHeaderName -> ctx.token)
else result
@@ -87,12 +86,12 @@ class RequestInstrumentation {
@Before("call(* play.api.GlobalSettings.onError(..)) && args(request, ex)")
def beforeOnError(request: TraceContextAware, ex: Throwable): Unit = {
TraceContext.map { ctx ⇒
- recordHttpServerMetrics(InternalServerError.header, ctx.name, ctx.lookupExtension(Play))
+ recordHttpServerMetrics(InternalServerError.header, ctx.name)
}
}
- def recordHttpServerMetrics(header: ResponseHeader, traceName: String, playExtension: PlayExtension): Unit =
- playExtension.httpServerMetrics.recordResponse(traceName, header.status.toString)
+ def recordHttpServerMetrics(header: ResponseHeader, traceName: String): Unit =
+ Kamon(Play).httpServerMetrics.recordResponse(traceName, header.status.toString)
def storeDiagnosticData(request: RequestHeader): Unit = {
val agent = request.headers.get(UserAgent).getOrElse(Unknown)
diff --git a/kamon-play/src/main/scala/kamon/play/instrumentation/WSInstrumentation.scala b/kamon-play/src/main/scala/kamon/play/instrumentation/WSInstrumentation.scala
index fc58f9da..8b76ab8b 100644
--- a/kamon-play/src/main/scala/kamon/play/instrumentation/WSInstrumentation.scala
+++ b/kamon-play/src/main/scala/kamon/play/instrumentation/WSInstrumentation.scala
@@ -16,6 +16,7 @@
package kamon.play.instrumentation
+import kamon.Kamon
import kamon.play.Play
import kamon.trace.{ TraceContext, SegmentCategory }
import org.aspectj.lang.ProceedingJoinPoint
@@ -33,7 +34,7 @@ class WSInstrumentation {
@Around("onExecuteRequest(request)")
def aroundExecuteRequest(pjp: ProceedingJoinPoint, request: WSRequest): Any = {
TraceContext.map { ctx ⇒
- val playExtension = ctx.lookupExtension(Play)
+ val playExtension = Kamon(Play)
val executor = playExtension.defaultDispatcher
val segmentName = playExtension.generateHttpClientSegmentName(request)
val segment = ctx.startSegment(segmentName, SegmentCategory.HttpClient, Play.SegmentLibraryName)
diff --git a/kamon-play/src/test/scala/kamon/play/LoggerLikeInstrumentationSpec.scala b/kamon-play/src/test/scala/kamon/play/LoggerLikeInstrumentationSpec.scala
index 622c2501..de85743c 100644
--- a/kamon-play/src/test/scala/kamon/play/LoggerLikeInstrumentationSpec.scala
+++ b/kamon-play/src/test/scala/kamon/play/LoggerLikeInstrumentationSpec.scala
@@ -19,6 +19,7 @@ import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.classic.{ AsyncAppender, LoggerContext }
import ch.qos.logback.core.read.ListAppender
import ch.qos.logback.core.status.NopStatusListener
+import kamon.Kamon
import kamon.trace.TraceLocal
import kamon.trace.TraceLocal.AvailableToMdc
import org.scalatest.BeforeAndAfter
@@ -34,7 +35,7 @@ import scala.concurrent.duration._
import scala.concurrent.{ Await, Future }
class LoggerLikeInstrumentationSpec extends PlaySpec with OneServerPerSuite with BeforeAndAfter {
-
+ Kamon.start()
System.setProperty("config.file", "./kamon-play/src/test/resources/conf/application.conf")
val executor = scala.concurrent.ExecutionContext.Implicits.global
diff --git a/kamon-play/src/test/scala/kamon/play/RequestInstrumentationSpec.scala b/kamon-play/src/test/scala/kamon/play/RequestInstrumentationSpec.scala
index 0feecb82..3e199df6 100644
--- a/kamon-play/src/test/scala/kamon/play/RequestInstrumentationSpec.scala
+++ b/kamon-play/src/test/scala/kamon/play/RequestInstrumentationSpec.scala
@@ -16,8 +16,6 @@
package kamon.play
import kamon.Kamon
-import kamon.http.HttpServerMetrics
-import kamon.metric.{ Metrics, TraceMetrics }
import kamon.metric.instrument.CollectionContext
import kamon.play.action.TraceName
import kamon.trace.TraceLocal.HttpContextKey
@@ -33,13 +31,12 @@ import play.api.test.Helpers._
import play.api.test._
import play.core.Router.{ HandlerDef, Route, Routes }
import play.core.{ DynamicPart, PathPattern, Router, StaticPart }
-import play.libs.Akka
import scala.concurrent.duration._
import scala.concurrent.{ Await, Future }
class RequestInstrumentationSpec extends PlaySpec with OneServerPerSuite {
-
+ Kamon.start()
System.setProperty("config.file", "./kamon-play/src/test/resources/conf/application.conf")
val executor = scala.concurrent.ExecutionContext.Implicits.global
@@ -130,17 +127,17 @@ class RequestInstrumentationSpec extends PlaySpec with OneServerPerSuite {
"response to the getRouted Action and normalise the current TraceContext name" in {
Await.result(WS.url("http://localhost:19001/getRouted").get(), 10 seconds)
- Kamon(Metrics)(Akka.system()).find("getRouted.get", "trace") must not be empty
+ Kamon.metrics.find("getRouted.get", "trace") must not be empty
}
"response to the postRouted Action and normalise the current TraceContext name" in {
Await.result(WS.url("http://localhost:19001/postRouted").post("content"), 10 seconds)
- Kamon(Metrics)(Akka.system()).find("postRouted.post", "trace") must not be empty
+ Kamon.metrics.find("postRouted.post", "trace") must not be empty
}
"response to the showRouted Action and normalise the current TraceContext name" in {
Await.result(WS.url("http://localhost:19001/showRouted/2").get(), 10 seconds)
- Kamon(Metrics)(Akka.system()).find("show.some.id.get", "trace") must not be empty
+ Kamon.metrics.find("show.some.id.get", "trace") must not be empty
}
"include HttpContext information for help to diagnose possible errors" in {
@@ -155,7 +152,7 @@ class RequestInstrumentationSpec extends PlaySpec with OneServerPerSuite {
"record http server metrics for all processed requests" in {
val collectionContext = CollectionContext(100)
- Kamon(Metrics)(Akka.system()).find("play-server", "http-server").get.collect(collectionContext)
+ Kamon.metrics.find("play-server", "http-server").get.collect(collectionContext)
for (repetition ← 1 to 10) {
Await.result(route(FakeRequest(GET, "/default").withHeaders(traceTokenHeader)).get, 10 seconds)
@@ -169,7 +166,7 @@ class RequestInstrumentationSpec extends PlaySpec with OneServerPerSuite {
Await.result(routeWithOnError(FakeRequest(GET, "/error").withHeaders(traceTokenHeader)).get, 10 seconds)
}
- val snapshot = Kamon(Metrics)(Akka.system()).find("play-server", "http-server").get.collect(collectionContext)
+ val snapshot = Kamon.metrics.find("play-server", "http-server").get.collect(collectionContext)
snapshot.counter("GET: /default_200").get.count must be(10)
snapshot.counter("GET: /notFound_404").get.count must be(5)
snapshot.counter("GET: /error_500").get.count must be(5)
diff --git a/kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala b/kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala
index 795453d0..9e87da84 100644
--- a/kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala
+++ b/kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala
@@ -17,8 +17,8 @@
package kamon.play
import kamon.Kamon
-import kamon.metric.{ Metrics, EntitySnapshot, TraceMetrics }
-import kamon.trace.{ Tracer, TraceContext, SegmentCategory }
+import kamon.metric.{ EntitySnapshot, TraceMetrics }
+import kamon.trace.{ TraceContext, SegmentCategory }
import org.scalatest.{ Matchers, WordSpecLike }
import org.scalatestplus.play.OneServerPerSuite
import play.api.libs.ws.WS
@@ -26,12 +26,12 @@ import play.api.mvc.Action
import play.api.mvc.Results.Ok
import play.api.test.Helpers._
import play.api.test._
-import play.libs.Akka
import scala.concurrent.Await
import scala.concurrent.duration._
class WSInstrumentationSpec extends WordSpecLike with Matchers with OneServerPerSuite {
+ Kamon.start()
import kamon.metric.TraceMetricsSpec.SegmentSyntax
System.setProperty("config.file", "./kamon-play/src/test/resources/conf/application.conf")
@@ -66,11 +66,11 @@ class WSInstrumentationSpec extends WordSpecLike with Matchers with OneServerPer
}
def newContext(name: String): TraceContext =
- Kamon(Tracer)(Akka.system).newContext(name)
+ Kamon.tracer.newContext(name)
def takeSnapshotOf(traceName: String): EntitySnapshot = {
- val recorder = Kamon(Metrics)(Akka.system()).register(TraceMetrics, traceName).get.recorder
- val collectionContext = Kamon(Metrics)(Akka.system()).buildDefaultCollectionContext
+ val recorder = Kamon.metrics.register(TraceMetrics, traceName).get.recorder
+ val collectionContext = Kamon.metrics.buildDefaultCollectionContext
recorder.collect(collectionContext)
}
diff --git a/kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala b/kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala
index 67ab3c97..86f0c93e 100644
--- a/kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala
+++ b/kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala
@@ -38,7 +38,7 @@ object SimpleRequestProcessor extends App with SimpleRoutingApp with RequestBuil
import scala.concurrent.duration._
implicit val system = ActorSystem("test")
- val kamon = Kamon(system)
+ Kamon.start()
import test.SimpleRequestProcessor.system.dispatcher
val printer = system.actorOf(Props[PrintWhatever])
@@ -49,7 +49,7 @@ object SimpleRequestProcessor extends App with SimpleRoutingApp with RequestBuil
implicit val timeout = Timeout(30 seconds)
- val counter = Kamon(UserMetrics).counter("requests")
+ val counter = Kamon.userMetrics.counter("requests")
val pipeline = sendReceive
val replier = system.actorOf(Props[Replier].withRouter(RoundRobinPool(nrOfInstances = 4)), "replier")
@@ -179,6 +179,6 @@ object PingPong extends App {
def receive: Actor.Receive = { case "ping" ⇒ sender ! "pong" }
}))
- pinger.tell("pong", ponger)
+ //pinger.tell("pong", ponger)
}
diff --git a/kamon-spray/src/main/scala/kamon/spray/SprayExtension.scala b/kamon-spray/src/main/scala/kamon/spray/SprayExtension.scala
index 3df8d972..ab0fe50b 100644
--- a/kamon-spray/src/main/scala/kamon/spray/SprayExtension.scala
+++ b/kamon-spray/src/main/scala/kamon/spray/SprayExtension.scala
@@ -21,7 +21,7 @@ import akka.actor
import akka.event.{ Logging, LoggingAdapter }
import kamon.Kamon
import kamon.http.HttpServerMetrics
-import kamon.metric.{ Entity, Metrics }
+import kamon.metric.Entity
import spray.http.HttpHeaders.Host
import spray.http.HttpRequest
@@ -46,11 +46,11 @@ class SprayExtensionImpl(system: ExtendedActorSystem) extends SprayExtension {
val log = Logging(system, "SprayExtension")
val httpServerMetrics = {
- val metricsExtension = Metrics.get(system)
+ val metricsExtension = Kamon.metrics
val factory = metricsExtension.instrumentFactory(HttpServerMetrics.category)
val entity = Entity("spray-server", HttpServerMetrics.category)
- Metrics.get(system).register(entity, new HttpServerMetrics(factory)).recorder
+ metricsExtension.register(entity, new HttpServerMetrics(factory)).recorder
}
def generateTraceName(request: HttpRequest): String =
diff --git a/kamon-spray/src/main/scala/kamon/spray/instrumentation/ClientRequestInstrumentation.scala b/kamon-spray/src/main/scala/kamon/spray/instrumentation/ClientRequestInstrumentation.scala
index fa9063ad..d1e9036d 100644
--- a/kamon-spray/src/main/scala/kamon/spray/instrumentation/ClientRequestInstrumentation.scala
+++ b/kamon-spray/src/main/scala/kamon/spray/instrumentation/ClientRequestInstrumentation.scala
@@ -16,6 +16,7 @@
package spray.can.client
+import kamon.Kamon
import org.aspectj.lang.annotation._
import org.aspectj.lang.ProceedingJoinPoint
import spray.http._
@@ -47,7 +48,7 @@ class ClientRequestInstrumentation {
requestContext.traceContext
TraceContext.map { ctx ⇒
- val sprayExtension = ctx.lookupExtension(Spray)
+ val sprayExtension = Kamon.extension(Spray)
if (sprayExtension.settings.clientInstrumentationLevel == ClientInstrumentationLevel.HostLevelAPI) {
if (requestContext.segment.isEmpty) {
@@ -112,7 +113,7 @@ class ClientRequestInstrumentation {
(request: HttpRequest) ⇒ {
TraceContext.map { ctx ⇒
- val sprayExtension = ctx.lookupExtension(Spray)
+ val sprayExtension = Kamon.extension(Spray)
val segment =
if (sprayExtension.settings.clientInstrumentationLevel == ClientInstrumentationLevel.RequestLevelAPI)
ctx.startSegment(sprayExtension.generateRequestLevelApiSegmentName(request), SegmentCategory.HttpClient, Spray.SegmentLibraryName)
@@ -139,7 +140,7 @@ class ClientRequestInstrumentation {
def aroundIncludingDefaultHeadersAtHttpHostConnector(pjp: ProceedingJoinPoint, request: HttpMessage, defaultHeaders: List[HttpHeader]): Any = {
val modifiedHeaders = TraceContext.map { ctx ⇒
- val sprayExtension = ctx.lookupExtension(Spray)
+ val sprayExtension = Kamon.extension(Spray)
if (sprayExtension.settings.includeTraceTokenHeader)
RawHeader(sprayExtension.settings.traceTokenHeaderName, ctx.token) :: defaultHeaders
else
diff --git a/kamon-spray/src/main/scala/kamon/spray/instrumentation/ServerRequestInstrumentation.scala b/kamon-spray/src/main/scala/kamon/spray/instrumentation/ServerRequestInstrumentation.scala
index 73287132..bf20d167 100644
--- a/kamon-spray/src/main/scala/kamon/spray/instrumentation/ServerRequestInstrumentation.scala
+++ b/kamon-spray/src/main/scala/kamon/spray/instrumentation/ServerRequestInstrumentation.scala
@@ -39,9 +39,8 @@ class ServerRequestInstrumentation {
@After("openRequestInit(openRequest, request)")
def afterInit(openRequest: TraceContextAware, request: HttpRequest): Unit = {
- val system: ActorSystem = openRequest.asInstanceOf[OpenRequest].context.actorContext.system
- val tracer = Tracer.get(system)
- val sprayExtension = Kamon(Spray)(system)
+ import Kamon.tracer
+ val sprayExtension = Kamon(Spray)
val defaultTraceName = sprayExtension.generateTraceName(request)
val token = if (sprayExtension.settings.includeTraceTokenHeader) {
@@ -77,7 +76,7 @@ class ServerRequestInstrumentation {
if (incomingContext.isEmpty)
pjp.proceed()
else {
- val sprayExtension = incomingContext.lookupExtension(Spray)
+ val sprayExtension = Kamon(Spray)
val proceedResult = if (sprayExtension.settings.includeTraceTokenHeader) {
val responseWithHeader = includeTraceTokenIfPossible(response, sprayExtension.settings.traceTokenHeaderName, incomingContext.token)
@@ -98,7 +97,7 @@ class ServerRequestInstrumentation {
def verifyTraceContextConsistency(incomingTraceContext: TraceContext, storedTraceContext: TraceContext): Unit = {
def publishWarning(text: String): Unit =
- storedTraceContext.lookupExtension(Spray).log.warning(text)
+ Kamon(Spray).log.warning(text)
if (incomingTraceContext.nonEmpty) {
if (incomingTraceContext.token != storedTraceContext.token)
diff --git a/kamon-spray/src/test/scala/kamon/spray/ClientRequestInstrumentationSpec.scala b/kamon-spray/src/test/scala/kamon/spray/ClientRequestInstrumentationSpec.scala
index c5d7d992..a99bbdcc 100644
--- a/kamon-spray/src/test/scala/kamon/spray/ClientRequestInstrumentationSpec.scala
+++ b/kamon-spray/src/test/scala/kamon/spray/ClientRequestInstrumentationSpec.scala
@@ -264,14 +264,14 @@ class ClientRequestInstrumentationSpec extends BaseKamonSpec("client-request-ins
def disableAutomaticTraceTokenPropagation(): Unit = setIncludeTraceToken(false)
def setSegmentCollectionStrategy(strategy: ClientInstrumentationLevel.Level): Unit = {
- val target = Kamon(Spray)(system).settings
+ val target = Kamon(Spray).settings
val field = target.getClass.getDeclaredField("clientInstrumentationLevel")
field.setAccessible(true)
field.set(target, strategy)
}
def setIncludeTraceToken(include: Boolean): Unit = {
- val target = Kamon(Spray)(system).settings
+ val target = Kamon(Spray).settings
val field = target.getClass.getDeclaredField("includeTraceTokenHeader")
field.setAccessible(true)
field.set(target, include)
diff --git a/kamon-spray/src/test/scala/kamon/spray/SprayServerTracingSpec.scala b/kamon-spray/src/test/scala/kamon/spray/SprayServerTracingSpec.scala
index 1ae0cb98..bfd88ac8 100644
--- a/kamon-spray/src/test/scala/kamon/spray/SprayServerTracingSpec.scala
+++ b/kamon-spray/src/test/scala/kamon/spray/SprayServerTracingSpec.scala
@@ -79,7 +79,7 @@ class SprayServerTracingSpec extends BaseKamonSpec("spray-server-tracing-spec")
def disableAutomaticTraceTokenPropagation(): Unit = setIncludeTraceToken(false)
def setIncludeTraceToken(include: Boolean): Unit = {
- val target = Kamon(Spray)(system).settings
+ val target = Kamon(Spray).settings
val field = target.getClass.getDeclaredField("includeTraceTokenHeader")
field.setAccessible(true)
field.set(target, include)
diff --git a/kamon-statsd/src/main/scala/kamon/statsd/StatsD.scala b/kamon-statsd/src/main/scala/kamon/statsd/StatsD.scala
index d363bdd4..d406faf6 100644
--- a/kamon-statsd/src/main/scala/kamon/statsd/StatsD.scala
+++ b/kamon-statsd/src/main/scala/kamon/statsd/StatsD.scala
@@ -40,7 +40,7 @@ class StatsDExtension(system: ExtendedActorSystem) extends Kamon.Extension {
private val config = system.settings.config
private val statsDConfig = config.getConfig("kamon.statsd")
- val metricsExtension = Kamon(Metrics)
+ val metricsExtension = Kamon.metrics
val tickInterval = metricsExtension.settings.tickInterval
val statsDHost = new InetSocketAddress(statsDConfig.getString("hostname"), statsDConfig.getInt("port"))
diff --git a/kamon-statsd/src/test/scala/kamon/statsd/StatsDMetricSenderSpec.scala b/kamon-statsd/src/test/scala/kamon/statsd/StatsDMetricSenderSpec.scala
index a0d787d9..0211ac0f 100644
--- a/kamon-statsd/src/test/scala/kamon/statsd/StatsDMetricSenderSpec.scala
+++ b/kamon-statsd/src/test/scala/kamon/statsd/StatsDMetricSenderSpec.scala
@@ -20,6 +20,7 @@ import akka.testkit.{ TestKitBase, TestProbe }
import akka.actor.{ ActorRef, Props, ActorSystem }
import kamon.Kamon
import kamon.metric.instrument.{ InstrumentFactory, UnitOfMeasurement }
+import kamon.testkit.BaseKamonSpec
import kamon.util.MilliTimestamp
import org.scalatest.{ Matchers, WordSpecLike }
import kamon.metric._
@@ -28,28 +29,26 @@ import kamon.metric.SubscriptionsDispatcher.TickMetricSnapshot
import java.net.InetSocketAddress
import com.typesafe.config.ConfigFactory
-class StatsDMetricSenderSpec extends TestKitBase with WordSpecLike with Matchers {
- implicit lazy val system: ActorSystem = ActorSystem("statsd-metric-sender-spec", ConfigFactory.parseString(
- """
- |kamon {
- | statsd.simple-metric-key-generator {
- | application = kamon
- | hostname-override = kamon-host
- | include-hostname = true
- | metric-name-normalization-strategy = normalize
- | }
- |}
- |
- """.stripMargin))
+class StatsDMetricSenderSpec extends BaseKamonSpec("statsd-metric-sender-spec") {
+ override lazy val config =
+ ConfigFactory.parseString(
+ """
+ |kamon {
+ | statsd.simple-metric-key-generator {
+ | application = kamon
+ | hostname-override = kamon-host
+ | include-hostname = true
+ | metric-name-normalization-strategy = normalize
+ | }
+ |}
+ |
+ """.stripMargin)
implicit val metricKeyGenerator = new SimpleMetricKeyGenerator(system.settings.config) {
override def hostName: String = "localhost_local"
}
- val collectionContext = Kamon(Metrics).buildDefaultCollectionContext
-
"the StatsDMetricSender" should {
-
"flush the metrics data after processing the tick, even if the max-packet-size is not reached" in new UdpListenerFixture {
val testMetricKey = buildMetricKey(testEntity, "metric-one")
val testRecorder = buildRecorder("user/kamon")
@@ -134,7 +133,7 @@ class StatsDMetricSenderSpec extends TestKitBase with WordSpecLike with Matchers
}
def buildRecorder(name: String): TestEntityRecorder = {
- Kamon(Metrics).register(TestEntityRecorder, name).get.recorder
+ Kamon.metrics.register(TestEntityRecorder, name).get.recorder
}
def setup(metrics: Map[Entity, EntitySnapshot]): TestProbe = {
diff --git a/kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsExtension.scala b/kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsExtension.scala
index 8a27dd03..ebdaf01f 100644
--- a/kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsExtension.scala
+++ b/kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsExtension.scala
@@ -42,7 +42,7 @@ class SystemMetricsExtension(system: ExtendedActorSystem) extends Kamon.Extensio
val sigarFolder = config.getString("sigar-native-folder")
val sigarRefreshInterval = config.getFiniteDuration("sigar-metrics-refresh-interval")
val contextSwitchesRefreshInterval = config.getFiniteDuration("context-switches-refresh-interval")
- val metricsExtension = Kamon(Metrics)(system)
+ val metricsExtension = Kamon.metrics
// Sigar-based metrics
SigarProvisioner.provision(new File(sigarFolder))
diff --git a/kamon-system-metrics/src/main/scala/kamon/system/custom/ContextSwitchesMetrics.scala b/kamon-system-metrics/src/main/scala/kamon/system/custom/ContextSwitchesMetrics.scala
index 0f1cffca..384c89f1 100644
--- a/kamon-system-metrics/src/main/scala/kamon/system/custom/ContextSwitchesMetrics.scala
+++ b/kamon-system-metrics/src/main/scala/kamon/system/custom/ContextSwitchesMetrics.scala
@@ -88,7 +88,7 @@ class ContextSwitchesMetrics(pid: Long, log: LoggingAdapter, instrumentFactory:
object ContextSwitchesMetrics {
def register(system: ActorSystem, refreshInterval: FiniteDuration): ContextSwitchesMetrics = {
- val metricsExtension = Kamon(Metrics)(system)
+ val metricsExtension = Kamon.metrics
val log = Logging(system, "ContextSwitchesMetrics")
val pid = (new Sigar).getPid
diff --git a/kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarMetricsUpdater.scala b/kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarMetricsUpdater.scala
index 67eb48a9..e68b0ede 100644
--- a/kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarMetricsUpdater.scala
+++ b/kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarMetricsUpdater.scala
@@ -19,7 +19,7 @@ package kamon.system.sigar
import akka.actor.{ Props, Actor }
import kamon.Kamon
import kamon.metric.instrument.InstrumentFactory
-import kamon.metric.{ Entity, EntityRecorder, MetricsExtension, Metrics }
+import kamon.metric.{ Entity, EntityRecorder, MetricsExtension }
import kamon.system.sigar.SigarMetricsUpdater.UpdateSigarMetrics
import org.hyperic.sigar.Sigar
@@ -27,7 +27,7 @@ import scala.concurrent.duration.FiniteDuration
class SigarMetricsUpdater(refreshInterval: FiniteDuration) extends Actor {
val sigar = new Sigar
- val metricsExtension = Kamon(Metrics)(context.system)
+ val metricsExtension = Kamon.metrics
val sigarMetrics = List(
CpuMetrics.register(sigar, metricsExtension),
diff --git a/project/Projects.scala b/project/Projects.scala
index 2004ac07..e2aed340 100644
--- a/project/Projects.scala
+++ b/project/Projects.scala
@@ -111,7 +111,7 @@ object Projects extends Build {
compile(sprayCan, sprayClient, sprayRouting, sprayJson, sprayJsonLenses, newrelic, akkaSlf4j) ++
provided(aspectJ) ++
test(scalatest, akkaTestKit, sprayTestkit, slf4Api, akkaSlf4j))
- .dependsOn(kamonCore)
+ .dependsOn(kamonCore % "compile->compile;test->test")
.dependsOn(kamonTestkit % "compile->compile;test->test")
@@ -165,7 +165,7 @@ object Projects extends Build {
libraryDependencies ++=
compile(akkaActor) ++
test(scalatest, akkaTestKit, slf4Api, slf4nop))
- .dependsOn(kamonCore)
+ .dependsOn(kamonCore % "compile->compile;test->test")
.dependsOn(kamonSystemMetrics % "provided")
lazy val kamonDatadog = Project("kamon-datadog", file("kamon-datadog"))
@@ -175,7 +175,7 @@ object Projects extends Build {
libraryDependencies ++=
compile(akkaActor) ++
test(scalatest, akkaTestKit, slf4Api, slf4nop))
- .dependsOn(kamonCore)
+ .dependsOn(kamonCore % "compile->compile;test->test")
.dependsOn(kamonSystemMetrics % "provided")
lazy val kamonLogReporter = Project("kamon-log-reporter", file("kamon-log-reporter"))
diff --git a/project/Settings.scala b/project/Settings.scala
index 22a1f4e7..700312c1 100644
--- a/project/Settings.scala
+++ b/project/Settings.scala
@@ -13,9 +13,11 @@
* =========================================================================================
*/
+import com.typesafe.sbt.SbtAspectj.AspectjKeys._
+import sbt.Tests.{SubProcess, Group}
import sbt._
import Keys._
-import com.typesafe.sbt.SbtScalariform
+import com.typesafe.sbt.{SbtAspectj, SbtScalariform}
import com.typesafe.sbt.SbtScalariform.ScalariformKeys
import Publish.{settings => publishSettings}
import Release.{settings => releaseSettings}
@@ -29,17 +31,18 @@ object Settings {
val ScalaVersion = "2.10.4"
lazy val basicSettings = Seq(
- scalaVersion := ScalaVersion,
- resolvers ++= Dependencies.resolutionRepos,
- fork in run := true,
+ scalaVersion := ScalaVersion,
+ resolvers ++= Dependencies.resolutionRepos,
+ fork in run := true,
+ testGrouping in Test := singleTests((definedTests in Test).value, (javaOptions in Test).value),
javacOptions in compile := Seq(
"-Xlint:-options",
"-source", JavaVersion, "-target", JavaVersion
),
- javacOptions in doc := Seq(
+ javacOptions in doc := Seq(
"-source", JavaVersion
),
- scalacOptions := Seq(
+ scalacOptions := Seq(
"-encoding",
"utf8",
"-g:vars",
@@ -54,6 +57,15 @@ object Settings {
"-Xlog-reflective-calls"
)) ++ publishSettings ++ releaseSettings ++ graphSettings
+
+ def singleTests(tests: Seq[TestDefinition], jvmSettings: Seq[String]): Seq[Group] =
+ tests map { test =>
+ new Group(
+ name = test.name,
+ tests = Seq(test),
+ runPolicy = SubProcess(ForkOptions(runJVMOptions = jvmSettings)))
+ }
+
lazy val formatSettings = SbtScalariform.scalariformSettings ++ Seq(
ScalariformKeys.preferences in Compile := formattingPreferences,
ScalariformKeys.preferences in Test := formattingPreferences