aboutsummaryrefslogtreecommitdiff
path: root/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala
diff options
context:
space:
mode:
authorIvan Topolnjak <ivantopo@gmail.com>2014-08-04 21:18:24 -0300
committerIvan Topolnjak <ivantopo@gmail.com>2014-08-04 21:18:24 -0300
commit04a112ee8d49b23b8ebac7d28db805ee60c9d5d3 (patch)
treec3ba81c652e7411de292c86c7bb0c39a04e3ba10 /kamon-core/src/main/scala/kamon/metric/UserMetrics.scala
parenta6fc18a64dee64b9de9ff5e9b0fda0c4d84536c9 (diff)
downloadKamon-04a112ee8d49b23b8ebac7d28db805ee60c9d5d3.tar.gz
Kamon-04a112ee8d49b23b8ebac7d28db805ee60c9d5d3.tar.bz2
Kamon-04a112ee8d49b23b8ebac7d28db805ee60c9d5d3.zip
= core: allow subscribing to user metrics and give decent names
Diffstat (limited to 'kamon-core/src/main/scala/kamon/metric/UserMetrics.scala')
-rw-r--r--kamon-core/src/main/scala/kamon/metric/UserMetrics.scala238
1 files changed, 139 insertions, 99 deletions
diff --git a/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala b/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala
index f3803d37..d67cfa95 100644
--- a/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala
+++ b/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala
@@ -1,163 +1,203 @@
package kamon.metric
import akka.actor
-import akka.actor.{ ActorSystem, ExtendedActorSystem, ExtensionIdProvider, ExtensionId }
-import com.typesafe.config.Config
+import akka.actor.{ ExtendedActorSystem, ExtensionIdProvider, ExtensionId }
import kamon.Kamon
import kamon.metric.instrument.{ Gauge, MinMaxCounter, Counter, Histogram }
-import scala.collection.concurrent.TrieMap
import scala.concurrent.duration.FiniteDuration
class UserMetricsExtension(system: ExtendedActorSystem) extends Kamon.Extension {
- lazy val userMetricsRecorder = Kamon(Metrics)(system).register(UserMetrics, UserMetrics.Factory).get
+ import UserMetrics._
- def registerHistogram(name: String, precision: Histogram.Precision, highestTrackableValue: Long): Histogram =
- userMetricsRecorder.buildHistogram(name, precision, highestTrackableValue)
+ lazy val metricsExtension = Kamon(Metrics)(system)
+ val precisionConfig = system.settings.config.getConfig("kamon.metrics.precision")
- def registerHistogram(name: String): Histogram =
- userMetricsRecorder.buildHistogram(name)
+ val defaultHistogramPrecisionConfig = precisionConfig.getConfig("default-histogram-precision")
+ val defaultMinMaxCounterPrecisionConfig = precisionConfig.getConfig("default-min-max-counter-precision")
+ val defaultGaugePrecisionConfig = precisionConfig.getConfig("default-gauge-precision")
- def registerCounter(name: String): Counter =
- userMetricsRecorder.buildCounter(name)
+ def registerHistogram(name: String, precision: Histogram.Precision, highestTrackableValue: Long): Histogram = {
+ metricsExtension.storage.getOrElseUpdate(UserHistogram(name), {
+ UserHistogramRecorder(Histogram(highestTrackableValue, precision, Scale.Unit))
+ }).asInstanceOf[UserHistogramRecorder].histogram
+ }
+
+ def registerHistogram(name: String): Histogram = {
+ metricsExtension.storage.getOrElseUpdate(UserHistogram(name), {
+ UserHistogramRecorder(Histogram.fromConfig(defaultHistogramPrecisionConfig))
+ }).asInstanceOf[UserHistogramRecorder].histogram
+ }
+
+ def registerCounter(name: String): Counter = {
+ metricsExtension.storage.getOrElseUpdate(UserCounter(name), {
+ UserCounterRecorder(Counter())
+ }).asInstanceOf[UserCounterRecorder].counter
+ }
def registerMinMaxCounter(name: String, precision: Histogram.Precision, highestTrackableValue: Long,
refreshInterval: FiniteDuration): MinMaxCounter = {
- userMetricsRecorder.buildMinMaxCounter(name, precision, highestTrackableValue, refreshInterval)
+ metricsExtension.storage.getOrElseUpdate(UserMinMaxCounter(name), {
+ UserMinMaxCounterRecorder(MinMaxCounter(highestTrackableValue, precision, Scale.Unit, refreshInterval, system))
+ }).asInstanceOf[UserMinMaxCounterRecorder].minMaxCounter
}
- def registerMinMaxCounter(name: String): MinMaxCounter =
- userMetricsRecorder.buildMinMaxCounter(name)
+ def registerMinMaxCounter(name: String): MinMaxCounter = {
+ metricsExtension.storage.getOrElseUpdate(UserMinMaxCounter(name), {
+ UserMinMaxCounterRecorder(MinMaxCounter.fromConfig(defaultMinMaxCounterPrecisionConfig, system))
+ }).asInstanceOf[UserMinMaxCounterRecorder].minMaxCounter
+ }
- def registerGauge(name: String)(currentValueCollector: Gauge.CurrentValueCollector): Gauge =
- userMetricsRecorder.buildGauge(name)(currentValueCollector)
+ def registerGauge(name: String)(currentValueCollector: Gauge.CurrentValueCollector): Gauge = {
+ metricsExtension.storage.getOrElseUpdate(UserGauge(name), {
+ UserGaugeRecorder(Gauge.fromConfig(defaultGaugePrecisionConfig, system)(currentValueCollector))
+ }).asInstanceOf[UserGaugeRecorder].gauge
+ }
def registerGauge(name: String, precision: Histogram.Precision, highestTrackableValue: Long,
- refreshInterval: FiniteDuration)(currentValueCollector: Gauge.CurrentValueCollector): Gauge =
- userMetricsRecorder.buildGauge(name, precision, highestTrackableValue, refreshInterval, currentValueCollector)
+ refreshInterval: FiniteDuration)(currentValueCollector: Gauge.CurrentValueCollector): Gauge = {
+ metricsExtension.storage.getOrElseUpdate(UserGauge(name), {
+ UserGaugeRecorder(Gauge(precision, highestTrackableValue, Scale.Unit, refreshInterval, system)(currentValueCollector))
+ }).asInstanceOf[UserGaugeRecorder].gauge
+ }
def removeHistogram(name: String): Unit =
- userMetricsRecorder.removeHistogram(name)
+ metricsExtension.unregister(UserHistogram(name))
def removeCounter(name: String): Unit =
- userMetricsRecorder.removeCounter(name)
+ metricsExtension.unregister(UserCounter(name))
def removeMinMaxCounter(name: String): Unit =
- userMetricsRecorder.removeMinMaxCounter(name)
+ metricsExtension.unregister(UserMinMaxCounter(name))
def removeGauge(name: String): Unit =
- userMetricsRecorder.removeGauge(name)
+ metricsExtension.unregister(UserGauge(name))
}
-object UserMetrics extends ExtensionId[UserMetricsExtension] with ExtensionIdProvider with MetricGroupIdentity {
+object UserMetrics extends ExtensionId[UserMetricsExtension] with ExtensionIdProvider {
def lookup(): ExtensionId[_ <: actor.Extension] = Metrics
+
def createExtension(system: ExtendedActorSystem): UserMetricsExtension = new UserMetricsExtension(system)
- val name: String = "user-metrics-recorder"
- val category = new MetricGroupCategory {
- val name: String = "user-metrics"
+ //
+ // Histograms
+ //
+
+ case class UserHistogram(name: String) extends MetricGroupIdentity {
+ val category = UserHistograms
+ }
+
+ case class UserHistogramRecorder(histogram: Histogram) extends MetricGroupRecorder {
+ def collect(context: CollectionContext): MetricGroupSnapshot =
+ UserHistogramSnapshot(histogram.collect(context))
+
+ def cleanup: Unit = histogram.cleanup
+ }
+
+ case class UserHistogramSnapshot(histogramSnapshot: Histogram.Snapshot) extends MetricGroupSnapshot {
+ type GroupSnapshotType = UserHistogramSnapshot
+
+ def merge(that: UserHistogramSnapshot, context: CollectionContext): UserHistogramSnapshot =
+ UserHistogramSnapshot(that.histogramSnapshot.merge(histogramSnapshot, context))
+
+ def metrics: Map[MetricIdentity, MetricSnapshot] = Map((RecordedValues, histogramSnapshot))
}
- val Factory = new MetricGroupFactory {
- type GroupRecorder = UserMetricsRecorder
- def create(config: Config, system: ActorSystem): UserMetricsRecorder = new UserMetricsRecorder(system)
+ //
+ // Counters
+ //
+
+ case class UserCounter(name: String) extends MetricGroupIdentity {
+ val category = UserCounters
}
- class UserMetricsRecorder(system: ActorSystem) extends MetricGroupRecorder {
- val precisionConfig = system.settings.config.getConfig("kamon.metrics.precision")
- val defaultHistogramPrecisionConfig = precisionConfig.getConfig("default-histogram-precision")
- val defaultMinMaxCounterPrecisionConfig = precisionConfig.getConfig("default-min-max-counter-precision")
- val defaultGaugePrecisionConfig = precisionConfig.getConfig("default-gauge-precision")
+ case class UserCounterRecorder(counter: Counter) extends MetricGroupRecorder {
+ def collect(context: CollectionContext): MetricGroupSnapshot =
+ UserCounterSnapshot(counter.collect(context))
+
+ def cleanup: Unit = counter.cleanup
+ }
- val histograms = TrieMap[String, Histogram]()
- val counters = TrieMap[String, Counter]()
- val minMaxCounters = TrieMap[String, MinMaxCounter]()
- val gauges = TrieMap[String, Gauge]()
+ case class UserCounterSnapshot(counterSnapshot: Counter.Snapshot) extends MetricGroupSnapshot {
+ type GroupSnapshotType = UserCounterSnapshot
- def buildHistogram(name: String, precision: Histogram.Precision, highestTrackableValue: Long): Histogram =
- histograms.getOrElseUpdate(name, Histogram(highestTrackableValue, precision, Scale.Unit))
+ def merge(that: UserCounterSnapshot, context: CollectionContext): UserCounterSnapshot =
+ UserCounterSnapshot(that.counterSnapshot.merge(counterSnapshot, context))
- def buildHistogram(name: String): Histogram =
- histograms.getOrElseUpdate(name, Histogram.fromConfig(defaultHistogramPrecisionConfig))
+ def metrics: Map[MetricIdentity, MetricSnapshot] = Map((Count, counterSnapshot))
+ }
- def buildCounter(name: String): Counter =
- counters.getOrElseUpdate(name, Counter())
+ //
+ // MinMaxCounters
+ //
- def buildMinMaxCounter(name: String, precision: Histogram.Precision, highestTrackableValue: Long,
- refreshInterval: FiniteDuration): MinMaxCounter = {
- minMaxCounters.getOrElseUpdate(name, MinMaxCounter(highestTrackableValue, precision, Scale.Unit, refreshInterval, system))
- }
+ case class UserMinMaxCounter(name: String) extends MetricGroupIdentity {
+ val category = UserMinMaxCounters
+ }
- def buildMinMaxCounter(name: String): MinMaxCounter =
- minMaxCounters.getOrElseUpdate(name, MinMaxCounter.fromConfig(defaultMinMaxCounterPrecisionConfig, system))
+ case class UserMinMaxCounterRecorder(minMaxCounter: MinMaxCounter) extends MetricGroupRecorder {
+ def collect(context: CollectionContext): MetricGroupSnapshot =
+ UserMinMaxCounterSnapshot(minMaxCounter.collect(context))
- def buildGauge(name: String, precision: Histogram.Precision, highestTrackableValue: Long,
- refreshInterval: FiniteDuration, currentValueCollector: Gauge.CurrentValueCollector): Gauge =
- gauges.getOrElseUpdate(name, Gauge(precision, highestTrackableValue, Scale.Unit, refreshInterval, system)(currentValueCollector))
+ def cleanup: Unit = minMaxCounter.cleanup
+ }
- def buildGauge(name: String)(currentValueCollector: Gauge.CurrentValueCollector): Gauge =
- gauges.getOrElseUpdate(name, Gauge.fromConfig(defaultGaugePrecisionConfig, system)(currentValueCollector))
+ case class UserMinMaxCounterSnapshot(minMaxCounterSnapshot: Histogram.Snapshot) extends MetricGroupSnapshot {
+ type GroupSnapshotType = UserMinMaxCounterSnapshot
- def removeHistogram(name: String): Unit =
- histograms.remove(name)
+ def merge(that: UserMinMaxCounterSnapshot, context: CollectionContext): UserMinMaxCounterSnapshot =
+ UserMinMaxCounterSnapshot(that.minMaxCounterSnapshot.merge(minMaxCounterSnapshot, context))
- def removeCounter(name: String): Unit =
- counters.remove(name)
+ def metrics: Map[MetricIdentity, MetricSnapshot] = Map((RecordedValues, minMaxCounterSnapshot))
+ }
- def removeMinMaxCounter(name: String): Unit =
- minMaxCounters.remove(name).map(_.cleanup)
+ //
+ // Gauges
+ //
- def removeGauge(name: String): Unit =
- gauges.remove(name).map(_.cleanup)
+ case class UserGauge(name: String) extends MetricGroupIdentity {
+ val category = UserGauges
+ }
- def collect(context: CollectionContext): UserMetricsSnapshot = {
- val histogramSnapshots = histograms.map {
- case (name, histogram) ⇒
- (UserHistogram(name), histogram.collect(context))
- } toMap
+ case class UserGaugeRecorder(gauge: Gauge) extends MetricGroupRecorder {
+ def collect(context: CollectionContext): MetricGroupSnapshot =
+ UserGaugeSnapshot(gauge.collect(context))
- val counterSnapshots = counters.map {
- case (name, counter) ⇒
- (UserCounter(name), counter.collect(context))
- } toMap
+ def cleanup: Unit = gauge.cleanup
+ }
- val minMaxCounterSnapshots = minMaxCounters.map {
- case (name, minMaxCounter) ⇒
- (UserMinMaxCounter(name), minMaxCounter.collect(context))
- } toMap
+ case class UserGaugeSnapshot(gaugeSnapshot: Histogram.Snapshot) extends MetricGroupSnapshot {
+ type GroupSnapshotType = UserGaugeSnapshot
- val gaugeSnapshots = gauges.map {
- case (name, gauge) ⇒
- (UserGauge(name), gauge.collect(context))
- } toMap
+ def merge(that: UserGaugeSnapshot, context: CollectionContext): UserGaugeSnapshot =
+ UserGaugeSnapshot(that.gaugeSnapshot.merge(gaugeSnapshot, context))
- UserMetricsSnapshot(histogramSnapshots, counterSnapshots, minMaxCounterSnapshots, gaugeSnapshots)
- }
+ def metrics: Map[MetricIdentity, MetricSnapshot] = Map((RecordedValues, gaugeSnapshot))
+ }
- def cleanup: Unit = {}
+ case object UserHistograms extends MetricGroupCategory {
+ val name: String = "user-histogram"
}
- case class UserHistogram(name: String) extends MetricIdentity
- case class UserCounter(name: String) extends MetricIdentity
- case class UserMinMaxCounter(name: String) extends MetricIdentity
- case class UserGauge(name: String) extends MetricIdentity
+ case object UserCounters extends MetricGroupCategory {
+ val name: String = "user-counter"
+ }
- case class UserMetricsSnapshot(histograms: Map[UserHistogram, Histogram.Snapshot],
- counters: Map[UserCounter, Counter.Snapshot],
- minMaxCounters: Map[UserMinMaxCounter, Histogram.Snapshot],
- gauges: Map[UserGauge, Histogram.Snapshot])
- extends MetricGroupSnapshot {
+ case object UserMinMaxCounters extends MetricGroupCategory {
+ val name: String = "user-min-max-counter"
+ }
- type GroupSnapshotType = UserMetricsSnapshot
+ case object UserGauges extends MetricGroupCategory {
+ val name: String = "user-gauge"
+ }
- def merge(that: UserMetricsSnapshot, context: CollectionContext): UserMetricsSnapshot =
- UserMetricsSnapshot(
- combineMaps(histograms, that.histograms)((l, r) ⇒ l.merge(r, context)),
- combineMaps(counters, that.counters)((l, r) ⇒ l.merge(r, context)),
- combineMaps(minMaxCounters, that.minMaxCounters)((l, r) ⇒ l.merge(r, context)),
- combineMaps(gauges, that.gauges)((l, r) ⇒ l.merge(r, context)))
+ case object RecordedValues extends MetricIdentity {
+ val name: String = "values"
+ }
- def metrics: Map[MetricIdentity, MetricSnapshot] = histograms ++ counters ++ minMaxCounters ++ gauges
+ case object Count extends MetricIdentity {
+ val name: String = "count"
}
}
+