aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
17 files changed, 454 insertions, 513 deletions
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)