aboutsummaryrefslogtreecommitdiff
path: root/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala
diff options
context:
space:
mode:
Diffstat (limited to 'kamon-core/src/main/scala/kamon/metric/UserMetrics.scala')
-rw-r--r--kamon-core/src/main/scala/kamon/metric/UserMetrics.scala139
1 files changed, 139 insertions, 0 deletions
diff --git a/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala b/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala
new file mode 100644
index 00000000..dea03968
--- /dev/null
+++ b/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala
@@ -0,0 +1,139 @@
+package kamon.metric
+
+import akka.actor
+import akka.actor.{ ActorSystem, ExtendedActorSystem, ExtensionIdProvider, ExtensionId }
+import com.typesafe.config.Config
+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
+
+ def registerHistogram(name: String, precision: Histogram.Precision, highestTrackableValue: Long): Histogram =
+ userMetricsRecorder.buildHistogram(name, precision, highestTrackableValue)
+
+ def registerHistogram(name: String): Histogram =
+ userMetricsRecorder.buildHistogram(name)
+
+ def registerCounter(name: String): Counter =
+ userMetricsRecorder.buildCounter(name)
+
+ def registerMinMaxCounter(name: String, precision: Histogram.Precision, highestTrackableValue: Long,
+ refreshInterval: FiniteDuration): MinMaxCounter = {
+ userMetricsRecorder.buildMinMaxCounter(name, precision, highestTrackableValue, refreshInterval)
+ }
+
+ def registerMinMaxCounter(name: String): MinMaxCounter =
+ userMetricsRecorder.buildMinMaxCounter(name)
+
+ def registerGauge(name: String)(currentValueCollector: Gauge.CurrentValueCollector): Gauge =
+ userMetricsRecorder.buildGauge(name)(currentValueCollector)
+
+ def registerGauge(name: String, precision: Histogram.Precision, highestTrackableValue: Long,
+ refreshInterval: FiniteDuration)(currentValueCollector: Gauge.CurrentValueCollector): Gauge =
+ userMetricsRecorder.buildGauge(name, precision, highestTrackableValue, refreshInterval, currentValueCollector)
+}
+
+object UserMetrics extends ExtensionId[UserMetricsExtension] with ExtensionIdProvider with MetricGroupIdentity {
+ 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"
+ }
+
+ val Factory = new MetricGroupFactory {
+ type GroupRecorder = UserMetricsRecorder
+ def create(config: Config, system: ActorSystem): UserMetricsRecorder = new UserMetricsRecorder(system)
+ }
+
+ 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")
+
+ val histograms = TrieMap[String, Histogram]()
+ val counters = TrieMap[String, Counter]()
+ val minMaxCounters = TrieMap[String, MinMaxCounter]()
+ val gauges = TrieMap[String, Gauge]()
+
+ def buildHistogram(name: String, precision: Histogram.Precision, highestTrackableValue: Long): Histogram =
+ histograms.getOrElseUpdate(name, Histogram(highestTrackableValue, precision, Scale.Unit))
+
+ def buildHistogram(name: String): Histogram =
+ histograms.getOrElseUpdate(name, Histogram.fromConfig(defaultHistogramPrecisionConfig))
+
+ def buildCounter(name: String): Counter =
+ counters.getOrElseUpdate(name, Counter())
+
+ def buildMinMaxCounter(name: String, precision: Histogram.Precision, highestTrackableValue: Long,
+ refreshInterval: FiniteDuration): MinMaxCounter = {
+ minMaxCounters.getOrElseUpdate(name, MinMaxCounter(highestTrackableValue, precision, Scale.Unit, refreshInterval, system))
+ }
+
+ def buildMinMaxCounter(name: String): MinMaxCounter =
+ minMaxCounters.getOrElseUpdate(name, MinMaxCounter.fromConfig(defaultMinMaxCounterPrecisionConfig, system))
+
+ 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 buildGauge(name: String)(currentValueCollector: Gauge.CurrentValueCollector): Gauge =
+ gauges.getOrElseUpdate(name, Gauge.fromConfig(defaultGaugePrecisionConfig, system)(currentValueCollector))
+
+ def collect(context: CollectionContext): UserMetricsSnapshot = {
+ val histogramSnapshots = histograms.map {
+ case (name, histogram) ⇒
+ (UserHistogram(name), histogram.collect(context))
+ } toMap
+
+ val counterSnapshots = counters.map {
+ case (name, counter) ⇒
+ (UserCounter(name), counter.collect(context))
+ } toMap
+
+ val minMaxCounterSnapshots = minMaxCounters.map {
+ case (name, minMaxCounter) ⇒
+ (UserMinMaxCounter(name), minMaxCounter.collect(context))
+ } toMap
+
+ val gaugeSnapshots = gauges.map {
+ case (name, gauge) ⇒
+ (UserGauge(name), gauge.collect(context))
+ } toMap
+
+ UserMetricsSnapshot(histogramSnapshots, counterSnapshots, minMaxCounterSnapshots, gaugeSnapshots)
+ }
+
+ def cleanup: Unit = {}
+ }
+
+ 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 class UserMetricsSnapshot(histograms: Map[UserHistogram, Histogram.Snapshot],
+ counters: Map[UserCounter, Counter.Snapshot],
+ minMaxCounters: Map[UserMinMaxCounter, Histogram.Snapshot],
+ gauges: Map[UserGauge, Histogram.Snapshot])
+ extends MetricGroupSnapshot {
+
+ type GroupSnapshotType = UserMetricsSnapshot
+
+ 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)))
+
+ def metrics: Map[MetricIdentity, MetricSnapshot] = histograms ++ counters ++ minMaxCounters ++ gauges
+ }
+
+}