From 4a918ce6570129d3d4fd2d3e98d43f8078bb2d99 Mon Sep 17 00:00:00 2001 From: Eugene Platonov Date: Tue, 1 Dec 2015 13:26:50 -0500 Subject: + core: provide generic way to scale time and memory metrics --- .../metric/instrument/UnitOfMeasurement.scala | 40 +++++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'kamon-core/src/main/scala/kamon/metric/instrument/UnitOfMeasurement.scala') diff --git a/kamon-core/src/main/scala/kamon/metric/instrument/UnitOfMeasurement.scala b/kamon-core/src/main/scala/kamon/metric/instrument/UnitOfMeasurement.scala index c5a1b81a..5952b906 100644 --- a/kamon-core/src/main/scala/kamon/metric/instrument/UnitOfMeasurement.scala +++ b/kamon-core/src/main/scala/kamon/metric/instrument/UnitOfMeasurement.scala @@ -22,14 +22,27 @@ package kamon.metric.instrument * recorders and might be used to scale certain kinds of measurements in metric backends. */ trait UnitOfMeasurement { + type U <: UnitOfMeasurement + def name: String def label: String + def scale(toUnit: U)(value: Double): Double = value + + def tryScale(toUnit: UnitOfMeasurement)(value: Double): Double = + if (canScale(toUnit)) scale(toUnit.asInstanceOf[U])(value) + else throw new IllegalArgumentException(s"Can't scale different types of units `$name` and `${toUnit.name}`") + + protected def canScale(toUnit: UnitOfMeasurement): Boolean + } object UnitOfMeasurement { case object Unknown extends UnitOfMeasurement { + override type U = Unknown.type val name = "unknown" val label = "unknown" + + override protected def canScale(toUnit: UnitOfMeasurement): Boolean = UnitOfMeasurement.isUnknown(toUnit) } def isUnknown(uom: UnitOfMeasurement): Boolean = @@ -47,10 +60,13 @@ object UnitOfMeasurement { * UnitOfMeasurement representing time. */ case class Time(factor: Double, label: String) extends UnitOfMeasurement { + override type U = Time val name = "time" - def scale(toUnit: Time)(value: Double): Double = + override def scale(toUnit: Time)(value: Double): Double = (value * factor) / toUnit.factor + + override protected def canScale(toUnit: UnitOfMeasurement): Boolean = UnitOfMeasurement.isTime(toUnit) } object Time { @@ -58,22 +74,36 @@ object Time { val Microseconds = Time(1E-6, "µs") val Milliseconds = Time(1E-3, "ms") val Seconds = Time(1, "s") + + val units = List(Nanoseconds, Microseconds, Milliseconds, Seconds) + + def apply(time: String): Time = units.find(_.label.toLowerCase == time.toLowerCase) getOrElse { + throw new IllegalArgumentException(s"Can't recognize time unit '$time'") + } } /** * UnitOfMeasurement representing computer memory space. */ case class Memory(factor: Double, label: String) extends UnitOfMeasurement { + override type U = Memory val name = "bytes" - def scale(toUnit: Memory)(value: Double): Double = + override def scale(toUnit: Memory)(value: Double): Double = (value * factor) / toUnit.factor + + override protected def canScale(toUnit: UnitOfMeasurement): Boolean = UnitOfMeasurement.isMemory(toUnit) } object Memory { val Bytes = Memory(1, "b") val KiloBytes = Memory(1024, "Kb") - val MegaBytes = Memory(1024E2, "Mb") - val GigaBytes = Memory(1024E3, "Gb") -} + val MegaBytes = Memory(1024 * 1024, "Mb") + val GigaBytes = Memory(1024 * 1024 * 1024, "Gb") + val units = List(Bytes, KiloBytes, MegaBytes, GigaBytes) + + def apply(memory: String): Memory = units.find(_.label.toLowerCase == memory.toLowerCase) getOrElse { + throw new IllegalArgumentException(s"Can't recognize memory unit '$memory'") + } +} -- cgit v1.2.3