aboutsummaryrefslogtreecommitdiff
path: root/kamon-core/src/main/scala/kamon/metric/instrument
diff options
context:
space:
mode:
Diffstat (limited to 'kamon-core/src/main/scala/kamon/metric/instrument')
-rw-r--r--kamon-core/src/main/scala/kamon/metric/instrument/Counter.scala34
-rw-r--r--kamon-core/src/main/scala/kamon/metric/instrument/DynamicRange.scala33
-rw-r--r--kamon-core/src/main/scala/kamon/metric/instrument/Gauge.scala39
-rw-r--r--kamon-core/src/main/scala/kamon/metric/instrument/Histogram.scala193
-rw-r--r--kamon-core/src/main/scala/kamon/metric/instrument/HistogramExtension.scala39
-rw-r--r--kamon-core/src/main/scala/kamon/metric/instrument/InstrumentFactory.scala98
-rw-r--r--kamon-core/src/main/scala/kamon/metric/instrument/InstrumentSnapshot.scala57
-rw-r--r--kamon-core/src/main/scala/kamon/metric/instrument/MinMaxCounter.scala75
8 files changed, 0 insertions, 568 deletions
diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/Counter.scala b/kamon-core/src/main/scala/kamon/metric/instrument/Counter.scala
deleted file mode 100644
index f18e771c..00000000
--- a/kamon-core/src/main/scala/kamon/metric/instrument/Counter.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-package kamon
-package metric
-package instrument
-
-import java.util.concurrent.atomic.LongAdder
-
-import com.typesafe.scalalogging.StrictLogging
-import kamon.util.MeasurementUnit
-
-trait Counter {
- def measurementUnit: MeasurementUnit
-
- def increment(): Unit
- def increment(times: Long): Unit
-}
-
-class LongAdderCounter(name: String, tags: Map[String, String], val measurementUnit: MeasurementUnit)
- extends SnapshotableCounter with StrictLogging {
-
- private val adder = new LongAdder()
-
- def increment(): Unit =
- adder.increment()
-
- def increment(times: Long): Unit = {
- if (times >= 0)
- adder.add(times)
- else
- logger.warn(s"Ignored attempt to decrement counter [$name]")
- }
-
- def snapshot(): SingleValueSnapshot =
- SingleValueSnapshot(name, tags, measurementUnit, adder.sumThenReset())
-}
diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/DynamicRange.scala b/kamon-core/src/main/scala/kamon/metric/instrument/DynamicRange.scala
deleted file mode 100644
index 226f5450..00000000
--- a/kamon-core/src/main/scala/kamon/metric/instrument/DynamicRange.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-package kamon.metric.instrument
-
-import java.util.concurrent.TimeUnit
-
-case class DynamicRange(lowestDiscernibleValue: Long, highestTrackableValue: Long, significantValueDigits: Int) {
- def upTo(highestTrackableValue: Long): DynamicRange =
- copy(highestTrackableValue = highestTrackableValue)
-
- def startingFrom(lowestDiscernibleValue: Long): DynamicRange =
- copy(lowestDiscernibleValue = lowestDiscernibleValue)
-}
-
-object DynamicRange {
- private val oneHourInNanoseconds = TimeUnit.HOURS.toNanos(1)
-
- /**
- * Provides a range from 0 to 3.6e+12 (one hour in nanoseconds) with a value precision of 1 significant digit (10%)
- * across that range.
- */
- val Loose = DynamicRange(1L, oneHourInNanoseconds, 1)
-
- /**
- * Provides a range from 0 to 3.6e+12 (one hour in nanoseconds) with a value precision of 2 significant digit (1%)
- * across that range.
- */
- val Default = DynamicRange(1L, oneHourInNanoseconds, 2)
-
- /**
- * Provides a range from 0 to 3.6e+12 (one hour in nanoseconds) with a value precision of 3 significant digit (0.1%)
- * across that range.
- */
- val Fine = DynamicRange(1L, oneHourInNanoseconds, 3)
-}
diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/Gauge.scala b/kamon-core/src/main/scala/kamon/metric/instrument/Gauge.scala
deleted file mode 100644
index acbff912..00000000
--- a/kamon-core/src/main/scala/kamon/metric/instrument/Gauge.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-package kamon.metric.instrument
-
-import java.util.concurrent.atomic.AtomicLong
-import kamon.util.MeasurementUnit
-
-trait Gauge {
- def measurementUnit: MeasurementUnit
-
- def increment(): Unit
- def increment(times: Long): Unit
- def decrement(): Unit
- def decrement(times: Long): Unit
- def set(value: Long): Unit
-}
-
-
-class AtomicLongGauge(name: String, tags: Map[String, String], val measurementUnit: MeasurementUnit)
- extends SnapshotableGauge {
-
- private val currentValue = new AtomicLong(0L)
-
- def increment(): Unit =
- currentValue.incrementAndGet()
-
- def increment(times: Long): Unit =
- currentValue.addAndGet(times)
-
- def decrement(): Unit =
- currentValue.decrementAndGet()
-
- def decrement(times: Long): Unit =
- currentValue.addAndGet(-times)
-
- def set(value: Long): Unit =
- currentValue.set(value)
-
- def snapshot(): SingleValueSnapshot =
- SingleValueSnapshot(name, tags, measurementUnit, currentValue.get())
-}
diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/Histogram.scala b/kamon-core/src/main/scala/kamon/metric/instrument/Histogram.scala
deleted file mode 100644
index 29fe8c69..00000000
--- a/kamon-core/src/main/scala/kamon/metric/instrument/Histogram.scala
+++ /dev/null
@@ -1,193 +0,0 @@
-package kamon
-package metric
-package instrument
-
-import java.nio.ByteBuffer
-
-import com.typesafe.scalalogging.StrictLogging
-import kamon.util.MeasurementUnit
-import org.HdrHistogram.{AtomicHistogramExtension, ZigZag}
-
-trait Histogram {
- def dynamicRange: DynamicRange
- def measurementUnit: MeasurementUnit
-
- def record(value: Long): Unit
- def record(value: Long, times: Long): Unit
-}
-
-
-class HdrHistogram(name: String, tags: Map[String, String], val measurementUnit: MeasurementUnit, val dynamicRange: DynamicRange)
- extends AtomicHistogramExtension(dynamicRange) with SnapshotableHistogram with StrictLogging {
-
- def record(value: Long): Unit =
- tryRecord(value, 1)
-
- def record(value: Long, count: Long): Unit =
- tryRecord(value, count)
-
- private def tryRecord(value: Long, count: Long): Unit = {
- try {
- recordValueWithCount(value, count)
- } catch {
- case anyException: Throwable ⇒
- logger.warn(s"Failed to store value [$value] in histogram [$name]. You might need to change " +
- "your dynamic range configuration for this instrument.", anyException)
- }
- }
-
- override def snapshot(): DistributionSnapshot = {
- val buffer = HdrHistogram.tempSnapshotBuffer.get()
- val counts = countsArray()
- val countsLimit = counts.length()
- var index = 0
- buffer.clear()
-
- var minIndex = Int.MaxValue
- var maxIndex = 0
- var totalCount = 0L
-
- while(index < countsLimit) {
- val countAtIndex = counts.getAndSet(index, 0L)
-
- var zerosCount = 0L
- if(countAtIndex == 0L) {
- index += 1
- zerosCount = 1
- while(index < countsLimit && counts.get(index) == 0L) {
- index += 1
- zerosCount += 1
- }
- }
-
- if(zerosCount > 0) {
- if(index < countsLimit)
- ZigZag.putLong(buffer, -zerosCount)
- }
- else {
- if(minIndex > index)
- minIndex = index
- maxIndex = index
-
- index += 1
- totalCount += countAtIndex
- ZigZag.putLong(buffer, countAtIndex)
- }
- }
-
- buffer.flip()
- val zigZagCounts = Array.ofDim[Byte](buffer.limit())
- buffer.get(zigZagCounts)
-
- val distribution = new ZigZagCountsDistribution(totalCount, minIndex, maxIndex, ByteBuffer.wrap(zigZagCounts),
- protectedUnitMagnitude(), protectedSubBucketHalfCount(), protectedSubBucketHalfCountMagnitude())
-
- DistributionSnapshot(name, tags, measurementUnit, dynamicRange, distribution)
- }
-
- private class ZigZagCountsDistribution(val count: Long, minIndex: Int, maxIndex: Int, zigZagCounts: ByteBuffer,
- unitMagnitude: Int, subBucketHalfCount: Int, subBucketHalfCountMagnitude: Int) extends Distribution {
-
- val min: Long = if(count == 0) 0 else bucketValueAtIndex(minIndex)
- val max: Long = bucketValueAtIndex(maxIndex)
- def sum: Long = bucketsIterator.foldLeft(0L)((a, b) => a + (b.value * b.frequency))
-
- def buckets: Seq[Bucket] = {
- val builder = Vector.newBuilder[Bucket]
- bucketsIterator.foreach { b =>
- builder += DefaultBucket(b.value, b.frequency)
- }
-
- builder.result()
- }
-
- def bucketsIterator: Iterator[Bucket] = new Iterator[Bucket] {
- val buffer = zigZagCounts.duplicate()
- val bucket = MutableBucket(0, 0)
- var countsArrayIndex = 0
-
- def hasNext: Boolean =
- buffer.remaining() > 0
-
- def next(): Bucket = {
- val readLong = ZigZag.getLong(buffer)
- val frequency = if(readLong > 0) {
- readLong
- } else {
- countsArrayIndex += (-readLong.toInt)
- ZigZag.getLong(buffer)
- }
-
- bucket.value = bucketValueAtIndex(countsArrayIndex)
- bucket.frequency = frequency
- countsArrayIndex += 1
- bucket
- }
- }
-
- def percentilesIterator: Iterator[Percentile] = new Iterator[Percentile]{
- val buckets = bucketsIterator
- val percentile = MutablePercentile(0D, 0, 0)
- var countUnderQuantile = 0L
-
- def hasNext: Boolean =
- buckets.hasNext
-
- def next(): Percentile = {
- val bucket = buckets.next()
- countUnderQuantile += bucket.frequency
- percentile.quantile = (countUnderQuantile * 100D) / ZigZagCountsDistribution.this.count
- percentile.countUnderQuantile = countUnderQuantile
- percentile.value = bucket.value
- percentile
- }
- }
-
- def percentile(p: Double): Percentile = {
- val percentiles = percentilesIterator
- if(percentiles.hasNext) {
- var currentPercentile = percentiles.next()
- while(percentiles.hasNext && currentPercentile.quantile < p) {
- currentPercentile = percentiles.next()
- }
-
- currentPercentile
-
- } else DefaultPercentile(p, 0, 0)
- }
-
-
- def percentiles: Seq[Percentile] = {
- val builder = Vector.newBuilder[Percentile]
- percentilesIterator.foreach { p =>
- builder += DefaultPercentile(p.quantile, p.value, p.countUnderQuantile)
- }
-
- builder.result()
- }
-
- @inline private def bucketValueAtIndex(index: Int): Long = {
- var bucketIndex: Int = (index >> subBucketHalfCountMagnitude) - 1
- var subBucketIndex: Int = (index & (subBucketHalfCount - 1)) + subBucketHalfCount
- if (bucketIndex < 0) {
- subBucketIndex -= subBucketHalfCount
- bucketIndex = 0
- }
-
- subBucketIndex.toLong << (bucketIndex + unitMagnitude)
- }
- }
-
- case class DefaultBucket(value: Long, frequency: Long) extends Bucket
- case class MutableBucket(var value: Long, var frequency: Long) extends Bucket
-
- case class DefaultPercentile(quantile: Double, value: Long, countUnderQuantile: Long) extends Percentile
- case class MutablePercentile(var quantile: Double, var value: Long, var countUnderQuantile: Long) extends Percentile
-}
-
-object HdrHistogram {
- // TODO: move this to some object pool might be better, or at
- private val tempSnapshotBuffer = new ThreadLocal[ByteBuffer] {
- override def initialValue(): ByteBuffer = ByteBuffer.allocate(33792)
- }
-} \ No newline at end of file
diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/HistogramExtension.scala b/kamon-core/src/main/scala/kamon/metric/instrument/HistogramExtension.scala
deleted file mode 100644
index dc3cad08..00000000
--- a/kamon-core/src/main/scala/kamon/metric/instrument/HistogramExtension.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.HdrHistogram
-
-import java.nio.ByteBuffer
-import java.util.concurrent.atomic.AtomicLongArray
-
-import kamon.metric.instrument.DynamicRange
-
-/**
- * Exposes package-private members of [[org.HdrHistogram.AtomicHistogram]].
- */
-abstract class AtomicHistogramExtension(dr: DynamicRange)
- extends AtomicHistogram(dr.lowestDiscernibleValue, dr.highestTrackableValue, dr.significantValueDigits) {
-
- override def incrementTotalCount(): Unit = {}
- override def addToTotalCount(value: Long): Unit = {}
-
- def countsArray(): AtomicLongArray = counts
- def protectedUnitMagnitude(): Int = unitMagnitude
- def protectedSubBucketHalfCount(): Int = subBucketHalfCount
- def protectedSubBucketHalfCountMagnitude(): Int = subBucketHalfCountMagnitude
-}
-
-/**
- * Exposes the package-private members of [[org.HdrHistogram.ZigZagEncoding]].
- */
-object ZigZag {
- def putLong(buffer: ByteBuffer, value: Long): Unit =
- ZigZagEncoding.putLong(buffer, value)
-
- def getLong(buffer: ByteBuffer): Long =
- ZigZagEncoding.getLong(buffer)
-
- def putInt(buffer: ByteBuffer, value: Int): Unit =
- ZigZagEncoding.putInt(buffer, value)
-
- def getInt(buffer: ByteBuffer): Int =
- ZigZagEncoding.getInt(buffer)
-}
-
diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/InstrumentFactory.scala b/kamon-core/src/main/scala/kamon/metric/instrument/InstrumentFactory.scala
deleted file mode 100644
index 0e0536c6..00000000
--- a/kamon-core/src/main/scala/kamon/metric/instrument/InstrumentFactory.scala
+++ /dev/null
@@ -1,98 +0,0 @@
-package kamon
-package metric
-package instrument
-
-import java.time.Duration
-
-import com.typesafe.config.Config
-import kamon.metric.instrument.InstrumentFactory.CustomInstrumentSettings
-import kamon.util.MeasurementUnit
-
-
-private[kamon] class InstrumentFactory private (defaultHistogramDynamicRange: DynamicRange, defaultMMCounterDynamicRange: DynamicRange,
- defaultMMCounterSampleInterval: Duration, customSettings: Map[String, CustomInstrumentSettings]) {
-
- println("DEFAULT: " + defaultHistogramDynamicRange)
-
- def buildHistogram(dynamicRange: Option[DynamicRange])(name: String, tags: Map[String, String], unit: MeasurementUnit): SnapshotableHistogram =
- new HdrHistogram(name, tags, unit, instrumentDynamicRange(name, dynamicRange.getOrElse(defaultHistogramDynamicRange)))
-
- def buildMinMaxCounter(dynamicRange: Option[DynamicRange], sampleInterval: Option[Duration])
- (name: String, tags: Map[String, String], unit: MeasurementUnit): SnapshotableMinMaxCounter =
- new PaddedMinMaxCounter(
- name,
- tags,
- buildHistogram(dynamicRange.orElse(Some(defaultMMCounterDynamicRange)))(name, tags, unit),
- instrumentSampleInterval(name, sampleInterval.getOrElse(defaultMMCounterSampleInterval)) )
-
- def buildGauge(name: String, tags: Map[String, String], unit: MeasurementUnit): SnapshotableGauge =
- new AtomicLongGauge(name, tags, unit)
-
- def buildCounter(name: String, tags: Map[String, String], unit: MeasurementUnit): SnapshotableCounter =
- new LongAdderCounter(name, tags, unit)
-
-
- private def instrumentDynamicRange(instrumentName: String, dynamicRange: DynamicRange): DynamicRange =
- customSettings.get(instrumentName).fold(dynamicRange) { cs =>
- overrideDynamicRange(dynamicRange, cs)
- }
-
- private def instrumentSampleInterval(instrumentName: String, sampleInterval: Duration): Duration =
- customSettings.get(instrumentName).fold(sampleInterval) { cs =>
- cs.sampleInterval.getOrElse(sampleInterval)
- }
-
- private def overrideDynamicRange(defaultDynamicRange: DynamicRange, customSettings: CustomInstrumentSettings): DynamicRange =
- DynamicRange(
- customSettings.lowestDiscernibleValue.getOrElse(defaultDynamicRange.lowestDiscernibleValue),
- customSettings.highestTrackableValue.getOrElse(defaultDynamicRange.highestTrackableValue),
- customSettings.significantValueDigits.getOrElse(defaultDynamicRange.significantValueDigits)
- )
-}
-
-object InstrumentFactory {
-
- def fromConfig(config: Config): InstrumentFactory = {
- val factoryConfig = config.getConfig("kamon.metric.instrument-factory")
- val histogramDynamicRange = readDynamicRange(factoryConfig.getConfig("default-settings.histogram"))
- val mmCounterDynamicRange = readDynamicRange(factoryConfig.getConfig("default-settings.min-max-counter"))
- val mmCounterSampleInterval = factoryConfig.getDuration("default-settings.min-max-counter.sample-interval")
-
- val customSettings = factoryConfig.getConfig("custom-settings")
- .configurations
- .filter(nonEmptySection)
- .map(readCustomInstrumentSettings)
-
- new InstrumentFactory(histogramDynamicRange, mmCounterDynamicRange, mmCounterSampleInterval, customSettings)
- }
-
- private def nonEmptySection(entry: (String, Config)): Boolean = entry match {
- case (_, config) => config.firstLevelKeys.nonEmpty
- }
-
- private def readCustomInstrumentSettings(entry: (String, Config)): (String, CustomInstrumentSettings) = {
- val (metricName, metricConfig) = entry
- val customSettings = CustomInstrumentSettings(
- if (metricConfig.hasPath("lowest-discernible-value")) Some(metricConfig.getLong("lowest-discernible-value")) else None,
- if (metricConfig.hasPath("highest-trackable-value")) Some(metricConfig.getLong("highest-trackable-value")) else None,
- if (metricConfig.hasPath("significant-value-digits")) Some(metricConfig.getInt("significant-value-digits")) else None,
- if (metricConfig.hasPath("sample-interval")) Some(metricConfig.getDuration("sample-interval")) else None
- )
-
- (metricName -> customSettings)
- }
-
- private def readDynamicRange(config: Config): DynamicRange =
- DynamicRange(
- lowestDiscernibleValue = config.getLong("lowest-discernible-value"),
- highestTrackableValue = config.getLong("highest-trackable-value"),
- significantValueDigits = config.getInt("significant-value-digits")
- )
-
- private case class CustomInstrumentSettings(
- lowestDiscernibleValue: Option[Long],
- highestTrackableValue: Option[Long],
- significantValueDigits: Option[Int],
- sampleInterval: Option[Duration]
- )
-} \ No newline at end of file
diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/InstrumentSnapshot.scala b/kamon-core/src/main/scala/kamon/metric/instrument/InstrumentSnapshot.scala
deleted file mode 100644
index 1364c2d8..00000000
--- a/kamon-core/src/main/scala/kamon/metric/instrument/InstrumentSnapshot.scala
+++ /dev/null
@@ -1,57 +0,0 @@
-package kamon.metric.instrument
-
-import kamon.util.MeasurementUnit
-
-/**
- * Snapshot for instruments that internally track a single value. Meant to be used for counters and gauges.
- *
- */
-case class SingleValueSnapshot(name: String, tags: Map[String, String], measurementUnit: MeasurementUnit, value: Long)
-
-/**
- * Snapshot for instruments that internally the distribution of values in a defined dynamic range. Meant to be used
- * with histograms and min max counters.
- */
-case class DistributionSnapshot(name: String, tags: Map[String, String], measurementUnit: MeasurementUnit,
- dynamicRange: DynamicRange, distribution: Distribution)
-
-
-trait Distribution {
- def buckets: Seq[Bucket]
- def bucketsIterator: Iterator[Bucket]
-
- def min: Long
- def max: Long
- def sum: Long
- def count: Long
- def percentile(p: Double): Percentile
-
- def percentiles: Seq[Percentile]
- def percentilesIterator: Iterator[Percentile]
-}
-
-trait Bucket {
- def value: Long
- def frequency: Long
-}
-
-trait Percentile {
- def quantile: Double
- def value: Long
- def countUnderQuantile: Long
-}
-
-
-trait DistributionSnapshotInstrument {
- private[kamon] def snapshot(): DistributionSnapshot
-}
-
-trait SingleValueSnapshotInstrument {
- private[kamon] def snapshot(): SingleValueSnapshot
-}
-
-trait SnapshotableHistogram extends Histogram with DistributionSnapshotInstrument
-trait SnapshotableMinMaxCounter extends MinMaxCounter with DistributionSnapshotInstrument
-trait SnapshotableCounter extends Counter with SingleValueSnapshotInstrument
-trait SnapshotableGauge extends Gauge with SingleValueSnapshotInstrument
-
diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/MinMaxCounter.scala b/kamon-core/src/main/scala/kamon/metric/instrument/MinMaxCounter.scala
deleted file mode 100644
index 70094b7b..00000000
--- a/kamon-core/src/main/scala/kamon/metric/instrument/MinMaxCounter.scala
+++ /dev/null
@@ -1,75 +0,0 @@
-package kamon.metric.instrument
-
-import java.lang.Math.abs
-import java.time.Duration
-import java.util.concurrent.atomic.{AtomicLong, AtomicReference}
-
-import kamon.jsr166.LongMaxUpdater
-import kamon.util.MeasurementUnit
-
-trait MinMaxCounter {
- def dynamicRange: DynamicRange
- def sampleInterval: Duration
- def measurementUnit: MeasurementUnit
-
- def increment(): Unit
- def increment(times: Long): Unit
- def decrement(): Unit
- def decrement(times: Long): Unit
- def sample(): Unit
-}
-
-
-class PaddedMinMaxCounter(name: String, tags: Map[String, String], underlyingHistogram: Histogram with DistributionSnapshotInstrument,
- val sampleInterval: Duration) extends SnapshotableMinMaxCounter {
-
- private val min = new LongMaxUpdater(0L)
- private val max = new LongMaxUpdater(0L)
- private val sum = new AtomicLong()
-
- def dynamicRange: DynamicRange =
- underlyingHistogram.dynamicRange
-
- def measurementUnit: MeasurementUnit =
- underlyingHistogram.measurementUnit
-
- private[kamon] def snapshot(): DistributionSnapshot =
- underlyingHistogram.snapshot()
-
- def increment(): Unit =
- increment(1L)
-
- def increment(times: Long): Unit = {
- val currentValue = sum.addAndGet(times)
- max.update(currentValue)
- }
-
- def decrement(): Unit =
- decrement(1L)
-
- def decrement(times: Long): Unit = {
- val currentValue = sum.addAndGet(-times)
- min.update(-currentValue)
- }
-
- def sample(): Unit = {
- val currentValue = {
- val value = sum.get()
- if (value <= 0) 0 else value
- }
-
- val currentMin = {
- val rawMin = min.maxThenReset(-currentValue)
- if (rawMin >= 0)
- 0
- else
- abs(rawMin)
- }
-
- val currentMax = max.maxThenReset(currentValue)
-
- underlyingHistogram.record(currentValue)
- underlyingHistogram.record(currentMin)
- underlyingHistogram.record(currentMax)
- }
-} \ No newline at end of file