From 026d7ae4ea90a5de74ecb91f9ebdd297f6987cb2 Mon Sep 17 00:00:00 2001 From: Ivan Topolnjak Date: Fri, 17 Jul 2015 18:46:40 +0200 Subject: + core: introduce auto-start feature to make Kamon more test-friendly, related to #202. --- kamon-core/src/main/scala/kamon/Kamon.scala | 22 ++++++++++++++++++++-- .../test/scala/kamon/testkit/BaseKamonSpec.scala | 2 +- .../main/scala/test/SimpleRequestProcessor.scala | 2 +- project/Settings.scala | 6 ++++-- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/kamon-core/src/main/scala/kamon/Kamon.scala b/kamon-core/src/main/scala/kamon/Kamon.scala index d819588c..1c560d9f 100644 --- a/kamon-core/src/main/scala/kamon/Kamon.scala +++ b/kamon-core/src/main/scala/kamon/Kamon.scala @@ -16,6 +16,7 @@ package kamon import _root_.akka.actor import _root_.akka.actor._ +import _root_.akka.event.Logging import com.typesafe.config.{ ConfigFactory, Config } import kamon.metric._ import kamon.trace.{ TracerModuleImpl, TracerModule } @@ -25,10 +26,14 @@ object Kamon { private case class KamonCoreComponents(metrics: MetricsModule, tracer: TracerModule) + private val shouldAutoStart = isSystemPropertyEnabled("kamon.auto-start") + private val shouldWarnOnDuplicateStart = !isSystemPropertyEnabled("kamon.disable-duplicate-start-warning") + @volatile private var _system: ActorSystem = _ @volatile private var _coreComponents: Option[KamonCoreComponents] = None def start(config: Config): Unit = synchronized { + def resolveInternalConfig: Config = { val internalConfig = config.getConfig("kamon.internal-config") @@ -49,9 +54,15 @@ object Kamon { tracer.start(_system) _system.registerExtension(ModuleLoader) - } else sys.error("Kamon has already been started.") + } else if (shouldWarnOnDuplicateStart) { + val logger = Logging(_system, "Kamon") + logger.warning("An attempt to start Kamon has been made, but Kamon has already been started.") + } } + private def isSystemPropertyEnabled(propertyName: String): Boolean = + sys.props.get(propertyName).map(_.equals("true")).getOrElse(false) + def start(): Unit = start(ConfigFactory.load) @@ -79,7 +90,14 @@ object Kamon { apply(key) private def ifStarted[T](thunk: KamonCoreComponents ⇒ T): T = - _coreComponents.map(thunk(_)) getOrElse (sys.error("Kamon has not been started yet.")) + _coreComponents.map(thunk(_)) getOrElse { + if (shouldAutoStart) { + start() + thunk(_coreComponents.get) + + } else sys.error("Kamon has not been started yet. You must either explicitlt call Kamon.start(...) or enable " + + "automatic startup by adding -Dkamon.auto-start=true to your JVM options.") + } } diff --git a/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala b/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala index cb909ad9..61cc4e6b 100644 --- a/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala +++ b/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala @@ -28,7 +28,7 @@ import org.scalatest.{ BeforeAndAfterAll, Matchers, WordSpecLike } abstract class BaseKamonSpec(actorSystemName: String) extends TestKitBase with WordSpecLike with Matchers with ImplicitSender with BeforeAndAfterAll { lazy val collectionContext = Kamon.metrics.buildDefaultCollectionContext implicit lazy val system: ActorSystem = { - Kamon.start(config.withFallback(ConfigFactory.load())) + //Kamon.start(config.withFallback(ConfigFactory.load())) ActorSystem(actorSystemName, config) } diff --git a/kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala b/kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala index 280158c0..b84ff2b6 100644 --- a/kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala +++ b/kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala @@ -37,7 +37,7 @@ object SimpleRequestProcessor extends App with SimpleRoutingApp with RequestBuil import scala.concurrent.duration._ - Kamon.start() + //Kamon.start() implicit val system = ActorSystem("test") import test.SimpleRequestProcessor.system.dispatcher diff --git a/project/Settings.scala b/project/Settings.scala index 675d99f2..8f06a665 100644 --- a/project/Settings.scala +++ b/project/Settings.scala @@ -32,8 +32,10 @@ object Settings { crossScalaVersions := Seq("2.10.5", "2.11.6"), resolvers ++= Dependencies.resolutionRepos, fork in run := true, - parallelExecution in Test := false, - testGrouping in Test := singleTestPerJvm((definedTests in Test).value, (javaOptions in Test).value), + //parallelExecution in Test := false, + //testGrouping in Test := singleTestPerJvm((definedTests in Test).value, (javaOptions in Test).value), + javaOptions in Test := Seq( + "-Dkamon.auto-start=true"), javacOptions := Seq( "-Xlint:-options", "-source", JavaVersion, "-target", JavaVersion), -- cgit v1.2.3