diff options
Diffstat (limited to 'kamon-core/src')
11 files changed, 76 insertions, 158 deletions
diff --git a/kamon-core/src/main/resources/reference.conf b/kamon-core/src/main/resources/reference.conf index b3adbe83..fb12b213 100644 --- a/kamon-core/src/main/resources/reference.conf +++ b/kamon-core/src/main/resources/reference.conf @@ -141,6 +141,8 @@ kamon { } } + # FQCN for a implementation of + config-provider = default # All settings included under the internal-config key will be used to repleace the akka.* and spray.* settings. By # doing this we avoid applying custom settings that might make sense for the user application to the internal actor diff --git a/kamon-core/src/main/scala/kamon/Kamon.scala b/kamon-core/src/main/scala/kamon/Kamon.scala index 3c749b3a..54050c18 100644 --- a/kamon-core/src/main/scala/kamon/Kamon.scala +++ b/kamon-core/src/main/scala/kamon/Kamon.scala @@ -16,90 +16,63 @@ package kamon import _root_.akka.actor import _root_.akka.actor._ -import _root_.akka.event.Logging -import com.typesafe.config.{ ConfigFactory, Config } +import com.typesafe.config.{ Config, ConfigFactory } import kamon.metric._ -import kamon.trace.{ TracerModuleImpl, TracerModule } +import kamon.trace.TracerModuleImpl +import org.slf4j.LoggerFactory object Kamon { - trait Extension extends actor.Extension - - 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 + private val log = LoggerFactory.getLogger(getClass) - def start(config: Config): Unit = synchronized { - - def resolveInternalConfig: Config = { - val internalConfig = config.getConfig("kamon.internal-config") - - config - .withoutPath("akka") - .withoutPath("spray") - .withFallback(internalConfig) - } + trait Extension extends actor.Extension - if (_coreComponents.isEmpty) { - val metrics = MetricsModuleImpl(config) - val tracer = TracerModuleImpl(metrics, config) + val config = resolveConfiguration + val metrics = MetricsModuleImpl(config) + val tracer = TracerModuleImpl(metrics, config) - _coreComponents = Some(KamonCoreComponents(metrics, tracer)) - _system = ActorSystem("kamon", resolveInternalConfig) + private lazy val _system = { + val internalConfig = config.getConfig("kamon.internal-config") + val patchedConfig = config + .withoutPath("akka") + .withoutPath("spray") + .withFallback(internalConfig) - metrics.start(_system) - tracer.start(_system) - _system.registerExtension(ModuleLoader) + log.info("Initializing KAMON DUUUDEEE") - } else if (shouldWarnOnDuplicateStart) { - val logger = Logging(_system, "Kamon") - logger.warning("An attempt to start Kamon has been made, but Kamon has already been started.") - } + ActorSystem("kamon", patchedConfig) } - private def isSystemPropertyEnabled(propertyName: String): Boolean = - sys.props.get(propertyName).map(_.equals("true")).getOrElse(false) + private lazy val _start = { + metrics.start(_system) + tracer.start(_system) + _system.registerExtension(ModuleLoader) + } - def start(): Unit = - start(ConfigFactory.load) + def start(): Unit = _start def shutdown(): Unit = { - _coreComponents = None - if (_system ne null) { - _system.shutdown() - _system = null - } + // TODO: Define what a proper shutdown should be like. } - def metrics: MetricsModule = - ifStarted(_.metrics) - - def tracer: TracerModule = - ifStarted(_.tracer) - - 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 apply[T <: Kamon.Extension](key: ExtensionId[T]): T = + key(_system) def extension[T <: Kamon.Extension](key: ExtensionId[T]): T = - apply(key) + apply(key)*/ - private def ifStarted[T](thunk: KamonCoreComponents ⇒ T): T = - _coreComponents.map(thunk(_)) getOrElse { - if (shouldAutoStart) { - start() - thunk(_coreComponents.get) + private def resolveConfiguration: Config = { + val defaultConfig = ConfigFactory.load() - } else sys.error("Kamon has not been started yet. You must either explicitly call Kamon.start(...) or enable " + - "automatic startup by adding -Dkamon.auto-start=true to your JVM options.") + defaultConfig.getString("kamon.config-provider") match { + case "default" ⇒ defaultConfig + case fqcn ⇒ + val dynamic = new ReflectiveDynamicAccess(getClass.getClassLoader) + dynamic.createInstanceFor[ConfigProvider](fqcn, Nil).get.config } + } +} +trait ConfigProvider { + def config: Config } diff --git a/kamon-core/src/main/scala/kamon/ModuleLoader.scala b/kamon-core/src/main/scala/kamon/ModuleLoader.scala index a26fd339..f240f6ce 100644 --- a/kamon-core/src/main/scala/kamon/ModuleLoader.scala +++ b/kamon-core/src/main/scala/kamon/ModuleLoader.scala @@ -21,6 +21,7 @@ import _root_.akka.actor._ import _root_.akka.event.Logging import org.aspectj.lang.ProceedingJoinPoint import org.aspectj.lang.annotation.{ Around, Pointcut, Aspect } +import org.slf4j.LoggerFactory private[kamon] object ModuleLoader extends ExtensionId[ModuleLoaderExtension] with ExtensionIdProvider { def lookup(): ExtensionId[_ <: actor.Extension] = ModuleLoader @@ -28,23 +29,22 @@ private[kamon] object ModuleLoader extends ExtensionId[ModuleLoaderExtension] wi } private[kamon] class ModuleLoaderExtension(system: ExtendedActorSystem) extends Kamon.Extension { - val log = Logging(system, "ModuleLoader") + val log = LoggerFactory.getLogger(getClass) val settings = ModuleLoaderSettings(system) if (settings.modulesRequiringAspectJ.nonEmpty && !isAspectJPresent && settings.showAspectJMissingWarning) logAspectJWeaverMissing(settings.modulesRequiringAspectJ) // Force initialization of all modules marked with auto-start. - settings.availableModules.filter(_.autoStart).foreach { module ⇒ - if (module.extensionClass == "none") - log.debug("Ignoring auto start of the [{}] module with no extension class.", module.name) - else - system.dynamicAccess.getObjectFor[ExtensionId[Kamon.Extension]](module.extensionClass).map { moduleID ⇒ - log.debug("Auto starting the [{}] module.", module.name) + settings.availableModules.filter(_.startInfo.nonEmpty).foreach { + case AvailableModuleInfo(name, requiresAJ, Some(ModuleStartInfo(autoStart, extensionClass))) if autoStart ⇒ + + system.dynamicAccess.getObjectFor[ExtensionId[Kamon.Extension]](extensionClass).map { moduleID ⇒ + log.debug(s"Auto starting the [$name] module.") moduleID.get(system) } recover { - case th: Throwable ⇒ log.error(th, "Failed to auto start the [{}] module.", module.name) + case th: Throwable ⇒ log.error(s"Failed to auto start the [$name] module.", th) } } @@ -82,7 +82,8 @@ private[kamon] class ModuleLoaderExtension(system: ExtendedActorSystem) extends } } -private[kamon] case class AvailableModuleInfo(name: String, extensionClass: String, requiresAspectJ: Boolean, autoStart: Boolean) +private[kamon] case class AvailableModuleInfo(name: String, requiresAspectJ: Boolean, startInfo: Option[ModuleStartInfo]) +private[kamon] case class ModuleStartInfo(autoStart: Boolean, extensionClass: String) private[kamon] case class ModuleLoaderSettings(showAspectJMissingWarning: Boolean, availableModules: List[AvailableModuleInfo]) { val modulesRequiringAspectJ = availableModules.filter(_.requiresAspectJ) } @@ -98,12 +99,15 @@ private[kamon] object ModuleLoaderSettings { val modules = config.firstLevelKeys val availableModules = modules.map { moduleName ⇒ val moduleConfig = config.getConfig(moduleName) + val requiresAspectJ = moduleConfig.getBoolean("requires-aspectj") + + val startInfo = + if (moduleConfig.hasPath("auto-start") && moduleConfig.hasPath("extension-class")) + Some(ModuleStartInfo(moduleConfig.getBoolean("auto-start"), moduleConfig.getString("extension-class"))) + else + None - AvailableModuleInfo( - moduleName, - moduleConfig.getString("extension-id"), - moduleConfig.getBoolean("requires-aspectj"), - moduleConfig.getBoolean("auto-start")) + AvailableModuleInfo(moduleName, requiresAspectJ, startInfo) } toList diff --git a/kamon-core/src/test/resources/application.conf b/kamon-core/src/test/resources/application.conf index e8217fc2..f79ab822 100644 --- a/kamon-core/src/test/resources/application.conf +++ b/kamon-core/src/test/resources/application.conf @@ -1,3 +1,15 @@ akka { loggers = ["akka.event.slf4j.Slf4jLogger"] +} + +kamon { + metric { + tick-interval = 1 hour + default-collection-context-buffer-size = 100 + } + + trace { + level-of-detail = simple-trace + sampling = all + } }
\ No newline at end of file diff --git a/kamon-core/src/test/resources/logback.xml b/kamon-core/src/test/resources/logback.xml index dd623d61..b467456f 100644 --- a/kamon-core/src/test/resources/logback.xml +++ b/kamon-core/src/test/resources/logback.xml @@ -1,17 +1,12 @@ -<configuration scan="true"> - <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"> - <resetJUL>true</resetJUL> - </contextListener> - - <conversionRule conversionWord="traceToken" converterClass="kamon.trace.logging.LogbackTraceTokenConverter"/> - +<configuration> + <statusListener class="ch.qos.logback.core.status.NopStatusListener"/> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> - <pattern>%date{HH:mm:ss.SSS} %-5level [%traceToken][%thread] %logger{55} - %msg%n</pattern> + <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> - <root level="error"> + <root level="OFF"> <appender-ref ref="STDOUT"/> </root> -</configuration> +</configuration>
\ No newline at end of file diff --git a/kamon-core/src/test/scala/kamon/metric/SimpleMetricsSpec.scala b/kamon-core/src/test/scala/kamon/metric/SimpleMetricsSpec.scala index 0180e980..6d753888 100644 --- a/kamon-core/src/test/scala/kamon/metric/SimpleMetricsSpec.scala +++ b/kamon-core/src/test/scala/kamon/metric/SimpleMetricsSpec.scala @@ -16,21 +16,12 @@ 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._ class SimpleMetricsSpec extends BaseKamonSpec("simple-metrics-spec") { - override lazy val config = - ConfigFactory.parseString( - """ - |kamon.metric { - | tick-interval = 1 hour - | default-collection-context-buffer-size = 10 - |} - """.stripMargin) "the SimpleMetrics extension" should { diff --git a/kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala b/kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala index ac35cf58..97bf0e2c 100644 --- a/kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala +++ b/kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala @@ -26,21 +26,6 @@ import scala.concurrent.duration._ import kamon.metric.SubscriptionsDispatcher.TickMetricSnapshot class TickMetricSnapshotBufferSpec extends BaseKamonSpec("trace-metrics-spec") with ImplicitSender { - override lazy val config = - ConfigFactory.parseString( - """ - |kamon.metric { - | tick-interval = 1 hour - | default-collection-context-buffer-size = 10 - | - | filters { - | trace { - | includes = [ "*" ] - | excludes = [ "non-tracked-trace" ] - | } - | } - |} - """.stripMargin) "the TickMetricSnapshotBuffer" should { "merge TickMetricSnapshots received until the flush timeout is reached and fix the from/to fields" in new SnapshotFixtures { diff --git a/kamon-core/src/test/scala/kamon/metric/TraceMetricsSpec.scala b/kamon-core/src/test/scala/kamon/metric/TraceMetricsSpec.scala index efdcb79b..3e3e2d8e 100644 --- a/kamon-core/src/test/scala/kamon/metric/TraceMetricsSpec.scala +++ b/kamon-core/src/test/scala/kamon/metric/TraceMetricsSpec.scala @@ -23,21 +23,6 @@ import kamon.trace.Tracer import kamon.metric.instrument.Histogram class TraceMetricsSpec extends BaseKamonSpec("trace-metrics-spec") with ImplicitSender { - override lazy val config = - ConfigFactory.parseString( - """ - |kamon.metric { - | tick-interval = 1 hour - | default-collection-context-buffer-size = 10 - | - | filters { - | trace { - | includes = [ "*" ] - | excludes = [ "non-tracked-trace"] - | } - | } - |} - """.stripMargin) "the TraceMetrics" should { "record the elapsed time between a trace creation and finish" in { diff --git a/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala b/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala index cb909ad9..f23d974c 100644 --- a/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala +++ b/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala @@ -28,12 +28,12 @@ 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() ActorSystem(actorSystemName, config) } def config: Config = - ConfigFactory.empty() + Kamon.config def newContext(name: String): TraceContext = Kamon.tracer.newContext(name) diff --git a/kamon-core/src/test/scala/kamon/trace/SimpleTraceSpec.scala b/kamon-core/src/test/scala/kamon/trace/SimpleTraceSpec.scala index c8f1ebf6..d6886d4c 100644 --- a/kamon-core/src/test/scala/kamon/trace/SimpleTraceSpec.scala +++ b/kamon-core/src/test/scala/kamon/trace/SimpleTraceSpec.scala @@ -23,21 +23,6 @@ import scala.concurrent.duration._ class SimpleTraceSpec extends BaseKamonSpec("simple-trace-spec") { - override lazy val config = - ConfigFactory.parseString( - """ - |kamon { - | metric { - | tick-interval = 1 hour - | } - | - | trace { - | level-of-detail = simple-trace - | sampling = all - | } - |} - """.stripMargin) - "the simple tracing" should { "send a TraceInfo when the trace has finished and all segments are finished" in { Kamon.tracer.subscribe(testActor) diff --git a/kamon-core/src/test/scala/kamon/trace/TraceContextManipulationSpec.scala b/kamon-core/src/test/scala/kamon/trace/TraceContextManipulationSpec.scala index 46620461..ecef9271 100644 --- a/kamon-core/src/test/scala/kamon/trace/TraceContextManipulationSpec.scala +++ b/kamon-core/src/test/scala/kamon/trace/TraceContextManipulationSpec.scala @@ -20,20 +20,6 @@ import com.typesafe.config.ConfigFactory import kamon.testkit.BaseKamonSpec class TraceContextManipulationSpec extends BaseKamonSpec("trace-metrics-spec") { - override lazy val config = - ConfigFactory.parseString( - """ - |kamon.metric { - | tick-interval = 1 hour - | - | filters { - | trace { - | includes = [ "*" ] - | excludes = [ "non-tracked-trace"] - | } - | } - |} - """.stripMargin) "the TraceContext api" should { "allow starting a trace within a specified block of code, and only within that block of code" in { |