diff options
Diffstat (limited to 'kamon-core/src/main/scala/kamon/metric/instrument')
6 files changed, 205 insertions, 0 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 new file mode 100644 index 00000000..4a9edd77 --- /dev/null +++ b/kamon-core/src/main/scala/kamon/metric/instrument/Counter.scala @@ -0,0 +1,11 @@ +package kamon.metric.instrument + +import kamon.metric.Entity + +trait Counter { + def increment(): Unit +} + +object Counter { + def apply(entity: Entity, name: String): Counter = ??? +} diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/DynamicRange.scala b/kamon-core/src/main/scala/kamon/metric/instrument/DynamicRange.scala new file mode 100644 index 00000000..628439c2 --- /dev/null +++ b/kamon-core/src/main/scala/kamon/metric/instrument/DynamicRange.scala @@ -0,0 +1,33 @@ +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(0L, 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(0L, 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(0L, 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 new file mode 100644 index 00000000..43c71206 --- /dev/null +++ b/kamon-core/src/main/scala/kamon/metric/instrument/Gauge.scala @@ -0,0 +1,15 @@ +package kamon.metric.instrument + +import kamon.metric.Entity + +trait Gauge { + def increment(): Unit + def increment(times: Long): Unit + def decrement(): Unit + def decrement(times: Long): Unit + def set(value: Long): Unit +} + +object Gauge { + def apply(entity: Entity, name: String): Gauge = ??? +} diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/Histogram.scala b/kamon-core/src/main/scala/kamon/metric/instrument/Histogram.scala new file mode 100644 index 00000000..c43c9dbc --- /dev/null +++ b/kamon-core/src/main/scala/kamon/metric/instrument/Histogram.scala @@ -0,0 +1,18 @@ +package kamon.metric.instrument + +import kamon.metric.Entity + +trait Histogram { + def dynamicRange: DynamicRange + + def record(value: Long): Unit + def record(value: Long, times: Long): Unit +} + +object Histogram { + def apply(entity: Entity, name: String, dynamicRange2: DynamicRange): Histogram = new Histogram { + override def dynamicRange: DynamicRange = dynamicRange2 + override def record(value: Long): Unit = ??? + override def record(value: Long, times: Long): Unit = ??? + } +} diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/InstrumentFactory.scala b/kamon-core/src/main/scala/kamon/metric/instrument/InstrumentFactory.scala new file mode 100644 index 00000000..820c05b5 --- /dev/null +++ b/kamon-core/src/main/scala/kamon/metric/instrument/InstrumentFactory.scala @@ -0,0 +1,102 @@ +package kamon +package metric +package instrument + +import java.time.Duration + +import com.typesafe.config.Config +import kamon.metric.instrument.InstrumentFactory.CustomInstrumentSettings + + +private[kamon] class InstrumentFactory private ( + defaultHistogramDynamicRange: DynamicRange, + defaultMMCounterDynamicRange: DynamicRange, + defaultMMCounterSampleRate: Duration, + customSettings: Map[(String, String), CustomInstrumentSettings]) { + + def buildHistogram(entity: Entity, name: String, dynamicRange: DynamicRange = defaultHistogramDynamicRange): Histogram = + Histogram(entity, name, instrumentDynamicRange(entity, name, dynamicRange)) + + def buildMinMaxCounter(entity: Entity, name: String, dynamicRange: DynamicRange = defaultMMCounterDynamicRange, + sampleInterval: Duration = defaultMMCounterSampleRate): MinMaxCounter = + MinMaxCounter( + entity, + name, + instrumentDynamicRange(entity, name, dynamicRange), + instrumentSampleInterval(entity, name, sampleInterval) + ) + + def buildGauge(entity: Entity, name: String): Gauge = + Gauge(entity, name) + + def buildCounter(entity: Entity, name: String): Counter = + Counter(entity, name) + + + private def instrumentDynamicRange(entity: Entity, instrumentName: String, dynamicRange: DynamicRange): DynamicRange = + customSettings.get((entity.category, instrumentName)).fold(dynamicRange) { cs => + overrideDynamicRange(dynamicRange, cs) + } + + private def instrumentSampleInterval(entity: Entity, instrumentName: String, sampleInterval: Duration): Duration = + customSettings.get((entity.category, 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 apply(config: Config): InstrumentFactory = { + val histogramDynamicRange = readDynamicRange(config.getConfig("default-settings.histogram")) + val mmCounterDynamicRange = readDynamicRange(config.getConfig("default-settings.min-max-counter")) + val mmCounterSampleInterval = config.getDuration("default-settings.min-max-counter.sample-interval") + + val customSettings = config.getConfig("custom-settings") + .configurations + .filter(nonEmptyCategories) + .flatMap(buildCustomInstrumentSettings) + + new InstrumentFactory(histogramDynamicRange, mmCounterDynamicRange, mmCounterSampleInterval, customSettings) + } + + private def nonEmptyCategories(entry: (String, Config)): Boolean = entry match { + case (_, config) => config.firstLevelKeys.nonEmpty + } + + private def buildCustomInstrumentSettings(entry: (String, Config)): Map[(String, String), CustomInstrumentSettings] = { + val (category, categoryConfig) = entry + categoryConfig.configurations.map { + case (instrumentName, instrumentConfig) => (category, instrumentName) -> readCustomSettings(instrumentConfig) + } + } + + 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] + ) + + private def readCustomSettings(config: Config): CustomInstrumentSettings = + CustomInstrumentSettings( + if (config.hasPath("lowest-discernible-value")) Some(config.getLong("lowest-discernible-value")) else None, + if (config.hasPath("highest-trackable-value")) Some(config.getLong("highest-trackable-value")) else None, + if (config.hasPath("significant-value-digits")) Some(config.getInt("significant-value-digits")) else None, + if (config.hasPath("sample-interval")) Some(config.getDuration("sample-interval")) else None + ) +}
\ No newline at end of file diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/MinMaxCounter.scala b/kamon-core/src/main/scala/kamon/metric/instrument/MinMaxCounter.scala new file mode 100644 index 00000000..34a983a9 --- /dev/null +++ b/kamon-core/src/main/scala/kamon/metric/instrument/MinMaxCounter.scala @@ -0,0 +1,26 @@ +package kamon.metric.instrument + +import java.time.Duration + +import kamon.metric.Entity + +trait MinMaxCounter { + def dynamicRange: DynamicRange + def sampleInterval: Duration + + def increment(): Unit + def increment(times: Long): Unit + def decrement(): Unit + def decrement(times: Long): Unit +} + +object MinMaxCounter { + def apply(entity: Entity, name: String, dynamicRange2: DynamicRange, sampleInterval2: Duration): MinMaxCounter = new MinMaxCounter { + override def sampleInterval: Duration = sampleInterval2 + override def increment(): Unit = ??? + override def increment(times: Long): Unit = ??? + override def decrement(): Unit = ??? + override def decrement(times: Long): Unit = ??? + override def dynamicRange: DynamicRange = dynamicRange2 + } +} |