aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Topolnjak <ivantopo@gmail.com>2015-03-05 23:39:44 +0100
committerIvan Topolnjak <ivantopo@gmail.com>2015-03-09 23:09:08 +0100
commit959ce3573253ec4ac5b837d8a9c9e70f1f80bd6b (patch)
tree27c1fe8f22429fe3820f988ab17caaf8e4a6fa3a
parent69ea63923e0d3697f8ca4c7eb9cb808821832aa2 (diff)
downloadKamon-959ce3573253ec4ac5b837d8a9c9e70f1f80bd6b.tar.gz
Kamon-959ce3573253ec4ac5b837d8a9c9e70f1f80bd6b.tar.bz2
Kamon-959ce3573253ec4ac5b837d8a9c9e70f1f80bd6b.zip
! all: introduced support for metric tags.
-rw-r--r--kamon-akka/src/main/scala/kamon/akka/instrumentation/ActorCellInstrumentation.scala21
-rw-r--r--kamon-akka/src/main/scala/kamon/akka/instrumentation/DispatcherInstrumentation.scala12
-rw-r--r--kamon-akka/src/test/scala/kamon/akka/ActorMetricsSpec.scala4
-rw-r--r--kamon-akka/src/test/scala/kamon/akka/DispatcherMetricsSpec.scala1
-rw-r--r--kamon-akka/src/test/scala/kamon/akka/RouterMetricsSpec.scala6
-rw-r--r--kamon-akka/src/test/scala/kamon/akka/instrumentation/ActorLoggingInstrumentationSpec.scala2
-rw-r--r--kamon-akka/src/test/scala/kamon/akka/instrumentation/ActorSystemMessageInstrumentationSpec.scala2
-rw-r--r--kamon-akka/src/test/scala/kamon/akka/instrumentation/AskPatternInstrumentationSpec.scala2
-rw-r--r--kamon-annotation/src/main/scala/kamon/annotation/instrumentation/BaseAnnotationInstrumentation.scala8
-rw-r--r--kamon-annotation/src/test/scala/kamon/annotation/AnnotationInstrumentationSpec.scala93
-rw-r--r--kamon-annotation/src/test/scala/kamon/annotation/StaticAnnotationInstrumentationJavaSpec.scala74
-rw-r--r--kamon-annotation/src/test/scala/kamon/annotation/StaticAnnotationInstrumentationSpec.scala92
-rw-r--r--kamon-core/src/main/scala/kamon/Kamon.scala12
-rw-r--r--kamon-core/src/main/scala/kamon/metric/Entity.scala27
-rw-r--r--kamon-core/src/main/scala/kamon/metric/EntityRecorder.scala103
-rw-r--r--kamon-core/src/main/scala/kamon/metric/MetricKey.scala120
-rw-r--r--kamon-core/src/main/scala/kamon/metric/Metrics.scala269
-rw-r--r--kamon-core/src/main/scala/kamon/metric/SimpleMetrics.scala204
-rw-r--r--kamon-core/src/main/scala/kamon/metric/TraceMetrics.scala27
-rw-r--r--kamon-core/src/main/scala/kamon/metric/instrument/Gauge.scala4
-rw-r--r--kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala26
-rw-r--r--kamon-core/src/main/scala/kamon/trace/Tracer.scala4
-rw-r--r--kamon-core/src/main/scala/kamon/trace/TracingContext.scala5
-rw-r--r--kamon-core/src/main/scala/kamon/util/FunctionalInterfaces.scala9
-rw-r--r--kamon-core/src/test/scala/kamon/metric/SimpleMetricsSpec.scala74
-rw-r--r--kamon-core/src/test/scala/kamon/metric/SubscriptionsProtocolSpec.scala20
-rw-r--r--kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala14
-rw-r--r--kamon-core/src/test/scala/kamon/metric/TraceMetricsSpec.scala42
-rw-r--r--kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala7
-rw-r--r--kamon-datadog/src/main/scala/kamon/datadog/DatadogMetricsSender.scala15
-rw-r--r--kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala22
-rw-r--r--kamon-jdbc/src/main/scala/kamon/jdbc/instrumentation/StatementInstrumentation.scala17
-rw-r--r--kamon-jdbc/src/test/scala/kamon/jdbc/instrumentation/StatementInstrumentationSpec.scala42
-rw-r--r--kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala17
-rw-r--r--kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetricExtractor.scala51
-rw-r--r--kamon-newrelic/src/test/scala/kamon/newrelic/MetricReporterSpec.scala14
-rw-r--r--kamon-play/src/main/scala/kamon/play/Play.scala8
-rw-r--r--kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala38
-rw-r--r--kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala2
-rw-r--r--kamon-spray/src/main/scala/kamon/spray/SprayExtension.scala5
-rw-r--r--kamon-spray/src/test/scala/kamon/spray/ClientRequestInstrumentationSpec.scala32
-rw-r--r--kamon-statsd/src/test/scala/kamon/statsd/SimpleMetricKeyGeneratorSpec.scala2
-rw-r--r--kamon-statsd/src/test/scala/kamon/statsd/StatsDMetricSenderSpec.scala4
-rw-r--r--kamon-system-metrics/src/main/scala/kamon/system/custom/ContextSwitchesMetrics.scala4
-rw-r--r--kamon-system-metrics/src/main/scala/kamon/system/jmx/GarbageCollectionMetrics.scala7
-rw-r--r--kamon-system-metrics/src/main/scala/kamon/system/jmx/JmxSystemMetricRecorderCompanion.scala8
-rw-r--r--kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarMetricsUpdater.scala8
-rw-r--r--project/Settings.scala1
48 files changed, 783 insertions, 798 deletions
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 4783484f..d1d420fe 100644
--- a/kamon-akka/src/main/scala/kamon/akka/instrumentation/ActorCellInstrumentation.scala
+++ b/kamon-akka/src/main/scala/kamon/akka/instrumentation/ActorCellInstrumentation.scala
@@ -34,11 +34,14 @@ 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 = {
- Kamon.metrics.register(ActorMetrics, ref.path.elements.mkString("/")).map { registration ⇒
+ val actorEntity = Entity(ref.path.elements.mkString("/"), ActorMetrics.category)
+
+ if (Kamon.metrics.shouldTrack(actorEntity)) {
+ val actorMetricsRecorder = Kamon.metrics.entity(ActorMetrics, actorEntity)
val cellMetrics = cell.asInstanceOf[ActorCellMetrics]
- cellMetrics.entity = registration.entity
- cellMetrics.recorder = Some(registration.recorder)
+ cellMetrics.entity = actorEntity
+ cellMetrics.recorder = Some(actorMetricsRecorder)
}
}
@@ -90,14 +93,14 @@ class ActorCellInstrumentation {
def afterStop(cell: ActorCell): Unit = {
val cellMetrics = cell.asInstanceOf[ActorCellMetrics]
cellMetrics.recorder.map { _ ⇒
- Kamon.metrics.unregister(cellMetrics.entity)
+ Kamon.metrics.removeEntity(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 { _ ⇒
- Kamon.metrics.unregister(routedCellMetrics.routerEntity)
+ Kamon.metrics.removeEntity(routedCellMetrics.routerEntity)
}
}
}
@@ -124,11 +127,13 @@ 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 = {
- Kamon.metrics.register(RouterMetrics, ref.path.elements.mkString("/")).map { registration ⇒
+ val routerEntity = Entity(ref.path.elements.mkString("/"), RouterMetrics.category)
+
+ if (Kamon.metrics.shouldTrack(routerEntity)) {
val cellMetrics = cell.asInstanceOf[RoutedActorCellMetrics]
- cellMetrics.routerEntity = registration.entity
- cellMetrics.routerRecorder = Some(registration.recorder)
+ cellMetrics.routerEntity = routerEntity
+ cellMetrics.routerRecorder = Some(Kamon.metrics.entity(RouterMetrics, routerEntity))
}
}
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 7b15c443..eb6b5293 100644
--- a/kamon-akka/src/main/scala/kamon/akka/instrumentation/DispatcherInstrumentation.scala
+++ b/kamon-akka/src/main/scala/kamon/akka/instrumentation/DispatcherInstrumentation.scala
@@ -59,10 +59,16 @@ class DispatcherInstrumentation {
private def registerDispatcher(dispatcherName: String, executorService: ExecutorService, system: ActorSystem): Unit =
executorService match {
case fjp: AkkaForkJoinPool ⇒
- Kamon.metrics.register(ForkJoinPoolDispatcherMetrics.factory(fjp), dispatcherName)
+ val dispatcherEntity = Entity(dispatcherName, AkkaDispatcherMetrics.Category)
+
+ if (Kamon.metrics.shouldTrack(dispatcherEntity))
+ Kamon.metrics.entity(ForkJoinPoolDispatcherMetrics.factory(fjp), dispatcherName)
case tpe: ThreadPoolExecutor ⇒
- Kamon.metrics.register(ThreadPoolExecutorDispatcherMetrics.factory(tpe), dispatcherName)
+ val dispatcherEntity = Entity(dispatcherName, AkkaDispatcherMetrics.Category)
+
+ if (Kamon.metrics.shouldTrack(dispatcherEntity))
+ Kamon.metrics.entity(ThreadPoolExecutorDispatcherMetrics.factory(tpe), dispatcherName)
case others ⇒ // Currently not interested in other kinds of dispatchers.
}
@@ -120,7 +126,7 @@ class DispatcherInstrumentation {
import lazyExecutor.lookupData
if (lookupData.actorSystem != null)
- Kamon.metrics.unregister(Entity(lookupData.dispatcherName, AkkaDispatcherMetrics.Category))
+ Kamon.metrics.removeEntity(Entity(lookupData.dispatcherName, AkkaDispatcherMetrics.Category))
}
}
diff --git a/kamon-akka/src/test/scala/kamon/akka/ActorMetricsSpec.scala b/kamon-akka/src/test/scala/kamon/akka/ActorMetricsSpec.scala
index 19a71053..f4db8b8c 100644
--- a/kamon-akka/src/test/scala/kamon/akka/ActorMetricsSpec.scala
+++ b/kamon-akka/src/test/scala/kamon/akka/ActorMetricsSpec.scala
@@ -151,7 +151,7 @@ class ActorMetricsSpec extends BaseKamonSpec("actor-metrics-spec") {
trackedActor ! PoisonPill
deathWatcher.expectTerminated(trackedActor)
- actorMetricsRecorderOf(trackedActor).get shouldNot be theSameInstanceAs (firstRecorder)
+ actorMetricsRecorderOf(trackedActor) shouldBe empty
}
}
@@ -165,7 +165,7 @@ class ActorMetricsSpec extends BaseKamonSpec("actor-metrics-spec") {
def actorRecorderName(ref: ActorRef): String = ref.path.elements.mkString("/")
def actorMetricsRecorderOf(ref: ActorRef): Option[ActorMetrics] =
- Kamon.metrics.register(ActorMetrics, actorRecorderName(ref)).map(_.recorder)
+ Kamon.metrics.find(actorRecorderName(ref), ActorMetrics.category).map(_.asInstanceOf[ActorMetrics])
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/akka/DispatcherMetricsSpec.scala b/kamon-akka/src/test/scala/kamon/akka/DispatcherMetricsSpec.scala
index 2379bff5..dd5cfa45 100644
--- a/kamon-akka/src/test/scala/kamon/akka/DispatcherMetricsSpec.scala
+++ b/kamon-akka/src/test/scala/kamon/akka/DispatcherMetricsSpec.scala
@@ -15,7 +15,6 @@
package kamon.akka
-
import akka.actor.ActorRef
import akka.dispatch.MessageDispatcher
import akka.testkit.TestProbe
diff --git a/kamon-akka/src/test/scala/kamon/akka/RouterMetricsSpec.scala b/kamon-akka/src/test/scala/kamon/akka/RouterMetricsSpec.scala
index ec55648b..41c329d6 100644
--- a/kamon-akka/src/test/scala/kamon/akka/RouterMetricsSpec.scala
+++ b/kamon-akka/src/test/scala/kamon/akka/RouterMetricsSpec.scala
@@ -180,7 +180,7 @@ class RouterMetricsSpec extends BaseKamonSpec("router-metrics-spec") {
trackedRouter ! PoisonPill
deathWatcher.expectTerminated(trackedRouter)
- routerMetricsRecorderOf("user/stop-in-pool-router").get shouldNot be theSameInstanceAs (firstRecorder)
+ routerMetricsRecorderOf("user/stop-in-pool-router") shouldBe empty
}
"clean up the associated recorder when the group router is stopped" in new RouterMetricsFixtures {
@@ -193,7 +193,7 @@ class RouterMetricsSpec extends BaseKamonSpec("router-metrics-spec") {
trackedRouter ! PoisonPill
deathWatcher.expectTerminated(trackedRouter)
- routerMetricsRecorderOf("user/stop-in-group-router").get shouldNot be theSameInstanceAs (firstRecorder)
+ routerMetricsRecorderOf("user/stop-in-group-router") shouldBe empty
}
}
@@ -205,7 +205,7 @@ class RouterMetricsSpec extends BaseKamonSpec("router-metrics-spec") {
}
def routerMetricsRecorderOf(routerName: String): Option[RouterMetrics] =
- Kamon.metrics.register(RouterMetrics, routerName).map(_.recorder)
+ Kamon.metrics.find(routerName, RouterMetrics.category).map(_.asInstanceOf[RouterMetrics])
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/ActorLoggingInstrumentationSpec.scala b/kamon-akka/src/test/scala/kamon/akka/instrumentation/ActorLoggingInstrumentationSpec.scala
index 42a26cdd..85f41795 100644
--- a/kamon-akka/src/test/scala/kamon/akka/instrumentation/ActorLoggingInstrumentationSpec.scala
+++ b/kamon-akka/src/test/scala/kamon/akka/instrumentation/ActorLoggingInstrumentationSpec.scala
@@ -21,7 +21,7 @@ import com.typesafe.config.ConfigFactory
import kamon.testkit.BaseKamonSpec
import kamon.trace.TraceLocal.AvailableToMdc
import kamon.trace.logging.MdcKeysSupport
-import kamon.trace.{Tracer, TraceContextAware, TraceLocal}
+import kamon.trace.{ Tracer, TraceContextAware, TraceLocal }
import org.scalatest.Inspectors
import org.slf4j.MDC
diff --git a/kamon-akka/src/test/scala/kamon/akka/instrumentation/ActorSystemMessageInstrumentationSpec.scala b/kamon-akka/src/test/scala/kamon/akka/instrumentation/ActorSystemMessageInstrumentationSpec.scala
index fd9f58d0..1635fadc 100644
--- a/kamon-akka/src/test/scala/kamon/akka/instrumentation/ActorSystemMessageInstrumentationSpec.scala
+++ b/kamon-akka/src/test/scala/kamon/akka/instrumentation/ActorSystemMessageInstrumentationSpec.scala
@@ -21,7 +21,7 @@ import akka.actor._
import akka.testkit.ImplicitSender
import com.typesafe.config.ConfigFactory
import kamon.testkit.BaseKamonSpec
-import kamon.trace.{Tracer, EmptyTraceContext}
+import kamon.trace.{ Tracer, EmptyTraceContext }
import org.scalatest.WordSpecLike
import scala.concurrent.duration._
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 a44945ea..4268e53d 100644
--- a/kamon-akka/src/test/scala/kamon/akka/instrumentation/AskPatternInstrumentationSpec.scala
+++ b/kamon-akka/src/test/scala/kamon/akka/instrumentation/AskPatternInstrumentationSpec.scala
@@ -27,7 +27,7 @@ import com.typesafe.config.ConfigFactory
import kamon.Kamon
import kamon.akka.Akka
import kamon.testkit.BaseKamonSpec
-import kamon.trace.{Tracer, TraceContext, TraceContextAware}
+import kamon.trace.{ Tracer, TraceContext, TraceContextAware }
import scala.concurrent.duration._
diff --git a/kamon-annotation/src/main/scala/kamon/annotation/instrumentation/BaseAnnotationInstrumentation.scala b/kamon-annotation/src/main/scala/kamon/annotation/instrumentation/BaseAnnotationInstrumentation.scala
index 57e8c4d7..2074e237 100644
--- a/kamon-annotation/src/main/scala/kamon/annotation/instrumentation/BaseAnnotationInstrumentation.scala
+++ b/kamon-annotation/src/main/scala/kamon/annotation/instrumentation/BaseAnnotationInstrumentation.scala
@@ -39,7 +39,7 @@ class BaseAnnotationInstrumentation {
val time = method.getAnnotation(classOf[Time])
val name = evalString(time.name())
val tags = evalTags(time.tags())
- val currentHistogram = Kamon.simpleMetrics.histogram(HistogramKey(name, tags))
+ val currentHistogram = Kamon.metrics.histogram(name, tags)
histograms.set(jps.getId, currentHistogram)
currentHistogram
}
@@ -50,7 +50,7 @@ class BaseAnnotationInstrumentation {
val name = evalString(histogram.name())
val tags = evalTags(histogram.tags())
val dynamicRange = DynamicRange(histogram.lowestDiscernibleValue(), histogram.highestTrackableValue(), histogram.precision())
- val currentHistogram = Kamon.simpleMetrics.histogram(HistogramKey(name, tags), dynamicRange)
+ val currentHistogram = Kamon.metrics.histogram(name, tags, dynamicRange)
histograms.set(jps.getId, currentHistogram)
currentHistogram
}
@@ -60,7 +60,7 @@ class BaseAnnotationInstrumentation {
val minMaxCount = method.getAnnotation(classOf[MinMaxCount])
val name = evalString(minMaxCount.name())
val tags = evalTags(minMaxCount.tags())
- val minMaxCounter = Kamon.simpleMetrics.minMaxCounter(MinMaxCounterKey(name, tags))
+ val minMaxCounter = Kamon.metrics.minMaxCounter(name, tags)
minMaxCounters.set(jps.getId, minMaxCounter)
minMaxCounter
}
@@ -70,7 +70,7 @@ class BaseAnnotationInstrumentation {
val count = method.getAnnotation(classOf[Count])
val name = evalString(count.name())
val tags = evalTags(count.tags())
- val counter = Kamon.simpleMetrics.counter(CounterKey(name, tags))
+ val counter = Kamon.metrics.counter(name, tags)
counters.set(jps.getId, counter)
counter
}
diff --git a/kamon-annotation/src/test/scala/kamon/annotation/AnnotationInstrumentationSpec.scala b/kamon-annotation/src/test/scala/kamon/annotation/AnnotationInstrumentationSpec.scala
index 41f0fc34..3d94d246 100644
--- a/kamon-annotation/src/test/scala/kamon/annotation/AnnotationInstrumentationSpec.scala
+++ b/kamon-annotation/src/test/scala/kamon/annotation/AnnotationInstrumentationSpec.scala
@@ -19,10 +19,9 @@ package kamon.annotation
import com.typesafe.config.ConfigFactory
import kamon.metric._
import kamon.testkit.BaseKamonSpec
+import kamon.trace.SegmentCategory
class AnnotationInstrumentationSpec extends BaseKamonSpec("annotation-instrumentation-spec") {
- import kamon.metric.TraceMetricsSpec.SegmentSyntax
-
override lazy val config =
ConfigFactory.parseString(
"""
@@ -38,7 +37,6 @@ class AnnotationInstrumentationSpec extends BaseKamonSpec("annotation-instrument
val snapshot = takeSnapshotOf("trace", "trace")
snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(10)
- snapshot.segments.size should be(0)
}
"create a segment when is invoked a method annotated with @Segment" in {
@@ -47,8 +45,13 @@ class AnnotationInstrumentationSpec extends BaseKamonSpec("annotation-instrument
val snapshot = takeSnapshotOf("trace-with-segment", "trace")
snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(10)
- snapshot.segments.size should be(1)
- snapshot.segment("inner-segment", "inner", "segment") should not be empty
+ val segmentMetricsSnapshot = takeSnapshotOf("inner-segment", "trace-segment",
+ tags = Map(
+ "trace" -> "trace-with-segment",
+ "category" -> "inner",
+ "library" -> "segment"))
+
+ segmentMetricsSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(10)
}
"create a segment when is invoked a method annotated with @Segment and evaluate EL expressions" in {
@@ -57,28 +60,30 @@ class AnnotationInstrumentationSpec extends BaseKamonSpec("annotation-instrument
val snapshot = takeSnapshotOf("trace-with-segment-el", "trace")
snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(10)
- snapshot.segments.size should be(10)
- snapshot.segment("inner-segment:1", "inner", "segment") should not be empty
+ val segmentMetricsSnapshot = takeSnapshotOf("inner-segment:1", "trace-segment",
+ tags = Map(
+ "trace" -> "trace-with-segment-el",
+ "category" -> "inner",
+ "library" -> "segment"))
+
+ segmentMetricsSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
}
"count the invocations of a method annotated with @Count" in {
for (id ← 1 to 10) Annotated(id).count()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.counter("count").get.count should be(10)
+ val snapshot = takeSnapshotOf("count", "counter")
+ snapshot.counter("counter").get.count should be(10)
}
"count the invocations of a method annotated with @Count and evaluate EL expressions" in {
for (id ← 1 to 2) Annotated(id).countWithEL()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.counter("count:1").get.count should be(1)
- snapshot.counter("count:2").get.count should be(1)
+ val counter1Snapshot = takeSnapshotOf("count:1", "counter", Map("counter" -> "1", "env" -> "prod"))
+ counter1Snapshot.counter("counter").get.count should be(1)
- val counterKey = (name: String) ⇒ (key: CounterKey) ⇒ key.name == name
-
- snapshot.counters.keys.find(counterKey("count:1")).get.metadata should be(Map("counter" -> "1", "env" -> "prod"))
- snapshot.counters.keys.find(counterKey("count:2")).get.metadata should be(Map("counter" -> "1", "env" -> "prod"))
+ val counter2Snapshot = takeSnapshotOf("count:2", "counter", Map("counter" -> "1", "env" -> "prod"))
+ counter2Snapshot.counter("counter").get.count should be(1)
}
"count the current invocations of a method annotated with @MinMaxCount" in {
@@ -86,45 +91,38 @@ class AnnotationInstrumentationSpec extends BaseKamonSpec("annotation-instrument
Annotated(id).countMinMax()
}
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.minMaxCounter("minMax").get.max should be(1)
+ val snapshot = takeSnapshotOf("minMax", "min-max-counter")
+ snapshot.minMaxCounter("min-max-counter").get.max should be(1)
}
"count the current invocations of a method annotated with @MinMaxCount and evaluate EL expressions" in {
for (id ← 1 to 10) Annotated(id).countMinMaxWithEL()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.minMaxCounter("minMax:1").get.sum should be(1)
- snapshot.minMaxCounter("minMax:2").get.sum should be(1)
-
- val minMaxKey = (name: String) ⇒ (key: MinMaxCounterKey) ⇒ key.name == name
+ val minMaxCounter1Snapshot = takeSnapshotOf("minMax:1", "min-max-counter", tags = Map("minMax" -> "1", "env" -> "dev"))
+ minMaxCounter1Snapshot.minMaxCounter("min-max-counter").get.sum should be(1)
- snapshot.minMaxCounters.keys.find(minMaxKey("minMax:1")).get.metadata should be(Map("minMax" -> "1", "env" -> "dev"))
- snapshot.minMaxCounters.keys.find(minMaxKey("minMax:2")).get.metadata should be(Map("minMax" -> "1", "env" -> "dev"))
+ val minMaxCounter2Snapshot = takeSnapshotOf("minMax:2", "min-max-counter", tags = Map("minMax" -> "1", "env" -> "dev"))
+ minMaxCounter2Snapshot.minMaxCounter("min-max-counter").get.sum should be(1)
}
"measure the time spent in the execution of a method annotated with @Time" in {
for (id ← 1 to 1) Annotated(id).time()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.histogram("time").get.numberOfMeasurements should be(1)
+ val snapshot = takeSnapshotOf("time", "histogram")
+ snapshot.histogram("histogram").get.numberOfMeasurements should be(1)
}
"measure the time spent in the execution of a method annotated with @Time and evaluate EL expressions" in {
for (id ← 1 to 1) Annotated(id).timeWithEL()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.histogram("time:1").get.numberOfMeasurements should be(1)
-
- val histogramKey = (name: String) ⇒ (key: HistogramKey) ⇒ key.name == name
-
- snapshot.histograms.keys.find(histogramKey("time:1")).get.metadata should be(Map("slow-service" -> "service", "env" -> "prod"))
+ val snapshot = takeSnapshotOf("time:1", "histogram", tags = Map("slow-service" -> "service", "env" -> "prod"))
+ snapshot.histogram("histogram").get.numberOfMeasurements should be(1)
}
"record the value returned by a method annotated with @Histogram" in {
for (value ← 1 to 5) Annotated().histogram(value)
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
+ val snapshot = takeSnapshotOf("histogram", "histogram")
snapshot.histogram("histogram").get.numberOfMeasurements should be(5)
snapshot.histogram("histogram").get.min should be(1)
snapshot.histogram("histogram").get.max should be(5)
@@ -134,23 +132,18 @@ class AnnotationInstrumentationSpec extends BaseKamonSpec("annotation-instrument
"record the value returned by a method annotated with @Histogram and evaluate EL expressions" in {
for (value ← 1 to 2) Annotated(value).histogramWithEL(value)
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.histogram("histogram:1").get.numberOfMeasurements should be(1)
- snapshot.histogram("histogram:1").get.min should be(1)
- snapshot.histogram("histogram:1").get.max should be(1)
- snapshot.histogram("histogram:1").get.sum should be(1)
-
- snapshot.histogram("histogram:2").get.numberOfMeasurements should be(1)
- snapshot.histogram("histogram:2").get.min should be(2)
- snapshot.histogram("histogram:2").get.max should be(2)
- snapshot.histogram("histogram:2").get.sum should be(2)
-
- val histogramKey = (name: String) ⇒ (key: HistogramKey) ⇒ key.name == name
-
- snapshot.histograms.keys.find(histogramKey("histogram:1")).get.metadata should be(Map("histogram" -> "hdr", "env" -> "prod"))
- snapshot.histograms.keys.find(histogramKey("histogram:2")).get.metadata should be(Map("histogram" -> "hdr", "env" -> "prod"))
+ val snapshot1 = takeSnapshotOf("histogram:1", "histogram", tags = Map("histogram" -> "hdr", "env" -> "prod"))
+ snapshot1.histogram("histogram").get.numberOfMeasurements should be(1)
+ snapshot1.histogram("histogram").get.min should be(1)
+ snapshot1.histogram("histogram").get.max should be(1)
+ snapshot1.histogram("histogram").get.sum should be(1)
+
+ val snapshot2 = takeSnapshotOf("histogram:2", "histogram", tags = Map("histogram" -> "hdr", "env" -> "prod"))
+ snapshot2.histogram("histogram").get.numberOfMeasurements should be(1)
+ snapshot2.histogram("histogram").get.min should be(2)
+ snapshot2.histogram("histogram").get.max should be(2)
+ snapshot2.histogram("histogram").get.sum should be(2)
}
-
}
}
diff --git a/kamon-annotation/src/test/scala/kamon/annotation/StaticAnnotationInstrumentationJavaSpec.scala b/kamon-annotation/src/test/scala/kamon/annotation/StaticAnnotationInstrumentationJavaSpec.scala
index 4bae9f1d..6e0fbd02 100644
--- a/kamon-annotation/src/test/scala/kamon/annotation/StaticAnnotationInstrumentationJavaSpec.scala
+++ b/kamon-annotation/src/test/scala/kamon/annotation/StaticAnnotationInstrumentationJavaSpec.scala
@@ -21,8 +21,6 @@ import kamon.metric.{ HistogramKey, MinMaxCounterKey, CounterKey }
import kamon.testkit.BaseKamonSpec
class StaticAnnotationInstrumentationJavaSpec extends BaseKamonSpec("static-annotation-instrumentation-java-spec") {
- import kamon.metric.TraceMetricsSpec.SegmentSyntax
-
override lazy val config =
ConfigFactory.parseString(
"""
@@ -38,16 +36,17 @@ class StaticAnnotationInstrumentationJavaSpec extends BaseKamonSpec("static-anno
val snapshot = takeSnapshotOf("trace", "trace")
snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(10)
- snapshot.segments.size should be(0)
}
"create a segment when is invoked a static method annotated with @Segment" in {
- for (id ← 1 to 10) AnnotatedJavaClass.segment()
+ for (id ← 1 to 7) AnnotatedJavaClass.segment()
- val snapshot = takeSnapshotOf("trace-with-segment", "trace")
- snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(10)
+ val segmentMetricsSnapshot = takeSnapshotOf("inner-segment", "trace-segment",
+ tags = Map(
+ "trace" -> "trace-with-segment",
+ "category" -> "inner",
+ "library" -> "segment"))
- snapshot.segments.size should be(1)
- snapshot.segment("inner-segment", "inner", "segment") should not be empty
+ segmentMetricsSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(7)
}
"create a segment when is invoked a static method annotated with @Segment and evaluate EL expressions" in {
@@ -56,26 +55,27 @@ class StaticAnnotationInstrumentationJavaSpec extends BaseKamonSpec("static-anno
val snapshot = takeSnapshotOf("trace-with-segment-el", "trace")
snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(10)
- snapshot.segments.size should be(1)
- snapshot.segment("inner-segment:10", "segments", "segment") should not be empty
+ val segmentMetricsSnapshot = takeSnapshotOf("inner-segment:10", "trace-segment",
+ tags = Map(
+ "trace" -> "trace-with-segment-el",
+ "category" -> "segments",
+ "library" -> "segment"))
+
+ segmentMetricsSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(10)
}
"count the invocations of a static method annotated with @Count" in {
for (id ← 1 to 10) AnnotatedJavaClass.count()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.counter("count").get.count should be(10)
+ val snapshot = takeSnapshotOf("count", "counter")
+ snapshot.counter("counter").get.count should be(10)
}
"count the invocations of a static method annotated with @Count and evaluate EL expressions" in {
for (id ← 1 to 2) AnnotatedJavaClass.countWithEL()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.counter("count:10").get.count should be(2)
-
- val counterKey = (name: String) ⇒ (key: CounterKey) ⇒ key.name == name
-
- snapshot.counters.keys.find(counterKey("count:10")).get.metadata should be(Map("counter" -> "1", "env" -> "prod"))
+ val snapshot = takeSnapshotOf("count:10", "counter", tags = Map("counter" -> "1", "env" -> "prod"))
+ snapshot.counter("counter").get.count should be(2)
}
"count the current invocations of a static method annotated with @MinMaxCount" in {
@@ -83,43 +83,35 @@ class StaticAnnotationInstrumentationJavaSpec extends BaseKamonSpec("static-anno
AnnotatedJavaClass.countMinMax()
}
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.minMaxCounter("minMax").get.max should be(1)
+ val snapshot = takeSnapshotOf("minMax", "min-max-counter")
+ snapshot.minMaxCounter("min-max-counter").get.max should be(1)
}
"count the current invocations of a static method annotated with @MinMaxCount and evaluate EL expressions" in {
for (id ← 1 to 10) AnnotatedJavaClass.countMinMaxWithEL()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.minMaxCounter("minMax:10").get.max should be(1)
-
- val minMaxKey = (name: String) ⇒ (key: MinMaxCounterKey) ⇒ key.name == name
-
- snapshot.minMaxCounters.keys.find(minMaxKey("minMax:10")).get.metadata should be(Map("minMax" -> "1", "env" -> "dev"))
+ val snapshot = takeSnapshotOf("minMax:10", "min-max-counter", tags = Map("minMax" -> "1", "env" -> "dev"))
+ snapshot.minMaxCounter("min-max-counter").get.max should be(1)
}
"measure the time spent in the execution of a static method annotated with @Time" in {
for (id ← 1 to 1) AnnotatedJavaClass.time()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.histogram("time").get.numberOfMeasurements should be(1)
+ val snapshot = takeSnapshotOf("time", "histogram")
+ snapshot.histogram("histogram").get.numberOfMeasurements should be(1)
}
"measure the time spent in the execution of a static method annotated with @Time and evaluate EL expressions" in {
for (id ← 1 to 1) AnnotatedJavaClass.timeWithEL()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.histogram("time:10").get.numberOfMeasurements should be(1)
-
- val histogramKey = (name: String) ⇒ (key: HistogramKey) ⇒ key.name == name
-
- snapshot.histograms.keys.find(histogramKey("time:10")).get.metadata should be(Map("slow-service" -> "service", "env" -> "prod"))
+ val snapshot = takeSnapshotOf("time:10", "histogram", tags = Map("slow-service" -> "service", "env" -> "prod"))
+ snapshot.histogram("histogram").get.numberOfMeasurements should be(1)
}
"record the value returned by a static method annotated with @Histogram" in {
for (value ← 1 to 5) AnnotatedJavaClass.histogram(value.toLong)
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
+ val snapshot = takeSnapshotOf("histogram", "histogram")
snapshot.histogram("histogram").get.numberOfMeasurements should be(5)
snapshot.histogram("histogram").get.min should be(1)
snapshot.histogram("histogram").get.max should be(5)
@@ -129,14 +121,10 @@ class StaticAnnotationInstrumentationJavaSpec extends BaseKamonSpec("static-anno
"record the value returned by a static method annotated with @Histogram and evaluate EL expressions" in {
for (value ← 1 to 2) AnnotatedJavaClass.histogramWithEL(value.toLong)
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.histogram("histogram:10").get.numberOfMeasurements should be(2)
- snapshot.histogram("histogram:10").get.min should be(1)
- snapshot.histogram("histogram:10").get.max should be(2)
-
- val histogramKey = (name: String) ⇒ (key: HistogramKey) ⇒ key.name == name
-
- snapshot.histograms.keys.find(histogramKey("histogram:10")).get.metadata should be(Map("histogram" -> "hdr", "env" -> "prod"))
+ val snapshot = takeSnapshotOf("histogram:10", "histogram", tags = Map("histogram" -> "hdr", "env" -> "prod"))
+ snapshot.histogram("histogram").get.numberOfMeasurements should be(2)
+ snapshot.histogram("histogram").get.min should be(1)
+ snapshot.histogram("histogram").get.max should be(2)
}
}
} \ No newline at end of file
diff --git a/kamon-annotation/src/test/scala/kamon/annotation/StaticAnnotationInstrumentationSpec.scala b/kamon-annotation/src/test/scala/kamon/annotation/StaticAnnotationInstrumentationSpec.scala
index aea83409..a8e68009 100644
--- a/kamon-annotation/src/test/scala/kamon/annotation/StaticAnnotationInstrumentationSpec.scala
+++ b/kamon-annotation/src/test/scala/kamon/annotation/StaticAnnotationInstrumentationSpec.scala
@@ -21,8 +21,6 @@ import kamon.metric.{ HistogramKey, MinMaxCounterKey, CounterKey }
import kamon.testkit.BaseKamonSpec
class StaticAnnotationInstrumentationSpec extends BaseKamonSpec("static-annotation-instrumentation-spec") {
- import kamon.metric.TraceMetricsSpec.SegmentSyntax
-
override lazy val config =
ConfigFactory.parseString(
"""
@@ -31,53 +29,62 @@ class StaticAnnotationInstrumentationSpec extends BaseKamonSpec("static-annotati
| default-collection-context-buffer-size = 100
|}
""".stripMargin)
-
"the Kamon Annotation module" should {
"create a new trace when is invoked a method annotated with @Trace in a Scala Object" in {
- for (id ← 1 to 10) AnnotatedObject.trace()
+ for (id ← 1 to 42) AnnotatedObject.trace()
val snapshot = takeSnapshotOf("trace", "trace")
- snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(10)
- snapshot.segments.size should be(0)
+ snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(42)
}
+
"create a segment when is invoked a method annotated with @Trace and @Segment in a Scala Object" in {
- for (id ← 1 to 10) AnnotatedObject.segment()
+ for (id ← 1 to 15) AnnotatedObject.segment()
- val snapshot = takeSnapshotOf("trace-with-segment", "trace")
- snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(10)
+ val segmentMetricsSnapshot = takeSnapshotOf("segment", "trace-segment",
+ tags = Map(
+ "trace" -> "trace-with-segment",
+ "category" -> "segments",
+ "library" -> "segment"))
- snapshot.segments.size should be(2)
- snapshot.segment("segment", "segments", "segment") should not be empty
- snapshot.segment("inner-segment", "inner", "segment") should not be empty
+ segmentMetricsSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(15)
}
"create a segment when is invoked a method annotated with @Trace and @Segment and evaluate EL expressions in a Scala Object" in {
- for (id ← 1 to 10) AnnotatedObject.segmentWithEL()
+ for (id ← 1 to 18) AnnotatedObject.segmentWithEL()
val snapshot = takeSnapshotOf("trace-with-segment-el", "trace")
- snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(10)
+ snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(18)
+
+ val segment10Snapshot = takeSnapshotOf("segment:10", "trace-segment",
+ tags = Map(
+ "trace" -> "trace-with-segment-el",
+ "category" -> "segments",
+ "library" -> "segment"))
- snapshot.segments.size should be(2)
- snapshot.segment("segment:10", "segments", "segment") should not be empty
- snapshot.segment("inner-segment", "inner", "segment") should not be empty
+ segment10Snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(18)
+
+ val innerSegmentSnapshot = takeSnapshotOf("inner-segment", "trace-segment",
+ tags = Map(
+ "trace" -> "trace-with-segment-el",
+ "category" -> "inner",
+ "library" -> "segment"))
+
+ innerSegmentSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(18)
}
"count the invocations of a method annotated with @Count in a Scala Object" in {
for (id ← 1 to 10) AnnotatedObject.count()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.counter("count").get.count should be(10)
+ val snapshot = takeSnapshotOf("count", "counter")
+ snapshot.counter("counter").get.count should be(10)
}
"count the invocations of a method annotated with @Count and evaluate EL expressions in a Scala Object" in {
for (id ← 1 to 2) AnnotatedObject.countWithEL()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.counter("count:10").get.count should be(2)
-
- val counterKey = (name: String) ⇒ (key: CounterKey) ⇒ key.name == name
+ val snapshot = takeSnapshotOf("count:10", "counter", tags = Map("counter" -> "1", "env" -> "prod"))
+ snapshot.counter("counter").get.count should be(2)
- snapshot.counters.keys.find(counterKey("count:10")).get.metadata should be(Map("counter" -> "1", "env" -> "prod"))
}
"count the current invocations of a method annotated with @MinMaxCount in a Scala Object" in {
@@ -85,43 +92,36 @@ class StaticAnnotationInstrumentationSpec extends BaseKamonSpec("static-annotati
AnnotatedObject.countMinMax()
}
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.minMaxCounter("minMax").get.max should be(1)
+ val snapshot = takeSnapshotOf("minMax", "min-max-counter")
+ snapshot.minMaxCounter("min-max-counter").get.max should be(1)
}
"count the current invocations of a method annotated with @MinMaxCount and evaluate EL expressions in a Scala Object" in {
for (id ← 1 to 10) AnnotatedObject.countMinMaxWithEL()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.minMaxCounter("minMax:10").get.max should be(1)
+ val snapshot = takeSnapshotOf("minMax:10", "min-max-counter", tags = Map("minMax" -> "1", "env" -> "dev"))
+ snapshot.minMaxCounter("min-max-counter").get.max should be(1)
- val minMaxKey = (name: String) ⇒ (key: MinMaxCounterKey) ⇒ key.name == name
-
- snapshot.minMaxCounters.keys.find(minMaxKey("minMax:10")).get.metadata should be(Map("minMax" -> "1", "env" -> "dev"))
}
"measure the time spent in the execution of a method annotated with @Time in a Scala Object" in {
for (id ← 1 to 1) AnnotatedObject.time()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.histogram("time").get.numberOfMeasurements should be(1)
+ val snapshot = takeSnapshotOf("time", "histogram")
+ snapshot.histogram("histogram").get.numberOfMeasurements should be(1)
}
"measure the time spent in the execution of a method annotated with @Time and evaluate EL expressions in a Scala Object" in {
for (id ← 1 to 1) AnnotatedObject.timeWithEL()
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.histogram("time:10").get.numberOfMeasurements should be(1)
-
- val histogramKey = (name: String) ⇒ (key: HistogramKey) ⇒ key.name == name
-
- snapshot.histograms.keys.find(histogramKey("time:10")).get.metadata should be(Map("slow-service" -> "service", "env" -> "prod"))
+ val snapshot = takeSnapshotOf("time:10", "histogram", tags = Map("slow-service" -> "service", "env" -> "prod"))
+ snapshot.histogram("histogram").get.numberOfMeasurements should be(1)
}
"record the value returned by a method annotated with @Histogram in a Scala Object" in {
for (value ← 1 to 5) AnnotatedObject.histogram(value)
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
+ val snapshot = takeSnapshotOf("histogram", "histogram")
snapshot.histogram("histogram").get.numberOfMeasurements should be(5)
snapshot.histogram("histogram").get.min should be(1)
snapshot.histogram("histogram").get.max should be(5)
@@ -131,14 +131,10 @@ class StaticAnnotationInstrumentationSpec extends BaseKamonSpec("static-annotati
"record the value returned by a method annotated with @Histogram and evaluate EL expressions in a Scala Object" in {
for (value ← 1 to 2) AnnotatedObject.histogramWithEL(value)
- val snapshot = takeSnapshotOf("simple-metric", "simple-metric")
- snapshot.histogram("histogram:10").get.numberOfMeasurements should be(2)
- snapshot.histogram("histogram:10").get.min should be(1)
- snapshot.histogram("histogram:10").get.max should be(2)
-
- val histogramKey = (name: String) ⇒ (key: HistogramKey) ⇒ key.name == name
-
- snapshot.histograms.keys.find(histogramKey("histogram:10")).get.metadata should be(Map("histogram" -> "hdr", "env" -> "prod"))
+ val snapshot = takeSnapshotOf("histogram:10", "histogram", tags = Map("histogram" -> "hdr", "env" -> "prod"))
+ snapshot.histogram("histogram").get.numberOfMeasurements should be(2)
+ snapshot.histogram("histogram").get.min should be(1)
+ snapshot.histogram("histogram").get.max should be(2)
}
}
}
diff --git a/kamon-core/src/main/scala/kamon/Kamon.scala b/kamon-core/src/main/scala/kamon/Kamon.scala
index a2a24f49..a6469039 100644
--- a/kamon-core/src/main/scala/kamon/Kamon.scala
+++ b/kamon-core/src/main/scala/kamon/Kamon.scala
@@ -18,15 +18,13 @@ import _root_.akka.actor
import _root_.akka.actor._
import com.typesafe.config.{ ConfigFactory, Config }
import kamon.metric._
+import kamon.metric.instrument.Gauge
import kamon.trace.{ TracerImpl, Tracer }
object Kamon {
trait Extension extends actor.Extension
- private case class KamonCoreComponents(
- metrics: Metrics,
- tracer: Tracer,
- simpleMetrics: SimpleMetrics)
+ private case class KamonCoreComponents(metrics: Metrics, tracer: Tracer)
@volatile private var _system: ActorSystem = _
@volatile private var _coreComponents: Option[KamonCoreComponents] = None
@@ -43,10 +41,9 @@ object Kamon {
if (_coreComponents.isEmpty) {
val metrics = MetricsImpl(config)
- val simpleMetrics = SimpleMetricsImpl(metrics)
val tracer = TracerImpl(metrics, config)
- _coreComponents = Some(KamonCoreComponents(metrics, tracer, simpleMetrics))
+ _coreComponents = Some(KamonCoreComponents(metrics, tracer))
_system = ActorSystem("kamon", resolveInternalConfig)
metrics.start(_system)
@@ -70,9 +67,6 @@ object Kamon {
def tracer: Tracer =
ifStarted(_.tracer)
- def simpleMetrics: SimpleMetrics =
- ifStarted(_.simpleMetrics)
-
def apply[T <: Kamon.Extension](key: ExtensionId[T]): T =
ifStarted { _ ⇒
if (_system ne null)
diff --git a/kamon-core/src/main/scala/kamon/metric/Entity.scala b/kamon-core/src/main/scala/kamon/metric/Entity.scala
index 8d328f83..91249af0 100644
--- a/kamon-core/src/main/scala/kamon/metric/Entity.scala
+++ b/kamon-core/src/main/scala/kamon/metric/Entity.scala
@@ -23,36 +23,15 @@ package kamon.metric
*
* // TODO: Find a better word for `thing`.
*/
-class Entity(val name: String, val category: String, val metadata: Map[String, String]) {
-
- override def equals(o: Any): Boolean = {
- if (this eq o.asInstanceOf[AnyRef])
- true
- else if ((o.asInstanceOf[AnyRef] eq null) || !o.isInstanceOf[Entity])
- false
- else {
- val thatAsEntity = o.asInstanceOf[Entity]
- category == thatAsEntity.category && name == thatAsEntity.name
- }
- }
-
- override def hashCode: Int = {
- var result: Int = name.hashCode
- result = 31 * result + category.hashCode
- return result
- }
-}
+case class Entity(name: String, category: String, tags: Map[String, String])
object Entity {
def apply(name: String, category: String): Entity =
apply(name, category, Map.empty)
- def apply(name: String, category: String, metadata: Map[String, String]): Entity =
- new Entity(name, category, metadata)
-
def create(name: String, category: String): Entity =
apply(name, category, Map.empty)
- def create(name: String, category: String, metadata: Map[String, String]): Entity =
- new Entity(name, category, metadata)
+ def create(name: String, category: String, tags: Map[String, String]): Entity =
+ new Entity(name, category, tags)
} \ No newline at end of file
diff --git a/kamon-core/src/main/scala/kamon/metric/EntityRecorder.scala b/kamon-core/src/main/scala/kamon/metric/EntityRecorder.scala
index 6e0a4248..65dafa9a 100644
--- a/kamon-core/src/main/scala/kamon/metric/EntityRecorder.scala
+++ b/kamon-core/src/main/scala/kamon/metric/EntityRecorder.scala
@@ -19,6 +19,7 @@ package kamon.metric
import kamon.metric.instrument.Gauge.CurrentValueCollector
import kamon.metric.instrument.Histogram.DynamicRange
import kamon.metric.instrument._
+import kamon.util.Function
import scala.collection.concurrent.TrieMap
import scala.concurrent.duration.FiniteDuration
@@ -33,6 +34,64 @@ trait EntityRecorderFactory[T <: EntityRecorder] {
def createRecorder(instrumentFactory: InstrumentFactory): T
}
+object EntityRecorderFactory {
+ def apply[T <: EntityRecorder](entityCategory: String, factory: InstrumentFactory ⇒ T): EntityRecorderFactory[T] =
+ new EntityRecorderFactory[T] {
+ def category: String = entityCategory
+ def createRecorder(instrumentFactory: InstrumentFactory): T = factory(instrumentFactory)
+ }
+
+ def create[T <: EntityRecorder](entityCategory: String, factory: Function[InstrumentFactory, T]): EntityRecorderFactory[T] =
+ new EntityRecorderFactory[T] {
+ def category: String = entityCategory
+ def createRecorder(instrumentFactory: InstrumentFactory): T = factory(instrumentFactory)
+ }
+}
+
+private[kamon] sealed trait SingleInstrumentEntityRecorder extends EntityRecorder {
+ def key: MetricKey
+ def instrument: Instrument
+
+ def collect(collectionContext: CollectionContext): EntitySnapshot =
+ new DefaultEntitySnapshot(Map(key -> instrument.collect(collectionContext)))
+
+ def cleanup: Unit = instrument.cleanup
+}
+
+object SingleInstrumentEntityRecorder {
+ val Histogram = "histogram"
+ val MinMaxCounter = "min-max-counter"
+ val Gauge = "gauge"
+ val Counter = "counter"
+
+ val AllCategories = List("histogram", "gauge", "counter", "min-max-counter")
+}
+
+/**
+ * Entity recorder for a single Counter instrument.
+ */
+case class CounterRecorder(key: MetricKey, instrument: Counter) extends SingleInstrumentEntityRecorder
+
+/**
+ * Entity recorder for a single Histogram instrument.
+ */
+case class HistogramRecorder(key: MetricKey, instrument: Histogram) extends SingleInstrumentEntityRecorder
+
+/**
+ * Entity recorder for a single MinMaxCounter instrument.
+ */
+case class MinMaxCounterRecorder(key: MetricKey, instrument: MinMaxCounter) extends SingleInstrumentEntityRecorder
+
+/**
+ * Entity recorder for a single Gauge instrument.
+ */
+case class GaugeRecorder(key: MetricKey, instrument: Gauge) extends SingleInstrumentEntityRecorder
+
+/**
+ * Base class with plenty of utility methods to facilitate the creation of [[EntityRecorder]] implementations.
+ * It is not required to use this base class for defining custom a custom [[EntityRecorder]], but it is certainly
+ * the most convenient way to do it and the preferred approach throughout the Kamon codebase.
+ */
abstract class GenericEntityRecorder(instrumentFactory: InstrumentFactory) extends EntityRecorder {
import kamon.util.TriemapAtomicGetOrElseUpdate.Syntax
@@ -41,10 +100,10 @@ abstract class GenericEntityRecorder(instrumentFactory: InstrumentFactory) exten
_instruments.atomicGetOrElseUpdate(key, instrument, _.cleanup).asInstanceOf[T]
protected def histogram(name: String): Histogram =
- register(HistogramKey(name), instrumentFactory.createHistogram(name))
+ register(HistogramKey(name, UnitOfMeasurement.Unknown), instrumentFactory.createHistogram(name))
protected def histogram(name: String, dynamicRange: DynamicRange): Histogram =
- register(HistogramKey(name), instrumentFactory.createHistogram(name, Some(dynamicRange)))
+ register(HistogramKey(name, UnitOfMeasurement.Unknown), instrumentFactory.createHistogram(name, Some(dynamicRange)))
protected def histogram(name: String, unitOfMeasurement: UnitOfMeasurement): Histogram =
register(HistogramKey(name, unitOfMeasurement), instrumentFactory.createHistogram(name))
@@ -52,32 +111,26 @@ abstract class GenericEntityRecorder(instrumentFactory: InstrumentFactory) exten
protected def histogram(name: String, dynamicRange: DynamicRange, unitOfMeasurement: UnitOfMeasurement): Histogram =
register(HistogramKey(name, unitOfMeasurement), instrumentFactory.createHistogram(name, Some(dynamicRange)))
- protected def histogram(key: HistogramKey): Histogram =
- register(key, instrumentFactory.createHistogram(key.name))
-
- protected def histogram(key: HistogramKey, dynamicRange: DynamicRange): Histogram =
- register(key, instrumentFactory.createHistogram(key.name, Some(dynamicRange)))
-
protected def removeHistogram(name: String): Unit =
- _instruments.remove(HistogramKey(name))
+ _instruments.remove(HistogramKey(name, UnitOfMeasurement.Unknown))
- protected def removeHistogram(key: HistogramKey): Unit =
- _instruments.remove(key)
+ protected def removeHistogram(name: String, unitOfMeasurement: UnitOfMeasurement): Unit =
+ _instruments.remove(HistogramKey(name, unitOfMeasurement))
protected def minMaxCounter(name: String): MinMaxCounter =
- register(MinMaxCounterKey(name), instrumentFactory.createMinMaxCounter(name))
+ register(MinMaxCounterKey(name, UnitOfMeasurement.Unknown), instrumentFactory.createMinMaxCounter(name))
protected def minMaxCounter(name: String, dynamicRange: DynamicRange): MinMaxCounter =
- register(MinMaxCounterKey(name), instrumentFactory.createMinMaxCounter(name, Some(dynamicRange)))
+ register(MinMaxCounterKey(name, UnitOfMeasurement.Unknown), instrumentFactory.createMinMaxCounter(name, Some(dynamicRange)))
protected def minMaxCounter(name: String, refreshInterval: FiniteDuration): MinMaxCounter =
- register(MinMaxCounterKey(name), instrumentFactory.createMinMaxCounter(name, refreshInterval = Some(refreshInterval)))
+ register(MinMaxCounterKey(name, UnitOfMeasurement.Unknown), instrumentFactory.createMinMaxCounter(name, refreshInterval = Some(refreshInterval)))
protected def minMaxCounter(name: String, unitOfMeasurement: UnitOfMeasurement): MinMaxCounter =
register(MinMaxCounterKey(name, unitOfMeasurement), instrumentFactory.createMinMaxCounter(name))
protected def minMaxCounter(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration): MinMaxCounter =
- register(MinMaxCounterKey(name), instrumentFactory.createMinMaxCounter(name, Some(dynamicRange), Some(refreshInterval)))
+ register(MinMaxCounterKey(name, UnitOfMeasurement.Unknown), instrumentFactory.createMinMaxCounter(name, Some(dynamicRange), Some(refreshInterval)))
protected def minMaxCounter(name: String, dynamicRange: DynamicRange, unitOfMeasurement: UnitOfMeasurement): MinMaxCounter =
register(MinMaxCounterKey(name, unitOfMeasurement), instrumentFactory.createMinMaxCounter(name, Some(dynamicRange)))
@@ -86,7 +139,7 @@ abstract class GenericEntityRecorder(instrumentFactory: InstrumentFactory) exten
register(MinMaxCounterKey(name, unitOfMeasurement), instrumentFactory.createMinMaxCounter(name, refreshInterval = Some(refreshInterval)))
protected def minMaxCounter(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration, unitOfMeasurement: UnitOfMeasurement): MinMaxCounter =
- register(MinMaxCounterKey(name), instrumentFactory.createMinMaxCounter(name, Some(dynamicRange), Some(refreshInterval)))
+ register(MinMaxCounterKey(name, UnitOfMeasurement.Unknown), instrumentFactory.createMinMaxCounter(name, Some(dynamicRange), Some(refreshInterval)))
protected def minMaxCounter(key: MinMaxCounterKey): MinMaxCounter =
register(key, instrumentFactory.createMinMaxCounter(key.name))
@@ -101,31 +154,31 @@ abstract class GenericEntityRecorder(instrumentFactory: InstrumentFactory) exten
register(key, instrumentFactory.createMinMaxCounter(key.name, Some(dynamicRange), Some(refreshInterval)))
protected def removeMinMaxCounter(name: String): Unit =
- _instruments.remove(MinMaxCounterKey(name))
+ _instruments.remove(MinMaxCounterKey(name, UnitOfMeasurement.Unknown))
protected def removeMinMaxCounter(key: MinMaxCounterKey): Unit =
_instruments.remove(key)
protected def gauge(name: String, valueCollector: CurrentValueCollector): Gauge =
- register(GaugeKey(name), instrumentFactory.createGauge(name, valueCollector = valueCollector))
+ register(GaugeKey(name, UnitOfMeasurement.Unknown), instrumentFactory.createGauge(name, valueCollector = valueCollector))
protected def gauge(name: String, dynamicRange: DynamicRange, valueCollector: CurrentValueCollector): Gauge =
- register(GaugeKey(name), instrumentFactory.createGauge(name, Some(dynamicRange), valueCollector = valueCollector))
+ register(GaugeKey(name, UnitOfMeasurement.Unknown), instrumentFactory.createGauge(name, Some(dynamicRange), valueCollector = valueCollector))
protected def gauge(name: String, refreshInterval: FiniteDuration, valueCollector: CurrentValueCollector): Gauge =
- register(GaugeKey(name), instrumentFactory.createGauge(name, refreshInterval = Some(refreshInterval), valueCollector = valueCollector))
+ register(GaugeKey(name, UnitOfMeasurement.Unknown), instrumentFactory.createGauge(name, refreshInterval = Some(refreshInterval), valueCollector = valueCollector))
protected def gauge(name: String, unitOfMeasurement: UnitOfMeasurement, valueCollector: CurrentValueCollector): Gauge =
register(GaugeKey(name, unitOfMeasurement), instrumentFactory.createGauge(name, valueCollector = valueCollector))
protected def gauge(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration, valueCollector: CurrentValueCollector): Gauge =
- register(GaugeKey(name), instrumentFactory.createGauge(name, Some(dynamicRange), Some(refreshInterval), valueCollector = valueCollector))
+ register(GaugeKey(name, UnitOfMeasurement.Unknown), instrumentFactory.createGauge(name, Some(dynamicRange), Some(refreshInterval), valueCollector = valueCollector))
protected def gauge(name: String, dynamicRange: DynamicRange, unitOfMeasurement: UnitOfMeasurement, valueCollector: CurrentValueCollector): Gauge =
register(GaugeKey(name, unitOfMeasurement), instrumentFactory.createGauge(name, Some(dynamicRange), valueCollector = valueCollector))
protected def gauge(name: String, refreshInterval: FiniteDuration, unitOfMeasurement: UnitOfMeasurement, valueCollector: CurrentValueCollector): Gauge =
- register(GaugeKey(name), instrumentFactory.createGauge(name, refreshInterval = Some(refreshInterval), valueCollector = valueCollector))
+ register(GaugeKey(name, UnitOfMeasurement.Unknown), instrumentFactory.createGauge(name, refreshInterval = Some(refreshInterval), valueCollector = valueCollector))
protected def gauge(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration, unitOfMeasurement: UnitOfMeasurement, valueCollector: CurrentValueCollector): Gauge =
register(GaugeKey(name, unitOfMeasurement), instrumentFactory.createGauge(name, Some(dynamicRange), Some(refreshInterval), valueCollector))
@@ -143,19 +196,19 @@ abstract class GenericEntityRecorder(instrumentFactory: InstrumentFactory) exten
register(key, instrumentFactory.createGauge(key.name, Some(dynamicRange), Some(refreshInterval), valueCollector = valueCollector))
protected def removeGauge(name: String): Unit =
- _instruments.remove(GaugeKey(name))
+ _instruments.remove(GaugeKey(name, UnitOfMeasurement.Unknown))
protected def removeGauge(key: GaugeKey): Unit =
_instruments.remove(key)
protected def counter(name: String): Counter =
- register(CounterKey(name), instrumentFactory.createCounter())
+ register(CounterKey(name, UnitOfMeasurement.Unknown), instrumentFactory.createCounter())
protected def counter(key: CounterKey): Counter =
register(key, instrumentFactory.createCounter())
protected def removeCounter(name: String): Unit =
- _instruments.remove(CounterKey(name))
+ _instruments.remove(CounterKey(name, UnitOfMeasurement.Unknown))
protected def removeCounter(key: CounterKey): Unit =
_instruments.remove(key)
diff --git a/kamon-core/src/main/scala/kamon/metric/MetricKey.scala b/kamon-core/src/main/scala/kamon/metric/MetricKey.scala
index c655665b..2c710a19 100644
--- a/kamon-core/src/main/scala/kamon/metric/MetricKey.scala
+++ b/kamon-core/src/main/scala/kamon/metric/MetricKey.scala
@@ -26,144 +26,32 @@ sealed trait MetricKey {
def name: String
def unitOfMeasurement: UnitOfMeasurement
def instrumentType: InstrumentType
- def metadata: Map[String, String]
}
-// Wish that there was a shorter way to describe the operations bellow, but apparently there is no way to generalize all
-// the apply/create versions that would produce the desired return types when used from Java.
-
/**
* MetricKey for all Histogram-based metrics.
*/
-case class HistogramKey(name: String, unitOfMeasurement: UnitOfMeasurement, metadata: Map[String, String]) extends MetricKey {
+private[kamon] case class HistogramKey(name: String, unitOfMeasurement: UnitOfMeasurement) extends MetricKey {
val instrumentType = InstrumentTypes.Histogram
}
-object HistogramKey {
- def apply(name: String): HistogramKey =
- apply(name, UnitOfMeasurement.Unknown)
-
- def apply(name: String, unitOfMeasurement: UnitOfMeasurement): HistogramKey =
- apply(name, unitOfMeasurement, Map.empty)
-
- def apply(name: String, metadata: Map[String, String]): HistogramKey =
- apply(name, UnitOfMeasurement.Unknown, metadata)
-
- /**
- * Java friendly versions:
- */
-
- def create(name: String): HistogramKey =
- apply(name, UnitOfMeasurement.Unknown)
-
- def create(name: String, unitOfMeasurement: UnitOfMeasurement): HistogramKey =
- apply(name, unitOfMeasurement)
-
- def create(name: String, metadata: Map[String, String]): HistogramKey =
- apply(name, metadata)
-
- def create(name: String, unitOfMeasurement: UnitOfMeasurement, metadata: Map[String, String]): HistogramKey =
- apply(name, unitOfMeasurement, metadata)
-}
-
/**
* MetricKey for all MinMaxCounter-based metrics.
*/
-case class MinMaxCounterKey(name: String, unitOfMeasurement: UnitOfMeasurement, metadata: Map[String, String]) extends MetricKey {
+case class MinMaxCounterKey(name: String, unitOfMeasurement: UnitOfMeasurement) extends MetricKey {
val instrumentType = InstrumentTypes.MinMaxCounter
}
-object MinMaxCounterKey {
- def apply(name: String): MinMaxCounterKey =
- apply(name, UnitOfMeasurement.Unknown)
-
- def apply(name: String, unitOfMeasurement: UnitOfMeasurement): MinMaxCounterKey =
- apply(name, unitOfMeasurement, Map.empty)
-
- def apply(name: String, metadata: Map[String, String]): MinMaxCounterKey =
- apply(name, UnitOfMeasurement.Unknown, metadata)
-
- /**
- * Java friendly versions:
- */
-
- def create(name: String): MinMaxCounterKey =
- apply(name, UnitOfMeasurement.Unknown)
-
- def create(name: String, unitOfMeasurement: UnitOfMeasurement): MinMaxCounterKey =
- apply(name, unitOfMeasurement)
-
- def create(name: String, metadata: Map[String, String]): MinMaxCounterKey =
- apply(name, metadata)
-
- def create(name: String, unitOfMeasurement: UnitOfMeasurement, metadata: Map[String, String]): MinMaxCounterKey =
- apply(name, unitOfMeasurement, metadata)
-}
-
/**
* MetricKey for all Gauge-based metrics.
*/
-case class GaugeKey(name: String, unitOfMeasurement: UnitOfMeasurement, metadata: Map[String, String]) extends MetricKey {
+case class GaugeKey(name: String, unitOfMeasurement: UnitOfMeasurement) extends MetricKey {
val instrumentType = InstrumentTypes.Gauge
}
-object GaugeKey {
- def apply(name: String): GaugeKey =
- apply(name, UnitOfMeasurement.Unknown)
-
- def apply(name: String, unitOfMeasurement: UnitOfMeasurement): GaugeKey =
- apply(name, unitOfMeasurement, Map.empty)
-
- def apply(name: String, metadata: Map[String, String]): GaugeKey =
- apply(name, UnitOfMeasurement.Unknown, metadata)
-
- /**
- * Java friendly versions:
- */
-
- def create(name: String): GaugeKey =
- apply(name, UnitOfMeasurement.Unknown)
-
- def create(name: String, unitOfMeasurement: UnitOfMeasurement): GaugeKey =
- apply(name, unitOfMeasurement)
-
- def create(name: String, metadata: Map[String, String]): GaugeKey =
- apply(name, metadata)
-
- def create(name: String, unitOfMeasurement: UnitOfMeasurement, metadata: Map[String, String]): GaugeKey =
- apply(name, unitOfMeasurement, metadata)
-}
-
/**
* MetricKey for all Counter-based metrics.
*/
-case class CounterKey(name: String, unitOfMeasurement: UnitOfMeasurement, metadata: Map[String, String]) extends MetricKey {
+case class CounterKey(name: String, unitOfMeasurement: UnitOfMeasurement) extends MetricKey {
val instrumentType = InstrumentTypes.Counter
}
-
-object CounterKey {
- def apply(name: String): CounterKey =
- apply(name, UnitOfMeasurement.Unknown)
-
- def apply(name: String, unitOfMeasurement: UnitOfMeasurement): CounterKey =
- apply(name, unitOfMeasurement, Map.empty)
-
- def apply(name: String, metadata: Map[String, String]): CounterKey =
- apply(name, UnitOfMeasurement.Unknown, metadata)
-
- /**
- * Java friendly versions:
- */
-
- def create(name: String): CounterKey =
- apply(name, UnitOfMeasurement.Unknown)
-
- def create(name: String, unitOfMeasurement: UnitOfMeasurement): CounterKey =
- apply(name, unitOfMeasurement)
-
- def create(name: String, metadata: Map[String, String]): CounterKey =
- apply(name, metadata)
-
- def create(name: String, unitOfMeasurement: UnitOfMeasurement, metadata: Map[String, String]): CounterKey =
- apply(name, unitOfMeasurement, metadata)
-} \ No newline at end of file
diff --git a/kamon-core/src/main/scala/kamon/metric/Metrics.scala b/kamon-core/src/main/scala/kamon/metric/Metrics.scala
index d79b1de3..6a976a1c 100644
--- a/kamon-core/src/main/scala/kamon/metric/Metrics.scala
+++ b/kamon-core/src/main/scala/kamon/metric/Metrics.scala
@@ -18,26 +18,195 @@ package kamon.metric
import com.typesafe.config.Config
import kamon.metric.SubscriptionsDispatcher.{ Unsubscribe, Subscribe }
-import kamon.metric.instrument.{ DefaultRefreshScheduler, InstrumentFactory, CollectionContext }
+import kamon.metric.instrument.Gauge.CurrentValueCollector
+import kamon.metric.instrument.Histogram.DynamicRange
+import kamon.metric.instrument._
import scala.collection.concurrent.TrieMap
import akka.actor._
-import kamon.util.{ LazyActorRef, TriemapAtomicGetOrElseUpdate }
+import kamon.util.{ Supplier, LazyActorRef, TriemapAtomicGetOrElseUpdate }
+
+import scala.concurrent.duration.FiniteDuration
case class EntityRegistration[T <: EntityRecorder](entity: Entity, recorder: T)
trait Metrics {
def settings: MetricsSettings
+
def shouldTrack(entity: Entity): Boolean
+
def shouldTrack(entityName: String, category: String): Boolean =
shouldTrack(Entity(entityName, category))
- def register[T <: EntityRecorder](recorderFactory: EntityRecorderFactory[T], entityName: String): Option[EntityRegistration[T]]
- def register[T <: EntityRecorder](entity: Entity, recorder: T): EntityRegistration[T]
- def unregister(entity: Entity): Unit
+ //
+ // Histograms registration and removal
+ //
+
+ def histogram(name: String): Histogram =
+ registerHistogram(name)
+
+ def histogram(name: String, unitOfMeasurement: UnitOfMeasurement): Histogram =
+ registerHistogram(name, unitOfMeasurement = Some(unitOfMeasurement))
+
+ def histogram(name: String, dynamicRange: DynamicRange): Histogram =
+ registerHistogram(name, dynamicRange = Some(dynamicRange))
+
+ def histogram(name: String, unitOfMeasurement: UnitOfMeasurement, dynamicRange: DynamicRange): Histogram =
+ registerHistogram(name, unitOfMeasurement = Some(unitOfMeasurement), dynamicRange = Some(dynamicRange))
+
+ def histogram(name: String, tags: Map[String, String]): Histogram =
+ registerHistogram(name, tags)
+
+ def histogram(name: String, tags: Map[String, String], unitOfMeasurement: UnitOfMeasurement): Histogram =
+ registerHistogram(name, tags, Some(unitOfMeasurement))
+
+ def histogram(name: String, tags: Map[String, String], dynamicRange: DynamicRange): Histogram =
+ registerHistogram(name, tags, dynamicRange = Some(dynamicRange))
+
+ def histogram(name: String, tags: Map[String, String], unitOfMeasurement: UnitOfMeasurement, dynamicRange: DynamicRange): Histogram =
+ registerHistogram(name, tags, Some(unitOfMeasurement), Some(dynamicRange))
+
+ def removeHistogram(name: String): Boolean =
+ removeHistogram(name, Map.empty)
+
+ def registerHistogram(name: String, tags: Map[String, String] = Map.empty, unitOfMeasurement: Option[UnitOfMeasurement] = None,
+ dynamicRange: Option[DynamicRange] = None): Histogram
+
+ def removeHistogram(name: String, tags: Map[String, String]): Boolean
+
+ //
+ // MinMaxCounter registration and removal
+ //
+
+ def minMaxCounter(name: String): MinMaxCounter =
+ registerMinMaxCounter(name)
+
+ def minMaxCounter(name: String, unitOfMeasurement: UnitOfMeasurement): MinMaxCounter =
+ registerMinMaxCounter(name, unitOfMeasurement = Some(unitOfMeasurement))
+
+ def minMaxCounter(name: String, dynamicRange: DynamicRange): MinMaxCounter =
+ registerMinMaxCounter(name, dynamicRange = Some(dynamicRange))
+
+ def minMaxCounter(name: String, refreshInterval: FiniteDuration): MinMaxCounter =
+ registerMinMaxCounter(name, refreshInterval = Some(refreshInterval))
+
+ def minMaxCounter(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration): MinMaxCounter =
+ registerMinMaxCounter(name, dynamicRange = Some(dynamicRange), refreshInterval = Some(refreshInterval))
+
+ def minMaxCounter(name: String, unitOfMeasurement: UnitOfMeasurement, dynamicRange: DynamicRange): MinMaxCounter =
+ registerMinMaxCounter(name, unitOfMeasurement = Some(unitOfMeasurement), dynamicRange = Some(dynamicRange))
+
+ def minMaxCounter(name: String, tags: Map[String, String]): MinMaxCounter =
+ registerMinMaxCounter(name, tags)
+
+ def minMaxCounter(name: String, tags: Map[String, String], unitOfMeasurement: UnitOfMeasurement): MinMaxCounter =
+ registerMinMaxCounter(name, tags, Some(unitOfMeasurement))
+
+ def minMaxCounter(name: String, tags: Map[String, String], dynamicRange: DynamicRange): MinMaxCounter =
+ registerMinMaxCounter(name, tags, dynamicRange = Some(dynamicRange))
+
+ def minMaxCounter(name: String, tags: Map[String, String], unitOfMeasurement: UnitOfMeasurement, dynamicRange: DynamicRange): MinMaxCounter =
+ registerMinMaxCounter(name, tags, Some(unitOfMeasurement), Some(dynamicRange))
+
+ def removeMinMaxCounter(name: String): Boolean =
+ removeMinMaxCounter(name, Map.empty)
+
+ def removeMinMaxCounter(name: String, tags: Map[String, String]): Boolean
+
+ def registerMinMaxCounter(name: String, tags: Map[String, String] = Map.empty, unitOfMeasurement: Option[UnitOfMeasurement] = None,
+ dynamicRange: Option[DynamicRange] = None, refreshInterval: Option[FiniteDuration] = None): MinMaxCounter
+
+ //
+ // Gauge registration and removal
+ //
+
+ def gauge(name: String)(valueCollector: CurrentValueCollector): Gauge =
+ registerGauge(name, valueCollector)
+
+ def gauge(name: String, unitOfMeasurement: UnitOfMeasurement)(valueCollector: CurrentValueCollector): Gauge =
+ registerGauge(name, valueCollector, unitOfMeasurement = Some(unitOfMeasurement))
+
+ def gauge(name: String, dynamicRange: DynamicRange)(valueCollector: CurrentValueCollector): Gauge =
+ registerGauge(name, valueCollector, dynamicRange = Some(dynamicRange))
+
+ def gauge(name: String, refreshInterval: FiniteDuration)(valueCollector: CurrentValueCollector): Gauge =
+ registerGauge(name, valueCollector, refreshInterval = Some(refreshInterval))
+
+ def gauge(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration)(valueCollector: CurrentValueCollector): Gauge =
+ registerGauge(name, valueCollector, dynamicRange = Some(dynamicRange), refreshInterval = Some(refreshInterval))
+
+ def gauge(name: String, unitOfMeasurement: UnitOfMeasurement, dynamicRange: DynamicRange)(valueCollector: CurrentValueCollector): Gauge =
+ registerGauge(name, valueCollector, unitOfMeasurement = Some(unitOfMeasurement), dynamicRange = Some(dynamicRange))
+
+ def gauge(name: String, tags: Map[String, String])(valueCollector: CurrentValueCollector): Gauge =
+ registerGauge(name, valueCollector, tags)
+
+ def gauge(name: String, tags: Map[String, String], unitOfMeasurement: UnitOfMeasurement)(valueCollector: CurrentValueCollector): Gauge =
+ registerGauge(name, valueCollector, tags, Some(unitOfMeasurement))
+
+ def gauge(name: String, tags: Map[String, String], dynamicRange: DynamicRange)(valueCollector: CurrentValueCollector): Gauge =
+ registerGauge(name, valueCollector, tags, dynamicRange = Some(dynamicRange))
+
+ def gauge(name: String, tags: Map[String, String], unitOfMeasurement: UnitOfMeasurement, dynamicRange: DynamicRange)(valueCollector: CurrentValueCollector): Gauge =
+ registerGauge(name, valueCollector, tags, Some(unitOfMeasurement), Some(dynamicRange))
+
+ def removeGauge(name: String): Boolean =
+ removeGauge(name, Map.empty)
+
+ def removeGauge(name: String, tags: Map[String, String]): Boolean
+
+ def registerGauge(name: String, valueCollector: CurrentValueCollector, tags: Map[String, String] = Map.empty,
+ unitOfMeasurement: Option[UnitOfMeasurement] = None, dynamicRange: Option[DynamicRange] = None,
+ refreshInterval: Option[FiniteDuration] = None): Gauge
+
+ //
+ // Counters registration and removal
+ //
+
+ def counter(name: String): Counter =
+ registerCounter(name)
+
+ def counter(name: String, unitOfMeasurement: UnitOfMeasurement): Counter =
+ registerCounter(name, unitOfMeasurement = Some(unitOfMeasurement))
+
+ def counter(name: String, tags: Map[String, String]): Counter =
+ registerCounter(name, tags)
+
+ def counter(name: String, tags: Map[String, String], unitOfMeasurement: UnitOfMeasurement): Counter =
+ registerCounter(name, tags, Some(unitOfMeasurement))
+
+ def removeCounter(name: String): Boolean =
+ removeCounter(name, Map.empty)
+
+ def removeCounter(name: String, tags: Map[String, String]): Boolean
+
+ def registerCounter(name: String, tags: Map[String, String] = Map.empty, unitOfMeasurement: Option[UnitOfMeasurement] = None,
+ dynamicRange: Option[DynamicRange] = None): Counter
+
+ //
+ // Entities registration and removal
+ //
+
+ def entity[T <: EntityRecorder](recorderFactory: EntityRecorderFactory[T], name: String): T =
+ entity(recorderFactory, Entity(name, recorderFactory.category))
+
+ def entity[T <: EntityRecorder](recorderFactory: EntityRecorderFactory[T], name: String, tags: Map[String, String]): T =
+ entity(recorderFactory, Entity(name, recorderFactory.category, tags))
+
+ def removeEntity(name: String, category: String): Boolean =
+ removeEntity(Entity(name, category, Map.empty))
+
+ def removeEntity(name: String, category: String, tags: Map[String, String]): Boolean =
+ removeEntity(Entity(name, category, tags))
+
+ def removeEntity(entity: Entity): Boolean
+
+ def entity[T <: EntityRecorder](recorderFactory: EntityRecorderFactory[T], entity: Entity): T
+
+ def find(name: String, category: String): Option[EntityRecorder] =
+ find(Entity(name, category))
def find(entity: Entity): Option[EntityRecorder]
- def find(name: String, category: String): Option[EntityRecorder]
def subscribe(filter: SubscriptionFilter, subscriber: ActorRef): Unit =
subscribe(filter, subscriber, permanently = false)
@@ -51,11 +220,15 @@ trait Metrics {
def subscribe(filter: SubscriptionFilter, subscriber: ActorRef, permanently: Boolean): Unit
def unsubscribe(subscriber: ActorRef): Unit
+
def buildDefaultCollectionContext: CollectionContext
+
def instrumentFactory(category: String): InstrumentFactory
}
private[kamon] class MetricsImpl(config: Config) extends Metrics {
+ import TriemapAtomicGetOrElseUpdate.Syntax
+
private val _trackedEntities = TrieMap.empty[Entity, EntityRecorder]
private val _subscriptions = new LazyActorRef
@@ -67,35 +240,83 @@ private[kamon] class MetricsImpl(config: Config) extends Metrics {
} getOrElse (settings.trackUnmatchedEntities)
- def register[T <: EntityRecorder](recorderFactory: EntityRecorderFactory[T], entityName: String): Option[EntityRegistration[T]] = {
- import TriemapAtomicGetOrElseUpdate.Syntax
- val entity = Entity(entityName, recorderFactory.category)
+ def registerHistogram(name: String, tags: Map[String, String], unitOfMeasurement: Option[UnitOfMeasurement],
+ dynamicRange: Option[DynamicRange]): Histogram = {
- if (shouldTrack(entity)) {
- val instrumentFactory = settings.instrumentFactories.get(recorderFactory.category).getOrElse(settings.defaultInstrumentFactory)
- val recorder = _trackedEntities.atomicGetOrElseUpdate(entity, recorderFactory.createRecorder(instrumentFactory), _.cleanup).asInstanceOf[T]
+ val histogramEntity = Entity(name, "histogram", tags)
+ val recorder = _trackedEntities.atomicGetOrElseUpdate(histogramEntity, {
+ val factory = instrumentFactory(histogramEntity.category)
+ HistogramRecorder(HistogramKey(histogramEntity.category, unitOfMeasurement.getOrElse(UnitOfMeasurement.Unknown)),
+ factory.createHistogram(name, dynamicRange))
+ }, _.cleanup)
- Some(EntityRegistration(entity, recorder))
- } else None
+ recorder.asInstanceOf[HistogramRecorder].instrument
}
- def register[T <: EntityRecorder](entity: Entity, recorder: T): EntityRegistration[T] = {
- _trackedEntities.put(entity, recorder).map { oldRecorder ⇒
- oldRecorder.cleanup
- }
+ def removeHistogram(name: String, tags: Map[String, String]): Boolean =
+ _trackedEntities.remove(Entity(name, "histogram", tags)).isDefined
+
+ def registerMinMaxCounter(name: String, tags: Map[String, String], unitOfMeasurement: Option[UnitOfMeasurement], dynamicRange: Option[DynamicRange],
+ refreshInterval: Option[FiniteDuration]): MinMaxCounter = {
+
+ val minMaxCounterEntity = Entity(name, "min-max-counter", tags)
+ val recorder = _trackedEntities.atomicGetOrElseUpdate(minMaxCounterEntity, {
+ val factory = instrumentFactory(minMaxCounterEntity.category)
+ MinMaxCounterRecorder(MinMaxCounterKey(minMaxCounterEntity.category, unitOfMeasurement.getOrElse(UnitOfMeasurement.Unknown)),
+ factory.createMinMaxCounter(name, dynamicRange, refreshInterval))
+ }, _.cleanup)
+
+ recorder.asInstanceOf[MinMaxCounterRecorder].instrument
+ }
+
+ def removeMinMaxCounter(name: String, tags: Map[String, String]): Boolean =
+ _trackedEntities.remove(Entity(name, "min-max-counter", tags)).isDefined
+
+ def registerGauge(name: String, valueCollector: CurrentValueCollector, tags: Map[String, String] = Map.empty,
+ unitOfMeasurement: Option[UnitOfMeasurement] = None, dynamicRange: Option[DynamicRange] = None,
+ refreshInterval: Option[FiniteDuration] = None): Gauge = {
+
+ val gaugeEntity = Entity(name, "gauge", tags)
+ val recorder = _trackedEntities.atomicGetOrElseUpdate(gaugeEntity, {
+ val factory = instrumentFactory(gaugeEntity.category)
+ GaugeRecorder(MinMaxCounterKey(gaugeEntity.category, unitOfMeasurement.getOrElse(UnitOfMeasurement.Unknown)),
+ factory.createGauge(name, dynamicRange, refreshInterval, valueCollector))
+ }, _.cleanup)
+
+ recorder.asInstanceOf[GaugeRecorder].instrument
+ }
+
+ def removeGauge(name: String, tags: Map[String, String]): Boolean =
+ _trackedEntities.remove(Entity(name, "gauge", tags)).isDefined
+
+ def registerCounter(name: String, tags: Map[String, String] = Map.empty, unitOfMeasurement: Option[UnitOfMeasurement] = None,
+ dynamicRange: Option[DynamicRange] = None): Counter = {
+
+ val counterEntity = Entity(name, "counter", tags)
+ val recorder = _trackedEntities.atomicGetOrElseUpdate(counterEntity, {
+ val factory = instrumentFactory(counterEntity.category)
+ CounterRecorder(CounterKey(counterEntity.category, unitOfMeasurement.getOrElse(UnitOfMeasurement.Unknown)),
+ factory.createCounter())
+ }, _.cleanup)
+
+ recorder.asInstanceOf[CounterRecorder].instrument
+ }
+
+ def removeCounter(name: String, tags: Map[String, String]): Boolean =
+ _trackedEntities.remove(Entity(name, "counter", tags)).isDefined
- EntityRegistration(entity, recorder)
+ def entity[T <: EntityRecorder](recorderFactory: EntityRecorderFactory[T], entity: Entity): T = {
+ _trackedEntities.atomicGetOrElseUpdate(entity, {
+ recorderFactory.createRecorder(instrumentFactory(recorderFactory.category))
+ }, _.cleanup).asInstanceOf[T]
}
- def unregister(entity: Entity): Unit =
- _trackedEntities.remove(entity).map(_.cleanup)
+ def removeEntity(entity: Entity): Boolean =
+ _trackedEntities.remove(entity).isDefined
def find(entity: Entity): Option[EntityRecorder] =
_trackedEntities.get(entity)
- def find(name: String, category: String): Option[EntityRecorder] =
- find(Entity(name, category))
-
def subscribe(filter: SubscriptionFilter, subscriber: ActorRef, permanent: Boolean): Unit =
_subscriptions.tell(Subscribe(filter, subscriber, permanent))
diff --git a/kamon-core/src/main/scala/kamon/metric/SimpleMetrics.scala b/kamon-core/src/main/scala/kamon/metric/SimpleMetrics.scala
deleted file mode 100644
index 6324c320..00000000
--- a/kamon-core/src/main/scala/kamon/metric/SimpleMetrics.scala
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * =========================================================================================
- * Copyright © 2013-2015 the kamon project <http://kamon.io/>
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
- * =========================================================================================
- */
-
-package kamon.metric
-
-import kamon.metric.instrument.Gauge.CurrentValueCollector
-import kamon.metric.instrument.Histogram.DynamicRange
-import kamon.metric.instrument._
-
-import scala.concurrent.duration.FiniteDuration
-
-trait SimpleMetrics {
- def histogram(name: String): Histogram
- def histogram(name: String, dynamicRange: DynamicRange): Histogram
- def histogram(name: String, unitOfMeasurement: UnitOfMeasurement): Histogram
- def histogram(name: String, dynamicRange: DynamicRange, unitOfMeasurement: UnitOfMeasurement): Histogram
- def histogram(key: HistogramKey): Histogram
- def histogram(key: HistogramKey, dynamicRange: DynamicRange): Histogram
- def removeHistogram(name: String): Unit
- def removeHistogram(key: HistogramKey): Unit
-
- def minMaxCounter(name: String): MinMaxCounter
- def minMaxCounter(name: String, dynamicRange: DynamicRange): MinMaxCounter
- def minMaxCounter(name: String, refreshInterval: FiniteDuration): MinMaxCounter
- def minMaxCounter(name: String, unitOfMeasurement: UnitOfMeasurement): MinMaxCounter
- def minMaxCounter(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration): MinMaxCounter
- def minMaxCounter(name: String, dynamicRange: DynamicRange, unitOfMeasurement: UnitOfMeasurement): MinMaxCounter
- def minMaxCounter(name: String, refreshInterval: FiniteDuration, unitOfMeasurement: UnitOfMeasurement): MinMaxCounter
- def minMaxCounter(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration, unitOfMeasurement: UnitOfMeasurement): MinMaxCounter
- def minMaxCounter(key: MinMaxCounterKey): MinMaxCounter
- def minMaxCounter(key: MinMaxCounterKey, dynamicRange: DynamicRange): MinMaxCounter
- def minMaxCounter(key: MinMaxCounterKey, refreshInterval: FiniteDuration): MinMaxCounter
- def minMaxCounter(key: MinMaxCounterKey, dynamicRange: DynamicRange, refreshInterval: FiniteDuration): MinMaxCounter
- def removeMinMaxCounter(name: String): Unit
- def removeMinMaxCounter(key: MinMaxCounterKey): Unit
-
- def gauge(name: String, valueCollector: CurrentValueCollector): Gauge
- def gauge(name: String, dynamicRange: DynamicRange, valueCollector: CurrentValueCollector): Gauge
- def gauge(name: String, refreshInterval: FiniteDuration, valueCollector: CurrentValueCollector): Gauge
- def gauge(name: String, unitOfMeasurement: UnitOfMeasurement, valueCollector: CurrentValueCollector): Gauge
- def gauge(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration, valueCollector: CurrentValueCollector): Gauge
- def gauge(name: String, dynamicRange: DynamicRange, unitOfMeasurement: UnitOfMeasurement, valueCollector: CurrentValueCollector): Gauge
- def gauge(name: String, refreshInterval: FiniteDuration, unitOfMeasurement: UnitOfMeasurement, valueCollector: CurrentValueCollector): Gauge
- def gauge(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration, unitOfMeasurement: UnitOfMeasurement, valueCollector: CurrentValueCollector): Gauge
- def gauge(key: GaugeKey, valueCollector: CurrentValueCollector): Gauge
- def gauge(key: GaugeKey, dynamicRange: DynamicRange, valueCollector: CurrentValueCollector): Gauge
- def gauge(key: GaugeKey, refreshInterval: FiniteDuration, valueCollector: CurrentValueCollector): Gauge
- def gauge(key: GaugeKey, dynamicRange: DynamicRange, refreshInterval: FiniteDuration, valueCollector: CurrentValueCollector): Gauge
- def removeGauge(name: String): Unit
- def removeGauge(key: GaugeKey): Unit
-
- def counter(name: String): Counter
- def counter(key: CounterKey): Counter
- def removeCounter(name: String): Unit
- def removeCounter(key: CounterKey): Unit
-
-}
-
-private[kamon] class SimpleMetricsImpl(instrumentFactory: InstrumentFactory) extends GenericEntityRecorder(instrumentFactory) with SimpleMetrics {
- override def histogram(name: String): Histogram =
- super.histogram(name)
-
- override def histogram(name: String, dynamicRange: DynamicRange): Histogram =
- super.histogram(name, dynamicRange)
-
- override def histogram(name: String, unitOfMeasurement: UnitOfMeasurement): Histogram =
- super.histogram(name, unitOfMeasurement)
-
- override def histogram(name: String, dynamicRange: DynamicRange, unitOfMeasurement: UnitOfMeasurement): Histogram =
- super.histogram(name, dynamicRange, unitOfMeasurement)
-
- override def histogram(key: HistogramKey): Histogram =
- super.histogram(key)
-
- override def histogram(key: HistogramKey, dynamicRange: DynamicRange): Histogram =
- super.histogram(key, dynamicRange)
-
- override def removeHistogram(name: String): Unit =
- super.removeHistogram(name)
-
- override def removeHistogram(key: HistogramKey): Unit =
- super.removeHistogram(key)
-
- override def minMaxCounter(name: String): MinMaxCounter =
- super.minMaxCounter(name)
-
- override def minMaxCounter(name: String, dynamicRange: DynamicRange): MinMaxCounter =
- super.minMaxCounter(name, dynamicRange)
-
- override def minMaxCounter(name: String, refreshInterval: FiniteDuration): MinMaxCounter =
- super.minMaxCounter(name, refreshInterval)
-
- override def minMaxCounter(name: String, unitOfMeasurement: UnitOfMeasurement): MinMaxCounter =
- super.minMaxCounter(name, unitOfMeasurement)
-
- override def minMaxCounter(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration): MinMaxCounter =
- super.minMaxCounter(name, dynamicRange, refreshInterval)
-
- override def minMaxCounter(name: String, dynamicRange: DynamicRange, unitOfMeasurement: UnitOfMeasurement): MinMaxCounter =
- super.minMaxCounter(name, dynamicRange, unitOfMeasurement)
-
- override def minMaxCounter(name: String, refreshInterval: FiniteDuration, unitOfMeasurement: UnitOfMeasurement): MinMaxCounter =
- super.minMaxCounter(name, refreshInterval, unitOfMeasurement)
-
- override def minMaxCounter(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration, unitOfMeasurement: UnitOfMeasurement): MinMaxCounter =
- super.minMaxCounter(name, dynamicRange, refreshInterval, unitOfMeasurement)
-
- override def minMaxCounter(key: MinMaxCounterKey): MinMaxCounter =
- super.minMaxCounter(key)
-
- override def minMaxCounter(key: MinMaxCounterKey, dynamicRange: DynamicRange): MinMaxCounter =
- super.minMaxCounter(key, dynamicRange)
-
- override def minMaxCounter(key: MinMaxCounterKey, refreshInterval: FiniteDuration): MinMaxCounter =
- super.minMaxCounter(key, refreshInterval)
-
- override def minMaxCounter(key: MinMaxCounterKey, dynamicRange: DynamicRange, refreshInterval: FiniteDuration): MinMaxCounter =
- super.minMaxCounter(key, dynamicRange, refreshInterval)
-
- override def removeMinMaxCounter(name: String): Unit =
- super.removeMinMaxCounter(name)
-
- override def removeMinMaxCounter(key: MinMaxCounterKey): Unit =
- super.removeMinMaxCounter(key)
-
- override def gauge(name: String, valueCollector: CurrentValueCollector): Gauge =
- super.gauge(name, valueCollector)
-
- override def gauge(name: String, dynamicRange: DynamicRange, valueCollector: CurrentValueCollector): Gauge =
- super.gauge(name, dynamicRange, valueCollector)
-
- override def gauge(name: String, refreshInterval: FiniteDuration, valueCollector: CurrentValueCollector): Gauge =
- super.gauge(name, refreshInterval, valueCollector)
-
- override def gauge(name: String, unitOfMeasurement: UnitOfMeasurement, valueCollector: CurrentValueCollector): Gauge =
- super.gauge(name, unitOfMeasurement, valueCollector)
-
- override def gauge(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration, valueCollector: CurrentValueCollector): Gauge =
- super.gauge(name, dynamicRange, refreshInterval, valueCollector)
-
- override def gauge(name: String, dynamicRange: DynamicRange, unitOfMeasurement: UnitOfMeasurement, valueCollector: CurrentValueCollector): Gauge =
- super.gauge(name, dynamicRange, unitOfMeasurement, valueCollector)
-
- override def gauge(name: String, refreshInterval: FiniteDuration, unitOfMeasurement: UnitOfMeasurement, valueCollector: CurrentValueCollector): Gauge =
- super.gauge(name, refreshInterval, unitOfMeasurement, valueCollector)
-
- override def gauge(name: String, dynamicRange: DynamicRange, refreshInterval: FiniteDuration, unitOfMeasurement: UnitOfMeasurement, valueCollector: CurrentValueCollector): Gauge =
- super.gauge(name, dynamicRange, refreshInterval, unitOfMeasurement, valueCollector)
-
- override def gauge(key: GaugeKey, valueCollector: CurrentValueCollector): Gauge =
- super.gauge(key, valueCollector)
-
- override def gauge(key: GaugeKey, dynamicRange: DynamicRange, valueCollector: CurrentValueCollector): Gauge =
- super.gauge(key, dynamicRange, valueCollector)
-
- override def gauge(key: GaugeKey, refreshInterval: FiniteDuration, valueCollector: CurrentValueCollector): Gauge =
- super.gauge(key, refreshInterval, valueCollector)
-
- override def gauge(key: GaugeKey, dynamicRange: DynamicRange, refreshInterval: FiniteDuration, valueCollector: CurrentValueCollector): Gauge =
- super.gauge(key, dynamicRange, refreshInterval, valueCollector)
-
- override def removeGauge(name: String): Unit =
- super.removeGauge(name)
-
- override def removeGauge(key: GaugeKey): Unit =
- super.removeGauge(key)
-
- override def counter(name: String): Counter =
- super.counter(name)
-
- override def counter(key: CounterKey): Counter =
- super.counter(key)
-
- override def removeCounter(name: String): Unit =
- super.removeCounter(name)
-
- override def removeCounter(key: CounterKey): Unit =
- super.removeCounter(key)
-}
-
-private[kamon] object SimpleMetricsImpl {
- val SimpleMetricsEntity = Entity("simple-metric", "simple-metric")
-
- def apply(metricsExtension: Metrics): SimpleMetricsImpl = {
- val instrumentFactory = metricsExtension.instrumentFactory(SimpleMetricsEntity.category)
- val simpleMetricsExtension = new SimpleMetricsImpl(instrumentFactory)
-
- metricsExtension.register(SimpleMetricsEntity, simpleMetricsExtension).recorder
- }
-
-} \ No newline at end of file
diff --git a/kamon-core/src/main/scala/kamon/metric/TraceMetrics.scala b/kamon-core/src/main/scala/kamon/metric/TraceMetrics.scala
index 3da9c1d4..cf43b87c 100644
--- a/kamon-core/src/main/scala/kamon/metric/TraceMetrics.scala
+++ b/kamon-core/src/main/scala/kamon/metric/TraceMetrics.scala
@@ -16,29 +16,30 @@
package kamon.metric
-import kamon.metric.instrument.{ Time, InstrumentFactory, Histogram }
+import kamon.metric.instrument.{ Time, InstrumentFactory }
class TraceMetrics(instrumentFactory: InstrumentFactory) extends GenericEntityRecorder(instrumentFactory) {
- import TraceMetrics.segmentKey
/**
* Records blah blah
*/
- val ElapsedTime = histogram("elapsed-time", unitOfMeasurement = Time.Nanoseconds)
-
- /**
- * Records Blah Blah.
- *
- */
- def segment(name: String, category: String, library: String): Histogram =
- histogram(segmentKey(name, category, library))
-
+ val elapsedTime = histogram("elapsed-time", unitOfMeasurement = Time.Nanoseconds)
}
object TraceMetrics extends EntityRecorderFactory[TraceMetrics] {
def category: String = "trace"
def createRecorder(instrumentFactory: InstrumentFactory): TraceMetrics = new TraceMetrics(instrumentFactory)
+}
+
+class SegmentMetrics(instrumentFactory: InstrumentFactory) extends GenericEntityRecorder(instrumentFactory) {
+
+ /**
+ * Records blah blah
+ */
+ val elapsedTime = histogram("elapsed-time", unitOfMeasurement = Time.Nanoseconds)
+}
- def segmentKey(name: String, category: String, library: String): HistogramKey =
- HistogramKey(name, Time.Nanoseconds, Map("category" -> category, "library" -> library))
+object SegmentMetrics extends EntityRecorderFactory[SegmentMetrics] {
+ def category: String = "trace-segment"
+ def createRecorder(instrumentFactory: InstrumentFactory): SegmentMetrics = new SegmentMetrics(instrumentFactory)
} \ No newline at end of file
diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/Gauge.scala b/kamon-core/src/main/scala/kamon/metric/instrument/Gauge.scala
index 80214510..61b53df2 100644
--- a/kamon-core/src/main/scala/kamon/metric/instrument/Gauge.scala
+++ b/kamon-core/src/main/scala/kamon/metric/instrument/Gauge.scala
@@ -55,6 +55,10 @@ object Gauge {
implicit def functionZeroAsCurrentValueCollector(f: () ⇒ Long): CurrentValueCollector = new CurrentValueCollector {
def currentValue: Long = f.apply()
}
+
+ implicit def callByNameLongAsCurrentValueCollector(f: ⇒ Long): CurrentValueCollector = new CurrentValueCollector {
+ def currentValue: Long = f
+ }
}
/**
diff --git a/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala b/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala
index eb4bad6f..0f09b4be 100644
--- a/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala
+++ b/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala
@@ -19,13 +19,14 @@ package kamon.trace
import java.util.concurrent.ConcurrentLinkedQueue
import akka.event.LoggingAdapter
-import kamon.metric.{ Metrics, TraceMetrics }
+import kamon.Kamon
+import kamon.metric.{ SegmentMetrics, Metrics, 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: Metrics)
+ val startTimestamp: RelativeNanoTimestamp, log: LoggingAdapter)
extends TraceContext {
@volatile private var _name = traceName
@@ -51,20 +52,23 @@ private[kamon] class MetricsOnlyContext(traceName: String, val token: String, iz
val traceElapsedTime = NanoInterval.since(startTimestamp)
_elapsedTime = traceElapsedTime
- metricsExtension.register(TraceMetrics, name).map { registration ⇒
- registration.recorder.ElapsedTime.record(traceElapsedTime.nanos)
- drainFinishedSegments(registration.recorder)
- }
+ Kamon.metrics.entity(TraceMetrics, name).elapsedTime.record(traceElapsedTime.nanos)
+ drainFinishedSegments()
}
def startSegment(segmentName: String, category: String, library: String): Segment =
new MetricsOnlySegment(segmentName, category, library)
- @tailrec private def drainFinishedSegments(recorder: TraceMetrics): Unit = {
+ @tailrec private def drainFinishedSegments(): Unit = {
val segment = _finishedSegments.poll()
if (segment != null) {
- recorder.segment(segment.name, segment.category, segment.library).record(segment.duration.nanos)
- drainFinishedSegments(recorder)
+ val segmentTags = Map(
+ "trace" -> name,
+ "category" -> segment.category,
+ "library" -> segment.library)
+
+ Kamon.metrics.entity(SegmentMetrics, segment.name, segmentTags).elapsedTime.record(segment.duration.nanos)
+ drainFinishedSegments()
}
}
@@ -72,9 +76,7 @@ private[kamon] class MetricsOnlyContext(traceName: String, val token: String, iz
_finishedSegments.add(SegmentLatencyData(segmentName, category, library, duration))
if (isClosed) {
- metricsExtension.register(TraceMetrics, name).map { registration ⇒
- drainFinishedSegments(registration.recorder)
- }
+ drainFinishedSegments()
}
}
diff --git a/kamon-core/src/main/scala/kamon/trace/Tracer.scala b/kamon-core/src/main/scala/kamon/trace/Tracer.scala
index cf83b36b..472c1d65 100644
--- a/kamon-core/src/main/scala/kamon/trace/Tracer.scala
+++ b/kamon-core/src/main/scala/kamon/trace/Tracer.scala
@@ -80,7 +80,7 @@ private[kamon] class TracerImpl(metricsExtension: Metrics, config: Config) exten
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)
+ def newMetricsOnlyContext = new MetricsOnlyContext(traceName, token, isOpen, _settings.levelOfDetail, startTimestamp, null)
if (_settings.levelOfDetail == LevelOfDetail.MetricsOnly || !isLocal)
newMetricsOnlyContext
@@ -88,7 +88,7 @@ private[kamon] class TracerImpl(metricsExtension: Metrics, config: Config) exten
if (!_settings.sampler.shouldTrace)
newMetricsOnlyContext
else
- new TracingContext(traceName, token, true, _settings.levelOfDetail, isLocal, startTimestamp, null, metricsExtension, this, dispatchTracingContext)
+ new TracingContext(traceName, token, true, _settings.levelOfDetail, isLocal, startTimestamp, null, dispatchTracingContext)
}
}
diff --git a/kamon-core/src/main/scala/kamon/trace/TracingContext.scala b/kamon-core/src/main/scala/kamon/trace/TracingContext.scala
index d34526f7..9708d25f 100644
--- a/kamon-core/src/main/scala/kamon/trace/TracingContext.scala
+++ b/kamon-core/src/main/scala/kamon/trace/TracingContext.scala
@@ -26,9 +26,8 @@ import kamon.metric.Metrics
import scala.collection.concurrent.TrieMap
private[trace] class TracingContext(traceName: String, token: String, izOpen: Boolean, levelOfDetail: LevelOfDetail,
- isLocal: Boolean, startTimeztamp: RelativeNanoTimestamp, log: LoggingAdapter, metricsExtension: Metrics,
- traceExtension: TracerImpl, traceInfoSink: TracingContext ⇒ Unit)
- extends MetricsOnlyContext(traceName, token, izOpen, levelOfDetail, startTimeztamp, log, metricsExtension) {
+ isLocal: Boolean, startTimeztamp: RelativeNanoTimestamp, log: LoggingAdapter, traceInfoSink: TracingContext ⇒ Unit)
+ extends MetricsOnlyContext(traceName, token, izOpen, levelOfDetail, startTimeztamp, log) {
private val _openSegments = new AtomicInteger(0)
private val _startTimestamp = NanoTimestamp.now
diff --git a/kamon-core/src/main/scala/kamon/util/FunctionalInterfaces.scala b/kamon-core/src/main/scala/kamon/util/FunctionalInterfaces.scala
new file mode 100644
index 00000000..1f600b78
--- /dev/null
+++ b/kamon-core/src/main/scala/kamon/util/FunctionalInterfaces.scala
@@ -0,0 +1,9 @@
+package kamon.util
+
+trait Supplier[T] {
+ def get: T
+}
+
+trait Function[T, R] {
+ def apply(t: T): R
+} \ 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 60ba9a0e..0180e980 100644
--- a/kamon-core/src/test/scala/kamon/metric/SimpleMetricsSpec.scala
+++ b/kamon-core/src/test/scala/kamon/metric/SimpleMetricsSpec.scala
@@ -35,93 +35,81 @@ class SimpleMetricsSpec extends BaseKamonSpec("simple-metrics-spec") {
"the SimpleMetrics extension" should {
"allow registering a fully configured Histogram and get the same Histogram if registering again" in {
- val histogramA = Kamon.simpleMetrics.histogram("histogram-with-settings", DynamicRange(1, 10000, 2))
- val histogramB = Kamon.simpleMetrics.histogram("histogram-with-settings", DynamicRange(1, 10000, 2))
+ val histogramA = Kamon.metrics.histogram("histogram-with-settings", DynamicRange(1, 10000, 2))
+ val histogramB = Kamon.metrics.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.simpleMetrics.histogram("histogram-with-settings", DynamicRange(1, 10000, 2))
- val histogramB = Kamon.simpleMetrics.histogram("histogram-with-settings", DynamicRange(1, 50000, 2))
+ val histogramA = Kamon.metrics.histogram("histogram-with-settings", DynamicRange(1, 10000, 2))
+ val histogramB = Kamon.metrics.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.simpleMetrics.histogram("histogram-with-default-configuration")
+ Kamon.metrics.histogram("histogram-with-default-configuration")
}
"allow registering a Counter and get the same Counter if registering again" in {
- val counterA = Kamon.simpleMetrics.counter("counter")
- val counterB = Kamon.simpleMetrics.counter("counter")
+ val counterA = Kamon.metrics.counter("counter")
+ val counterB = Kamon.metrics.counter("counter")
counterA shouldBe theSameInstanceAs(counterB)
}
"allow registering a fully configured MinMaxCounter and get the same MinMaxCounter if registering again" in {
- val minMaxCounterA = Kamon.simpleMetrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 10000, 2), 1 second)
- val minMaxCounterB = Kamon.simpleMetrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 10000, 2), 1 second)
+ val minMaxCounterA = Kamon.metrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 10000, 2), 1 second)
+ val minMaxCounterB = Kamon.metrics.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.simpleMetrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 10000, 2), 1 second)
- val minMaxCounterB = Kamon.simpleMetrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 50000, 2), 1 second)
+ val minMaxCounterA = Kamon.metrics.minMaxCounter("min-max-counter-with-settings", DynamicRange(1, 10000, 2), 1 second)
+ val minMaxCounterB = Kamon.metrics.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.simpleMetrics.minMaxCounter("min-max-counter-with-default-configuration")
+ Kamon.metrics.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.simpleMetrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second, {
- () ⇒ 1L
- })
-
- val gaugeB = Kamon.simpleMetrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second, {
- () ⇒ 1L
- })
+ val gaugeA = Kamon.metrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second)(1L)
+ val gaugeB = Kamon.metrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second)(1L)
gaugeA shouldBe theSameInstanceAs(gaugeB)
}
"return the original Gauge when registering a fully configured Gauge for second time but with different settings" in {
- val gaugeA = Kamon.simpleMetrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second, {
- () ⇒ 1L
- })
-
- val gaugeB = Kamon.simpleMetrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second, {
- () ⇒ 1L
- })
+ val gaugeA = Kamon.metrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second)(1L)
+ val gaugeB = Kamon.metrics.gauge("gauge-with-settings", DynamicRange(1, 10000, 2), 1 second)(1L)
gaugeA shouldBe theSameInstanceAs(gaugeB)
}
"allow registering a Gauge that takes the default configuration from the kamon.metrics.precision settings" in {
- Kamon.simpleMetrics.gauge("gauge-with-default-configuration", {
- () ⇒ 2L
- })
+ Kamon.metrics.gauge("gauge-with-default-configuration")(2L)
}
"allow un-registering user metrics" in {
- val counter = Kamon.simpleMetrics.counter("counter-for-remove")
- val histogram = Kamon.simpleMetrics.histogram("histogram-for-remove")
- val minMaxCounter = Kamon.simpleMetrics.minMaxCounter("min-max-counter-for-remove")
- val gauge = Kamon.simpleMetrics.gauge("gauge-for-remove", { () ⇒ 2L })
-
- Kamon.simpleMetrics.removeCounter("counter-for-remove")
- Kamon.simpleMetrics.removeHistogram("histogram-for-remove")
- Kamon.simpleMetrics.removeMinMaxCounter("min-max-counter-for-remove")
- Kamon.simpleMetrics.removeGauge("gauge-for-remove")
-
- counter should not be (theSameInstanceAs(Kamon.simpleMetrics.counter("counter-for-remove")))
- histogram should not be (theSameInstanceAs(Kamon.simpleMetrics.histogram("histogram-for-remove")))
- minMaxCounter should not be (theSameInstanceAs(Kamon.simpleMetrics.minMaxCounter("min-max-counter-for-remove")))
- gauge should not be (theSameInstanceAs(Kamon.simpleMetrics.gauge("gauge-for-remove", { () ⇒ 2L })))
+ val counter = Kamon.metrics.counter("counter-for-remove")
+ val histogram = Kamon.metrics.histogram("histogram-for-remove")
+ val minMaxCounter = Kamon.metrics.minMaxCounter("min-max-counter-for-remove")
+ val gauge = Kamon.metrics.gauge("gauge-for-remove")(2L)
+
+ Kamon.metrics.removeCounter("counter-for-remove")
+ Kamon.metrics.removeHistogram("histogram-for-remove")
+ Kamon.metrics.removeMinMaxCounter("min-max-counter-for-remove")
+ Kamon.metrics.removeGauge("gauge-for-remove")
+
+ counter should not be (theSameInstanceAs(Kamon.metrics.counter("counter-for-remove")))
+ histogram should not be (theSameInstanceAs(Kamon.metrics.histogram("histogram-for-remove")))
+ minMaxCounter should not be (theSameInstanceAs(Kamon.metrics.minMaxCounter("min-max-counter-for-remove")))
+ gauge should not be (theSameInstanceAs(Kamon.metrics.gauge("gauge-for-remove")(2L)))
}
}
}
diff --git a/kamon-core/src/test/scala/kamon/metric/SubscriptionsProtocolSpec.scala b/kamon-core/src/test/scala/kamon/metric/SubscriptionsProtocolSpec.scala
index 53ae5273..b8131f6e 100644
--- a/kamon-core/src/test/scala/kamon/metric/SubscriptionsProtocolSpec.scala
+++ b/kamon-core/src/test/scala/kamon/metric/SubscriptionsProtocolSpec.scala
@@ -34,12 +34,12 @@ class SubscriptionsProtocolSpec extends BaseKamonSpec("subscriptions-protocol-sp
""".stripMargin)
lazy val metricsModule = Kamon.metrics
- import metricsModule.{ register, subscribe, unsubscribe }
+ import metricsModule.{ entity, subscribe, unsubscribe }
"the Subscriptions messaging protocol" should {
"allow subscribing for a single tick" in {
val subscriber = TestProbe()
- register(TraceMetrics, "one-shot")
+ entity(TraceMetrics, "one-shot")
subscribe("trace", "one-shot", subscriber.ref, permanently = false)
flushSubscriptions()
@@ -54,7 +54,7 @@ class SubscriptionsProtocolSpec extends BaseKamonSpec("subscriptions-protocol-sp
"allow subscribing permanently to a metric" in {
val subscriber = TestProbe()
- register(TraceMetrics, "permanent")
+ entity(TraceMetrics, "permanent")
subscribe("trace", "permanent", subscriber.ref, permanently = true)
for (repetition ← 1 to 5) {
@@ -68,9 +68,9 @@ class SubscriptionsProtocolSpec extends BaseKamonSpec("subscriptions-protocol-sp
"allow subscribing to metrics matching a glob pattern" in {
val subscriber = TestProbe()
- register(TraceMetrics, "include-one")
- register(TraceMetrics, "exclude-two")
- register(TraceMetrics, "include-three")
+ entity(TraceMetrics, "include-one")
+ entity(TraceMetrics, "exclude-two")
+ entity(TraceMetrics, "include-three")
subscribe("trace", "include-*", subscriber.ref, permanently = true)
for (repetition ← 1 to 5) {
@@ -85,9 +85,9 @@ class SubscriptionsProtocolSpec extends BaseKamonSpec("subscriptions-protocol-sp
"send a single TickMetricSnapshot to each subscriber, even if subscribed multiple times" in {
val subscriber = TestProbe()
- register(TraceMetrics, "include-one")
- register(TraceMetrics, "exclude-two")
- register(TraceMetrics, "include-three")
+ entity(TraceMetrics, "include-one")
+ entity(TraceMetrics, "exclude-two")
+ entity(TraceMetrics, "include-three")
subscribe("trace", "include-one", subscriber.ref, permanently = true)
subscribe("trace", "include-three", subscriber.ref, permanently = true)
@@ -103,7 +103,7 @@ class SubscriptionsProtocolSpec extends BaseKamonSpec("subscriptions-protocol-sp
"allow un-subscribing a subscriber" in {
val subscriber = TestProbe()
- register(TraceMetrics, "one-shot")
+ entity(TraceMetrics, "one-shot")
subscribe("trace", "one-shot", subscriber.ref, permanently = true)
flushSubscriptions()
diff --git a/kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala b/kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala
index 0c9ced32..ac35cf58 100644
--- a/kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala
+++ b/kamon-core/src/test/scala/kamon/metric/TickMetricSnapshotBufferSpec.scala
@@ -88,21 +88,21 @@ class TickMetricSnapshotBufferSpec extends BaseKamonSpec("trace-metrics-spec") w
trait SnapshotFixtures {
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.entity(TraceMetrics, "buffer-spec-test-trace")
val firstEmpty = TickMetricSnapshot(new MilliTimestamp(1000), new MilliTimestamp(2000), Map.empty)
val secondEmpty = TickMetricSnapshot(new MilliTimestamp(2000), new MilliTimestamp(3000), Map.empty)
val thirdEmpty = TickMetricSnapshot(new MilliTimestamp(3000), new MilliTimestamp(4000), Map.empty)
- traceRecorder.ElapsedTime.record(10L)
- traceRecorder.ElapsedTime.record(20L)
- traceRecorder.ElapsedTime.record(30L)
+ traceRecorder.elapsedTime.record(10L)
+ traceRecorder.elapsedTime.record(20L)
+ traceRecorder.elapsedTime.record(30L)
val firstNonEmpty = TickMetricSnapshot(new MilliTimestamp(1000), new MilliTimestamp(2000), Map(
(testTraceIdentity -> traceRecorder.collect(collectionContext))))
- traceRecorder.ElapsedTime.record(10L)
- traceRecorder.ElapsedTime.record(10L)
- traceRecorder.ElapsedTime.record(300L)
+ traceRecorder.elapsedTime.record(10L)
+ traceRecorder.elapsedTime.record(10L)
+ traceRecorder.elapsedTime.record(300L)
val secondNonEmpty = TickMetricSnapshot(new MilliTimestamp(1000), new MilliTimestamp(2000), Map(
(testTraceIdentity -> traceRecorder.collect(collectionContext))))
}
diff --git a/kamon-core/src/test/scala/kamon/metric/TraceMetricsSpec.scala b/kamon-core/src/test/scala/kamon/metric/TraceMetricsSpec.scala
index 03a09b7f..efdcb79b 100644
--- a/kamon-core/src/test/scala/kamon/metric/TraceMetricsSpec.scala
+++ b/kamon-core/src/test/scala/kamon/metric/TraceMetricsSpec.scala
@@ -23,8 +23,6 @@ import kamon.trace.Tracer
import kamon.metric.instrument.Histogram
class TraceMetricsSpec extends BaseKamonSpec("trace-metrics-spec") with ImplicitSender {
- import TraceMetricsSpec.SegmentSyntax
-
override lazy val config =
ConfigFactory.parseString(
"""
@@ -60,10 +58,13 @@ class TraceMetricsSpec extends BaseKamonSpec("trace-metrics-spec") with Implicit
Tracer.currentContext.finish()
}
- val snapshot = takeSnapshotOf("trace-with-segments", "trace")
+ val snapshot = takeSnapshotOf("test-segment", "trace-segment",
+ tags = Map(
+ "trace" -> "trace-with-segments",
+ "category" -> "test-category",
+ "library" -> "test-library"))
+
snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
- snapshot.segments.size should be(1)
- snapshot.segment("test-segment", "test-category", "test-library").numberOfMeasurements should be(1)
}
"record the elapsed time for segments that finish after their correspondent trace has finished" in {
@@ -75,25 +76,26 @@ class TraceMetricsSpec extends BaseKamonSpec("trace-metrics-spec") with Implicit
val beforeFinishSegmentSnapshot = takeSnapshotOf("closing-segment-after-trace", "trace")
beforeFinishSegmentSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
- beforeFinishSegmentSnapshot.segments.size should be(0)
+
+ intercept[NoSuchElementException] {
+ // The segment metric should not exist before we it has finished.
+
+ takeSnapshotOf("test-segment", "trace-segment",
+ tags = Map(
+ "trace" -> "closing-segment-after-trace",
+ "category" -> "test-category",
+ "library" -> "test-library"))
+ }
segment.finish()
- val afterFinishSegmentSnapshot = takeSnapshotOf("closing-segment-after-trace", "trace")
- afterFinishSegmentSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(0)
- afterFinishSegmentSnapshot.segments.size should be(1)
- afterFinishSegmentSnapshot.segment("test-segment", "test-category", "test-library").numberOfMeasurements should be(1)
- }
- }
-}
+ val afterFinishSegmentSnapshot = takeSnapshotOf("test-segment", "trace-segment",
+ tags = Map(
+ "trace" -> "closing-segment-after-trace",
+ "category" -> "test-category",
+ "library" -> "test-library"))
-object TraceMetricsSpec {
- implicit class SegmentSyntax(val entitySnapshot: EntitySnapshot) extends AnyVal {
- def segments: Map[HistogramKey, Histogram.Snapshot] = {
- entitySnapshot.histograms.filterKeys(_.metadata.contains("category"))
+ afterFinishSegmentSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
}
-
- def segment(name: String, category: String, library: String): Histogram.Snapshot =
- segments(TraceMetrics.segmentKey(name, category, library))
}
}
diff --git a/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala b/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala
index f3d809bf..e7b18770 100644
--- a/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala
+++ b/kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala
@@ -20,7 +20,7 @@ import akka.testkit.{ ImplicitSender, TestKitBase }
import akka.actor.ActorSystem
import com.typesafe.config.{ Config, ConfigFactory }
import kamon.Kamon
-import kamon.metric.{ SubscriptionsDispatcher, EntitySnapshot, MetricsImpl }
+import kamon.metric.{ Entity, SubscriptionsDispatcher, EntitySnapshot, MetricsImpl }
import kamon.trace.TraceContext
import kamon.util.LazyActorRef
import org.scalatest.{ BeforeAndAfterAll, Matchers, WordSpecLike }
@@ -48,6 +48,11 @@ abstract class BaseKamonSpec(actorSystemName: String) extends TestKitBase with W
recorder.collect(collectionContext)
}
+ def takeSnapshotOf(name: String, category: String, tags: Map[String, String]): EntitySnapshot = {
+ val recorder = Kamon.metrics.find(Entity(name, category, tags)).get
+ recorder.collect(collectionContext)
+ }
+
def flushSubscriptions(): Unit = {
val subscriptionsField = Kamon.metrics.getClass.getDeclaredField("_subscriptions")
subscriptionsField.setAccessible(true)
diff --git a/kamon-datadog/src/main/scala/kamon/datadog/DatadogMetricsSender.scala b/kamon-datadog/src/main/scala/kamon/datadog/DatadogMetricsSender.scala
index 80d4f098..4a73f5aa 100644
--- a/kamon-datadog/src/main/scala/kamon/datadog/DatadogMetricsSender.scala
+++ b/kamon-datadog/src/main/scala/kamon/datadog/DatadogMetricsSender.scala
@@ -23,7 +23,7 @@ import akka.util.ByteString
import kamon.metric.SubscriptionsDispatcher.TickMetricSnapshot
import java.text.{ DecimalFormatSymbols, DecimalFormat }
import kamon.metric.instrument.{ Counter, Histogram }
-import kamon.metric.{ MetricKey, Entity }
+import kamon.metric.{ SingleInstrumentEntityRecorder, MetricKey, Entity }
import java.util.Locale
class DatadogMetricsSender(remote: InetSocketAddress, maxPacketSizeInBytes: Long) extends Actor with UdpExtensionProvider {
@@ -90,11 +90,18 @@ class DatadogMetricsSender(remote: InetSocketAddress, maxPacketSizeInBytes: Long
def encodeDatadogCounter(count: Long): String = count.toString + "|c"
def buildMetricName(entity: Entity, metricKey: MetricKey): String =
- s"$appName.${entity.category}.${metricKey.name}"
+ if (SingleInstrumentEntityRecorder.AllCategories.contains(entity.category))
+ s"$appName.${entity.category}"
+ else
+ s"$appName.${entity.category}.${metricKey.name}"
def buildIdentificationTag(entity: Entity, metricKey: MetricKey): String = {
- val normalizedEntityName = entity.name.replace(": ", ":")
- s"|#${entity.category}:${normalizedEntityName}"
+ val normalizedEntityName = entity.name.replace(" ", "")
+ if (entity.tags.nonEmpty) {
+ val tagsString = entity.tags.map { case (k, v) ⇒ k + ":" + v } mkString ","
+ s"|#${entity.category}:${normalizedEntityName},$tagsString"
+ } else
+ s"|#${entity.category}:${normalizedEntityName}"
}
}
diff --git a/kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala b/kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala
index b35902f9..22ce1f8e 100644
--- a/kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala
+++ b/kamon-datadog/src/test/scala/kamon/datadog/DatadogMetricSenderSpec.scala
@@ -96,7 +96,20 @@ class DatadogMetricSenderSpec extends BaseKamonSpec("datadog-metric-sender-spec"
val udp = setup(Map(entity -> testRecorder.collect(collectionContext)))
val Udp.Send(data, _, _) = udp.expectMsgType[Udp.Send]
- data.utf8String should be("kamon.category.metric-one:10|ms|@0.5|#category:datadog\nkamon.category.counter:4|c|#category:datadog\nkamon.category.metric-two:21|ms|#category:datadog")
+ data.utf8String.split("\n") should contain allOf (
+ "kamon.category.metric-one:10|ms|@0.5|#category:datadog",
+ "kamon.category.metric-two:21|ms|#category:datadog",
+ "kamon.category.counter:4|c|#category:datadog")
+ }
+
+ "include all entity tags, if available in the metric packet" in new UdpListenerFixture {
+ val (entity, testRecorder) = buildRecorder("datadog", tags = Map("my-cool-tag" -> "some-value"))
+ testRecorder.metricTwo.record(10L, 2)
+
+ val udp = setup(Map(entity -> testRecorder.collect(collectionContext)))
+ val Udp.Send(data, _, _) = udp.expectMsgType[Udp.Send]
+
+ data.utf8String should be(s"kamon.category.metric-two:10|ms|@0.5|#category:datadog,my-cool-tag:some-value")
}
}
@@ -105,9 +118,10 @@ class DatadogMetricSenderSpec extends BaseKamonSpec("datadog-metric-sender-spec"
val localhostName = ManagementFactory.getRuntimeMXBean.getName.split('@')(1)
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
- (registration.entity, registration.recorder)
+ def buildRecorder(name: String, tags: Map[String, String] = Map.empty): (Entity, TestEntityRecorder) = {
+ val entity = Entity(name, TestEntityRecorder.category, tags)
+ val recorder = Kamon.metrics.entity(TestEntityRecorder, entity)
+ (entity, recorder)
}
def setup(metrics: Map[Entity, EntitySnapshot]): TestProbe = {
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 aa9295db..bef20667 100644
--- a/kamon-jdbc/src/main/scala/kamon/jdbc/instrumentation/StatementInstrumentation.scala
+++ b/kamon-jdbc/src/main/scala/kamon/jdbc/instrumentation/StatementInstrumentation.scala
@@ -44,9 +44,8 @@ class StatementInstrumentation {
@Around("onExecuteStatement(sql) || onExecutePreparedStatement(sql) || onExecutePreparedCall(sql)")
def aroundExecuteStatement(pjp: ProceedingJoinPoint, sql: String): Any = {
Tracer.currentContext.collect { ctx ⇒
- val metricsExtension = Kamon.metrics
val jdbcExtension = Kamon(Jdbc)
- implicit val statementRecorder = metricsExtension.register(StatementsMetrics, "jdbc-statements").map(_.recorder)
+ implicit val statementRecorder = Kamon.metrics.entity(StatementsMetrics, "jdbc-statements")
sql.replaceAll(CommentPattern, Empty) match {
case SelectStatement(_) ⇒ withSegment(ctx, Select, jdbcExtension)(recordRead(pjp, sql, jdbcExtension))
@@ -71,22 +70,22 @@ class StatementInstrumentation {
try thunk finally segment.finish()
}
- def recordRead(pjp: ProceedingJoinPoint, sql: String, jdbcExtension: JdbcExtension)(implicit statementRecorder: Option[StatementsMetrics]): Any = {
+ def recordRead(pjp: ProceedingJoinPoint, sql: String, jdbcExtension: JdbcExtension)(implicit statementRecorder: StatementsMetrics): Any = {
withTimeSpent(pjp.proceedWithErrorHandler(sql, jdbcExtension)) { timeSpent ⇒
- statementRecorder.map(stmr ⇒ stmr.reads.record(timeSpent))
+ statementRecorder.reads.record(timeSpent)
val timeSpentInMillis = nanos.toMillis(timeSpent)
if (timeSpentInMillis >= jdbcExtension.slowQueryThreshold) {
- statementRecorder.map(stmr ⇒ stmr.slows.increment())
+ statementRecorder.slows.increment()
jdbcExtension.processSlowQuery(sql, timeSpentInMillis)
}
}
}
- def recordWrite(pjp: ProceedingJoinPoint, sql: String, jdbcExtension: JdbcExtension)(implicit statementRecorder: Option[StatementsMetrics]): Any = {
+ def recordWrite(pjp: ProceedingJoinPoint, sql: String, jdbcExtension: JdbcExtension)(implicit statementRecorder: StatementsMetrics): Any = {
withTimeSpent(pjp.proceedWithErrorHandler(sql, jdbcExtension)) { timeSpent ⇒
- statementRecorder.map(stmr ⇒ stmr.writes.record(timeSpent))
+ statementRecorder.writes.record(timeSpent)
}
}
}
@@ -107,13 +106,13 @@ object StatementInstrumentation {
val Delete = "Delete"
implicit class PimpedProceedingJoinPoint(pjp: ProceedingJoinPoint) {
- def proceedWithErrorHandler(sql: String, jdbcExtension: JdbcExtension)(implicit statementRecorder: Option[StatementsMetrics]): Any = {
+ def proceedWithErrorHandler(sql: String, jdbcExtension: JdbcExtension)(implicit statementRecorder: StatementsMetrics): Any = {
try {
pjp.proceed()
} catch {
case NonFatal(cause) ⇒
jdbcExtension.processSqlError(sql, cause)
- statementRecorder.map(stmr ⇒ stmr.errors.increment())
+ statementRecorder.errors.increment()
throw cause
}
}
diff --git a/kamon-jdbc/src/test/scala/kamon/jdbc/instrumentation/StatementInstrumentationSpec.scala b/kamon-jdbc/src/test/scala/kamon/jdbc/instrumentation/StatementInstrumentationSpec.scala
index 8ad5faa8..80107dff 100644
--- a/kamon-jdbc/src/test/scala/kamon/jdbc/instrumentation/StatementInstrumentationSpec.scala
+++ b/kamon-jdbc/src/test/scala/kamon/jdbc/instrumentation/StatementInstrumentationSpec.scala
@@ -24,8 +24,6 @@ import kamon.testkit.BaseKamonSpec
import kamon.trace.{ Tracer, SegmentCategory }
class StatementInstrumentationSpec extends BaseKamonSpec("jdbc-spec") {
- import TraceMetricsSpec.SegmentSyntax
-
override lazy val config =
ConfigFactory.parseString(
"""
@@ -76,8 +74,14 @@ class StatementInstrumentationSpec extends BaseKamonSpec("jdbc-spec") {
val traceSnapshot = takeSnapshotOf("jdbc-trace-insert", "trace")
traceSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
- traceSnapshot.segments.size should be(1)
- traceSnapshot.segment("Jdbc[Insert]", SegmentCategory.Database, Jdbc.SegmentLibraryName).numberOfMeasurements should be(100)
+
+ val segmentSnapshot = takeSnapshotOf("Jdbc[Insert]", "trace-segment",
+ tags = Map(
+ "trace" -> "jdbc-trace-insert",
+ "category" -> SegmentCategory.Database,
+ "library" -> Jdbc.SegmentLibraryName))
+
+ segmentSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(100)
}
"record the execution time of SELECT operation" in {
@@ -96,8 +100,14 @@ class StatementInstrumentationSpec extends BaseKamonSpec("jdbc-spec") {
val traceSnapshot = takeSnapshotOf("jdbc-trace-select", "trace")
traceSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
- traceSnapshot.segments.size should be(1)
- traceSnapshot.segment("Jdbc[Select]", SegmentCategory.Database, Jdbc.SegmentLibraryName).numberOfMeasurements should be(100)
+
+ val segmentSnapshot = takeSnapshotOf("Jdbc[Select]", "trace-segment",
+ tags = Map(
+ "trace" -> "jdbc-trace-select",
+ "category" -> SegmentCategory.Database,
+ "library" -> Jdbc.SegmentLibraryName))
+
+ segmentSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(100)
}
"record the execution time of UPDATE operation" in {
@@ -116,8 +126,14 @@ class StatementInstrumentationSpec extends BaseKamonSpec("jdbc-spec") {
val traceSnapshot = takeSnapshotOf("jdbc-trace-update", "trace")
traceSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
- traceSnapshot.segments.size should be(1)
- traceSnapshot.segment("Jdbc[Update]", SegmentCategory.Database, Jdbc.SegmentLibraryName).numberOfMeasurements should be(100)
+
+ val segmentSnapshot = takeSnapshotOf("Jdbc[Update]", "trace-segment",
+ tags = Map(
+ "trace" -> "jdbc-trace-update",
+ "category" -> SegmentCategory.Database,
+ "library" -> Jdbc.SegmentLibraryName))
+
+ segmentSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(100)
}
"record the execution time of DELETE operation" in {
@@ -136,8 +152,14 @@ class StatementInstrumentationSpec extends BaseKamonSpec("jdbc-spec") {
val traceSnapshot = takeSnapshotOf("jdbc-trace-delete", "trace")
traceSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
- traceSnapshot.segments.size should be(1)
- traceSnapshot.segment("Jdbc[Delete]", SegmentCategory.Database, Jdbc.SegmentLibraryName).numberOfMeasurements should be(100)
+
+ val segmentSnapshot = takeSnapshotOf("Jdbc[Delete]", "trace-segment",
+ tags = Map(
+ "trace" -> "jdbc-trace-delete",
+ "category" -> SegmentCategory.Database,
+ "library" -> Jdbc.SegmentLibraryName))
+
+ segmentSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(100)
}
diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala
index 41ed9661..6919a967 100644
--- a/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala
+++ b/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala
@@ -16,17 +16,22 @@
package kamon.newrelic
-import kamon.metric.{ SimpleMetricsImpl, EntitySnapshot, Entity }
+import kamon.metric.{ 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(SimpleMetricsImpl.SimpleMetricsEntity).map { allSimpleMetrics ⇒
- allSimpleMetrics.metrics.map {
- case (key, snapshot) ⇒ Metric(snapshot, key.unitOfMeasurement, s"Custom/${key.name}", None)
- }
+ def onlySimpleMetrics(kv: (Entity, EntitySnapshot)): Boolean =
+ kamon.metric.SingleInstrumentEntityRecorder.AllCategories.contains(kv._1.category)
- } getOrElse (Map.empty)
+ def toNewRelicMetric(kv: (Entity, EntitySnapshot)): (MetricID, MetricData) = {
+ val (entity, entitySnapshot) = kv
+ val (metricKey, instrumentSnapshot) = entitySnapshot.metrics.head
+
+ Metric(instrumentSnapshot, metricKey.unitOfMeasurement, s"Custom/${entity.name}", None)
+ }
+
+ metrics.filter(onlySimpleMetrics).map(toNewRelicMetric)
}
}
diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetricExtractor.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetricExtractor.scala
index d0144f4b..76cf0757 100644
--- a/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetricExtractor.scala
+++ b/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetricExtractor.scala
@@ -17,6 +17,7 @@
package kamon.newrelic
import kamon.metric.{ EntitySnapshot, Entity }
+import kamon.trace.SegmentCategory
import scala.collection.mutable
import kamon.metric.instrument.{ Time, CollectionContext, Histogram }
@@ -35,38 +36,36 @@ object WebTransactionMetricExtractor extends MetricExtractor {
val externalScopedByHostAndLibrarySnapshots = mutable.Map.empty[(String, String, String), List[Histogram.Snapshot]]
val transactionMetrics = metrics.filterKeys(_.category == "trace").map {
- case (entity: Entity, es: EntitySnapshot) ⇒
- // Trace metrics only have elapsed-time and segments and all of them are Histograms.
- es.histograms.foreach {
- case (key, segmentSnapshot) if key.metadata.get("category").filter(_ == "http-client").nonEmpty ⇒
- val library = key.metadata("library")
- accumulatedExternalServices = accumulatedExternalServices.merge(segmentSnapshot, collectionContext)
-
- // Accumulate externals by host
- externalByHostSnapshots.update(key.name, segmentSnapshot :: externalByHostSnapshots.getOrElse(key.name, Nil))
+ case (entity, entitySnapshot) ⇒
+ val elapsedTime = entitySnapshot.histogram("elapsed-time").get
+ accumulatedHttpDispatcher = accumulatedHttpDispatcher.merge(elapsedTime, collectionContext)
+ elapsedTime.recordsIterator.foreach { record ⇒
+ apdexBuilder.record(Time.Nanoseconds.scale(Time.Seconds)(record.level), record.count)
+ }
- // Accumulate externals by host and library
- externalByHostAndLibrarySnapshots.update((key.name, library),
- segmentSnapshot :: externalByHostAndLibrarySnapshots.getOrElse((key.name, library), Nil))
+ Metric(elapsedTime, Time.Nanoseconds, "WebTransaction/Custom/" + entity.name, None)
+ }
- // Accumulate externals by host and library, including the transaction as scope.
- externalScopedByHostAndLibrarySnapshots.update((key.name, library, entity.name),
- segmentSnapshot :: externalScopedByHostAndLibrarySnapshots.getOrElse((key.name, library, entity.name), Nil))
+ // Accumulate all segment metrics
+ metrics.filterKeys(_.category == "trace-segment").map {
+ case (entity, entitySnapshot) if entity.tags("category") == SegmentCategory.HttpClient ⇒
+ val library = entity.tags("library")
+ val trace = entity.tags("trace")
+ val elapsedTime = entitySnapshot.histogram("elapsed-time").get
- case otherSegments ⇒
+ accumulatedExternalServices = accumulatedExternalServices.merge(elapsedTime, collectionContext)
- }
+ // Accumulate externals by host
+ externalByHostSnapshots.update(entity.name, elapsedTime :: externalByHostSnapshots.getOrElse(entity.name, Nil))
- es.histograms.collect {
- case (key, elapsedTime) if key.name == "elapsed-time" ⇒
- accumulatedHttpDispatcher = accumulatedHttpDispatcher.merge(elapsedTime, collectionContext)
- elapsedTime.recordsIterator.foreach { record ⇒
- apdexBuilder.record(Time.Nanoseconds.scale(Time.Seconds)(record.level), record.count)
- }
+ // Accumulate externals by host and library
+ externalByHostAndLibrarySnapshots.update((entity.name, library),
+ elapsedTime :: externalByHostAndLibrarySnapshots.getOrElse((entity.name, library), Nil))
- Metric(elapsedTime, key.unitOfMeasurement, "WebTransaction/Custom/" + entity.name, None)
- }
- } flatten
+ // Accumulate externals by host and library, including the transaction as scope.
+ externalScopedByHostAndLibrarySnapshots.update((entity.name, library, trace),
+ elapsedTime :: externalScopedByHostAndLibrarySnapshots.getOrElse((entity.name, library, trace), Nil))
+ }
val httpDispatcher = Metric(accumulatedHttpDispatcher, Time.Seconds, "HttpDispatcher", None)
val webTransaction = httpDispatcher.copy(MetricID("WebTransaction", None))
diff --git a/kamon-newrelic/src/test/scala/kamon/newrelic/MetricReporterSpec.scala b/kamon-newrelic/src/test/scala/kamon/newrelic/MetricReporterSpec.scala
index 04380677..d4e815e5 100644
--- a/kamon-newrelic/src/test/scala/kamon/newrelic/MetricReporterSpec.scala
+++ b/kamon-newrelic/src/test/scala/kamon/newrelic/MetricReporterSpec.scala
@@ -139,19 +139,19 @@ class MetricReporterSpec extends BaseKamonSpec("metric-reporter-spec") with Spra
trait FakeTickSnapshotsFixture {
val testTraceID = Entity("example-trace", "trace")
- val recorder = Kamon.metrics.register(TraceMetrics, testTraceID.name).get.recorder
+ val recorder = Kamon.metrics.entity(TraceMetrics, testTraceID.name)
val collectionContext = Kamon.metrics.buildDefaultCollectionContext
def collectRecorder = recorder.collect(collectionContext)
- recorder.ElapsedTime.record(1000000)
- recorder.ElapsedTime.record(2000000)
- recorder.ElapsedTime.record(3000000)
+ recorder.elapsedTime.record(1000000)
+ recorder.elapsedTime.record(2000000)
+ recorder.elapsedTime.record(3000000)
val firstSnapshot = TickMetricSnapshot(new MilliTimestamp(1415587618000L), new MilliTimestamp(1415587678000L), Map(testTraceID -> collectRecorder))
- recorder.ElapsedTime.record(6000000)
- recorder.ElapsedTime.record(5000000)
- recorder.ElapsedTime.record(4000000)
+ recorder.elapsedTime.record(6000000)
+ recorder.elapsedTime.record(5000000)
+ recorder.elapsedTime.record(4000000)
val secondSnapshot = TickMetricSnapshot(new MilliTimestamp(1415587678000L), new MilliTimestamp(1415587738000L), Map(testTraceID -> collectRecorder))
}
} \ No newline at end of file
diff --git a/kamon-play/src/main/scala/kamon/play/Play.scala b/kamon-play/src/main/scala/kamon/play/Play.scala
index 9e160d58..270d244f 100644
--- a/kamon-play/src/main/scala/kamon/play/Play.scala
+++ b/kamon-play/src/main/scala/kamon/play/Play.scala
@@ -36,13 +36,7 @@ class PlayExtension(private val system: ExtendedActorSystem) extends Kamon.Exten
log.info(s"Starting the Kamon(Play) extension")
private val config = system.settings.config.getConfig("kamon.play")
- val httpServerMetrics = {
- val metricsExtension = Kamon.metrics
- val factory = metricsExtension.instrumentFactory(HttpServerMetrics.category)
- val entity = Entity("play-server", HttpServerMetrics.category)
-
- metricsExtension.register(entity, new HttpServerMetrics(factory)).recorder
- }
+ val httpServerMetrics = Kamon.metrics.entity(HttpServerMetrics, "play-server")
val defaultDispatcher = system.dispatcher
val includeTraceToken: Boolean = config.getBoolean("automatic-trace-token-propagation")
diff --git a/kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala b/kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala
index d639fd9f..fe16ccbf 100644
--- a/kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala
+++ b/kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala
@@ -17,7 +17,7 @@
package kamon.play
import kamon.Kamon
-import kamon.metric.{ EntitySnapshot, TraceMetrics }
+import kamon.metric.{ Entity, EntitySnapshot, TraceMetrics }
import kamon.trace.{ Tracer, TraceContext, SegmentCategory }
import org.scalatest.{ Matchers, WordSpecLike }
import org.scalatestplus.play.OneServerPerSuite
@@ -32,7 +32,7 @@ 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")
override lazy val port: Port = 19003
@@ -46,10 +46,16 @@ class WSInstrumentationSpec extends WordSpecLike with Matchers with OneServerPer
"propagate the TraceContext inside an Action and complete the WS request" in {
Await.result(route(FakeRequest(GET, "/inside")).get, 10 seconds)
- val snapshot = takeSnapshotOf("GET: /inside")
+ val snapshot = takeSnapshotOf("GET: /inside", "trace")
snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
- snapshot.segments.size should be(1)
- snapshot.segment(s"http://localhost:$port/async", SegmentCategory.HttpClient, Play.SegmentLibraryName).numberOfMeasurements should be(1)
+
+ val segmentMetricsSnapshot = takeSnapshotOf(s"http://localhost:$port/async", "trace-segment",
+ tags = Map(
+ "trace" -> "GET: /inside",
+ "category" -> SegmentCategory.HttpClient,
+ "library" -> Play.SegmentLibraryName))
+
+ segmentMetricsSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
}
"propagate the TraceContext outside an Action and complete the WS request" in {
@@ -58,22 +64,26 @@ class WSInstrumentationSpec extends WordSpecLike with Matchers with OneServerPer
Tracer.currentContext.finish()
}
- val snapshot = takeSnapshotOf("trace-outside-action")
+ val snapshot = takeSnapshotOf("trace-outside-action", "trace")
snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
- snapshot.segments.size should be(1)
- snapshot.segment(s"http://localhost:$port/outside", SegmentCategory.HttpClient, Play.SegmentLibraryName).numberOfMeasurements should be(1)
- }
+ val segmentMetricsSnapshot = takeSnapshotOf(s"http://localhost:$port/outside", "trace-segment",
+ tags = Map(
+ "trace" -> "trace-outside-action",
+ "category" -> SegmentCategory.HttpClient,
+ "library" -> Play.SegmentLibraryName))
+
+ segmentMetricsSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
+ }
}
+ lazy val collectionContext = Kamon.metrics.buildDefaultCollectionContext
+
def newContext(name: String): TraceContext =
Kamon.tracer.newContext(name)
- def takeSnapshotOf(traceName: String): EntitySnapshot = {
- // Give some time for async segments to finish.
- Thread.sleep(300)
- val recorder = Kamon.metrics.register(TraceMetrics, traceName).get.recorder
- val collectionContext = Kamon.metrics.buildDefaultCollectionContext
+ def takeSnapshotOf(name: String, category: String, tags: Map[String, String] = Map.empty): EntitySnapshot = {
+ val recorder = Kamon.metrics.find(Entity(name, category, tags)).get
recorder.collect(collectionContext)
}
diff --git a/kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala b/kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala
index 141c8768..e4cafb45 100644
--- a/kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala
+++ b/kamon-playground/src/main/scala/test/SimpleRequestProcessor.scala
@@ -49,7 +49,7 @@ object SimpleRequestProcessor extends App with SimpleRoutingApp with RequestBuil
implicit val timeout = Timeout(30 seconds)
- val counter = Kamon.simpleMetrics.counter("requests")
+ val counter = Kamon.metrics.counter("requests")
val pipeline = sendReceive
val replier = system.actorOf(Props[Replier].withRouter(RoundRobinPool(nrOfInstances = 4)), "replier")
diff --git a/kamon-spray/src/main/scala/kamon/spray/SprayExtension.scala b/kamon-spray/src/main/scala/kamon/spray/SprayExtension.scala
index ab0fe50b..a5aa33cb 100644
--- a/kamon-spray/src/main/scala/kamon/spray/SprayExtension.scala
+++ b/kamon-spray/src/main/scala/kamon/spray/SprayExtension.scala
@@ -46,11 +46,8 @@ class SprayExtensionImpl(system: ExtendedActorSystem) extends SprayExtension {
val log = Logging(system, "SprayExtension")
val httpServerMetrics = {
- val metricsExtension = Kamon.metrics
- val factory = metricsExtension.instrumentFactory(HttpServerMetrics.category)
val entity = Entity("spray-server", HttpServerMetrics.category)
-
- metricsExtension.register(entity, new HttpServerMetrics(factory)).recorder
+ Kamon.metrics.entity(HttpServerMetrics, entity)
}
def generateTraceName(request: HttpRequest): String =
diff --git a/kamon-spray/src/test/scala/kamon/spray/ClientRequestInstrumentationSpec.scala b/kamon-spray/src/test/scala/kamon/spray/ClientRequestInstrumentationSpec.scala
index 67e6725f..4b99022e 100644
--- a/kamon-spray/src/test/scala/kamon/spray/ClientRequestInstrumentationSpec.scala
+++ b/kamon-spray/src/test/scala/kamon/spray/ClientRequestInstrumentationSpec.scala
@@ -34,8 +34,6 @@ import scala.concurrent.duration._
class ClientRequestInstrumentationSpec extends BaseKamonSpec("client-request-instrumentation-spec") with ScalaFutures
with RequestBuilding with TestServer {
- import TraceMetricsSpec.SegmentSyntax
-
override lazy val config =
ConfigFactory.parseString(
"""
@@ -130,8 +128,14 @@ class ClientRequestInstrumentationSpec extends BaseKamonSpec("client-request-ins
val traceMetricsSnapshot = takeSnapshotOf("assign-name-to-segment-with-request-level-api", "trace")
traceMetricsSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
- traceMetricsSnapshot.segment("request-level /request-level-api-segment", SegmentCategory.HttpClient, Spray.SegmentLibraryName)
- .numberOfMeasurements should be(1)
+
+ val segmentMetricsSnapshot = takeSnapshotOf("request-level /request-level-api-segment", "trace-segment",
+ tags = Map(
+ "trace" -> "assign-name-to-segment-with-request-level-api",
+ "category" -> SegmentCategory.HttpClient,
+ "library" -> Spray.SegmentLibraryName))
+
+ segmentMetricsSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
}
"rename a request level api segment once it reaches the relevant host connector" in {
@@ -161,8 +165,14 @@ class ClientRequestInstrumentationSpec extends BaseKamonSpec("client-request-ins
val traceMetricsSnapshot = takeSnapshotOf("rename-segment-with-request-level-api", "trace")
traceMetricsSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
- traceMetricsSnapshot.segment("host-level /request-level-api-segment", SegmentCategory.HttpClient, Spray.SegmentLibraryName)
- .numberOfMeasurements should be(1)
+
+ val segmentMetricsSnapshot = takeSnapshotOf("host-level /request-level-api-segment", "trace-segment",
+ tags = Map(
+ "trace" -> "rename-segment-with-request-level-api",
+ "category" -> SegmentCategory.HttpClient,
+ "library" -> Spray.SegmentLibraryName))
+
+ segmentMetricsSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
}
}
@@ -249,8 +259,14 @@ class ClientRequestInstrumentationSpec extends BaseKamonSpec("client-request-ins
val traceMetricsSnapshot = takeSnapshotOf("create-segment-with-host-level-api", "trace")
traceMetricsSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
- traceMetricsSnapshot.segment("host-level /host-level-api-segment", SegmentCategory.HttpClient, Spray.SegmentLibraryName)
- .numberOfMeasurements should be(1)
+
+ val segmentMetricsSnapshot = takeSnapshotOf("host-level /host-level-api-segment", "trace-segment",
+ tags = Map(
+ "trace" -> "create-segment-with-host-level-api",
+ "category" -> SegmentCategory.HttpClient,
+ "library" -> Spray.SegmentLibraryName))
+
+ segmentMetricsSnapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
}
}
}
diff --git a/kamon-statsd/src/test/scala/kamon/statsd/SimpleMetricKeyGeneratorSpec.scala b/kamon-statsd/src/test/scala/kamon/statsd/SimpleMetricKeyGeneratorSpec.scala
index 0edeb3df..2e03a59d 100644
--- a/kamon-statsd/src/test/scala/kamon/statsd/SimpleMetricKeyGeneratorSpec.scala
+++ b/kamon-statsd/src/test/scala/kamon/statsd/SimpleMetricKeyGeneratorSpec.scala
@@ -69,7 +69,7 @@ class SimpleMetricKeyGeneratorSpec extends WordSpec with Matchers {
}
def buildMetricKey(categoryName: String, entityName: String, metricName: String)(implicit metricKeyGenerator: SimpleMetricKeyGenerator): String = {
- val metric = HistogramKey(metricName, UnitOfMeasurement.Unknown, Map.empty)
+ val metric = HistogramKey(metricName, UnitOfMeasurement.Unknown)
val entity = Entity(entityName, categoryName)
metricKeyGenerator.generateKey(entity, metric)
}
diff --git a/kamon-statsd/src/test/scala/kamon/statsd/StatsDMetricSenderSpec.scala b/kamon-statsd/src/test/scala/kamon/statsd/StatsDMetricSenderSpec.scala
index 0211ac0f..1e53f48f 100644
--- a/kamon-statsd/src/test/scala/kamon/statsd/StatsDMetricSenderSpec.scala
+++ b/kamon-statsd/src/test/scala/kamon/statsd/StatsDMetricSenderSpec.scala
@@ -128,12 +128,12 @@ class StatsDMetricSenderSpec extends BaseKamonSpec("statsd-metric-sender-spec")
val testEntity = Entity("user/kamon", "test")
def buildMetricKey(entity: Entity, metricName: String)(implicit metricKeyGenerator: SimpleMetricKeyGenerator): String = {
- val metricKey = HistogramKey(metricName, UnitOfMeasurement.Unknown, Map.empty)
+ val metricKey = HistogramKey(metricName, UnitOfMeasurement.Unknown)
metricKeyGenerator.generateKey(entity, metricKey)
}
def buildRecorder(name: String): TestEntityRecorder = {
- Kamon.metrics.register(TestEntityRecorder, name).get.recorder
+ Kamon.metrics.entity(TestEntityRecorder, name)
}
def setup(metrics: Map[Entity, EntitySnapshot]): TestProbe = {
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 384c89f1..5090f3dd 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,12 +88,10 @@ class ContextSwitchesMetrics(pid: Long, log: LoggingAdapter, instrumentFactory:
object ContextSwitchesMetrics {
def register(system: ActorSystem, refreshInterval: FiniteDuration): ContextSwitchesMetrics = {
- val metricsExtension = Kamon.metrics
val log = Logging(system, "ContextSwitchesMetrics")
val pid = (new Sigar).getPid
- val instrumentFactory = metricsExtension.instrumentFactory("system-metric")
- metricsExtension.register(Entity("context-switches", "system-metric"), new ContextSwitchesMetrics(pid, log, instrumentFactory)).recorder
+ Kamon.metrics.entity(EntityRecorderFactory("system-metric", new ContextSwitchesMetrics(pid, log, _)), "context-switches")
}
}
diff --git a/kamon-system-metrics/src/main/scala/kamon/system/jmx/GarbageCollectionMetrics.scala b/kamon-system-metrics/src/main/scala/kamon/system/jmx/GarbageCollectionMetrics.scala
index 59d4050c..7a5770d8 100644
--- a/kamon-system-metrics/src/main/scala/kamon/system/jmx/GarbageCollectionMetrics.scala
+++ b/kamon-system-metrics/src/main/scala/kamon/system/jmx/GarbageCollectionMetrics.scala
@@ -18,7 +18,8 @@ package kamon.system.jmx
import java.lang.management.{ GarbageCollectorMXBean, ManagementFactory }
-import kamon.metric.{ Entity, Metrics, GenericEntityRecorder }
+import kamon.Kamon
+import kamon.metric.{ EntityRecorderFactory, Entity, Metrics, GenericEntityRecorder }
import kamon.metric.instrument.{ DifferentialValueCollector, Time, InstrumentFactory }
import scala.collection.JavaConverters._
@@ -44,11 +45,9 @@ object GarbageCollectionMetrics {
name.replaceAll("""[^\w]""", "-").toLowerCase
def register(metricsExtension: Metrics): Unit = {
-
- val instrumentFactory = metricsExtension.instrumentFactory("system-metric")
ManagementFactory.getGarbageCollectorMXBeans.asScala.filter(_.isValid) map { gc ⇒
val gcName = sanitizeCollectorName(gc.getName)
- metricsExtension.register(Entity(s"$gcName-garbage-collector", "system-metric"), new GarbageCollectionMetrics(gc, instrumentFactory))
+ Kamon.metrics.entity(EntityRecorderFactory("system-metric", new GarbageCollectionMetrics(gc, _)), s"$gcName-garbage-collector")
}
}
}
diff --git a/kamon-system-metrics/src/main/scala/kamon/system/jmx/JmxSystemMetricRecorderCompanion.scala b/kamon-system-metrics/src/main/scala/kamon/system/jmx/JmxSystemMetricRecorderCompanion.scala
index 8837aec0..15bd399e 100644
--- a/kamon-system-metrics/src/main/scala/kamon/system/jmx/JmxSystemMetricRecorderCompanion.scala
+++ b/kamon-system-metrics/src/main/scala/kamon/system/jmx/JmxSystemMetricRecorderCompanion.scala
@@ -17,13 +17,11 @@
package kamon.system.jmx
import kamon.metric.instrument.InstrumentFactory
-import kamon.metric.{ Entity, EntityRecorder, Metrics }
+import kamon.metric.{ EntityRecorderFactory, EntityRecorder, Metrics }
abstract class JmxSystemMetricRecorderCompanion(metricName: String) {
- def register(metricsExtension: Metrics): EntityRecorder = {
- val instrumentFactory = metricsExtension.instrumentFactory("system-metric")
- metricsExtension.register(Entity(metricName, "system-metric"), apply(instrumentFactory)).recorder
- }
+ def register(metricsExtension: Metrics): EntityRecorder =
+ metricsExtension.entity(EntityRecorderFactory("system-metric", apply(_)), metricName)
def apply(instrumentFactory: InstrumentFactory): EntityRecorder
} \ No newline at end of file
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 68b133b0..a1bd3e01 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, Metrics }
+import kamon.metric.{ EntityRecorderFactory, Entity, EntityRecorder, Metrics }
import kamon.system.sigar.SigarMetricsUpdater.UpdateSigarMetrics
import org.hyperic.sigar.Sigar
@@ -65,10 +65,8 @@ trait SigarMetric extends EntityRecorder {
}
abstract class SigarMetricRecorderCompanion(metricName: String) {
- def register(sigar: Sigar, metricsExtension: Metrics): SigarMetric = {
- val instrumentFactory = metricsExtension.instrumentFactory("system-metric")
- metricsExtension.register(Entity(metricName, "system-metric"), apply(sigar, instrumentFactory)).recorder
- }
+ def register(sigar: Sigar, metricsExtension: Metrics): SigarMetric =
+ metricsExtension.entity(EntityRecorderFactory("system-metric", apply(sigar, _)), metricName)
def apply(sigar: Sigar, instrumentFactory: InstrumentFactory): SigarMetric
}
diff --git a/project/Settings.scala b/project/Settings.scala
index 8f839914..c6306dc6 100644
--- a/project/Settings.scala
+++ b/project/Settings.scala
@@ -32,6 +32,7 @@ object Settings {
scalaVersion := ScalaVersion,
resolvers ++= Dependencies.resolutionRepos,
fork in run := true,
+ parallelExecution in Test := false,
testGrouping in Test := singleTestPerJvm((definedTests in Test).value, (javaOptions in Test).value),
javacOptions in compile := Seq(
"-Xlint:-options",