diff options
Diffstat (limited to 'kamon-core/src/main/scala/kamon/metric/Metric.scala')
-rw-r--r-- | kamon-core/src/main/scala/kamon/metric/Metric.scala | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/kamon-core/src/main/scala/kamon/metric/Metric.scala b/kamon-core/src/main/scala/kamon/metric/Metric.scala new file mode 100644 index 00000000..58386353 --- /dev/null +++ b/kamon-core/src/main/scala/kamon/metric/Metric.scala @@ -0,0 +1,161 @@ +/* ========================================================================================= + * Copyright © 2013-2017 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 +package metric + +import java.util.concurrent.atomic.AtomicReference + +import kamon.metric.InstrumentFactory.InstrumentType +import kamon.metric.InstrumentFactory.InstrumentTypes._ +import kamon.util.MeasurementUnit + +import scala.collection.concurrent.TrieMap +import scala.concurrent.duration.Duration + + + +trait Metric[T] { + def name: String + def unit: MeasurementUnit + + def refine(tags: Tags): T + def refine(tags: (String, String)*): T + def refine(tag: String, value: String): T +} + +trait HistogramMetric extends Metric[Histogram] with Histogram +trait MinMaxCounterMetric extends Metric[MinMaxCounter] with MinMaxCounter +trait GaugeMetric extends Metric[Gauge] with Gauge +trait CounterMetric extends Metric[Counter] with Counter + + +abstract sealed class BaseMetric[T, S](val instrumentType: InstrumentType) extends Metric[T] { + private val instruments = TrieMap.empty[Tags, T] + protected lazy val baseInstrument: T = instruments.atomicGetOrElseUpdate(Map.empty, createInstrument(Map.empty)) + + def refine(tag: String, value: String): T = { + val instrumentTags = Map(tag -> value) + instruments.atomicGetOrElseUpdate(instrumentTags, createInstrument(instrumentTags)) + } + + def refine(tags: Map[String, String]): T = + instruments.atomicGetOrElseUpdate(tags, createInstrument(tags)) + + def refine(tags: (String, String)*): T = + refine(tags.toMap) + + + private[kamon] def snapshot(): Seq[S] = + instruments.values.map(createSnapshot).toSeq + + protected def createInstrument(tags: Tags): T + + protected def createSnapshot(instrument: T): S +} + + +private[kamon] final class HistogramMetricImpl(val name: String, val unit: MeasurementUnit, customDynamicRange: Option[DynamicRange], + factory: AtomicReference[InstrumentFactory]) extends BaseMetric[Histogram, MetricDistribution](Histogram) with HistogramMetric { + + def dynamicRange: DynamicRange = + baseInstrument.dynamicRange + + override def record(value: Long): Unit = + baseInstrument.record(value) + + override def record(value: Long, times: Long): Unit = + baseInstrument.record(value, times) + + override protected def createInstrument(tags: Tags): Histogram = + factory.get().buildHistogram(customDynamicRange)(name, tags, unit) + + override protected def createSnapshot(instrument: Histogram): MetricDistribution = + instrument.asInstanceOf[SnapshotableHistogram].snapshot() +} + +private[kamon] final class MinMaxCounterMetricImpl(val name: String, val unit: MeasurementUnit, customDynamicRange: Option[DynamicRange], + customSampleInterval: Option[Duration], factory: AtomicReference[InstrumentFactory]) + extends BaseMetric[MinMaxCounter, MetricDistribution](MinMaxCounter) with MinMaxCounterMetric { + + def dynamicRange: DynamicRange = + baseInstrument.dynamicRange + + override def sampleInterval: Duration = + baseInstrument.sampleInterval + + override def increment(): Unit = + baseInstrument.increment() + + override def increment(times: Long): Unit = + baseInstrument.increment(times) + + override def decrement(): Unit = + baseInstrument.decrement() + + override def decrement(times: Long): Unit = + baseInstrument.decrement(times) + + override def sample(): Unit = + baseInstrument.sample() + + override protected def createInstrument(tags: Tags): MinMaxCounter = + factory.get().buildMinMaxCounter(customDynamicRange, customSampleInterval)(name, tags, unit) + + override protected def createSnapshot(instrument: MinMaxCounter): MetricDistribution = + instrument.asInstanceOf[SnapshotableMinMaxCounter].snapshot() +} + + +private[kamon] final class CounterMetricImpl(val name: String, val unit: MeasurementUnit, factory: AtomicReference[InstrumentFactory]) + extends BaseMetric[Counter, MetricValue](Counter) with CounterMetric { + + override def increment(): Unit = + baseInstrument.increment() + + override def increment(times: Long): Unit = + baseInstrument.increment(times) + + override protected def createInstrument(tags: Tags): Counter = + factory.get().buildCounter(name, tags, unit) + + override protected def createSnapshot(instrument: Counter): MetricValue = + instrument.asInstanceOf[SnapshotableCounter].snapshot() +} + +private[kamon] final class GaugeMetricImpl(val name: String, val unit: MeasurementUnit, factory: AtomicReference[InstrumentFactory]) + extends BaseMetric[Gauge, MetricValue](Gauge) with GaugeMetric { + + override def increment(): Unit = + baseInstrument.increment() + + override def increment(times: Long): Unit = + baseInstrument.increment(times) + + override def decrement(): Unit = + baseInstrument.decrement() + + override def decrement(times: Long): Unit = + baseInstrument.decrement(times) + + override def set(value: Long): Unit = + baseInstrument.set(value) + + override protected def createInstrument(tags: Tags): Gauge = + factory.get().buildGauge(name, tags, unit) + + override protected def createSnapshot(instrument: Gauge): MetricValue = + instrument.asInstanceOf[SnapshotableGauge].snapshot() +}
\ No newline at end of file |