diff options
author | Ivan Topolnjak <ivantopo@gmail.com> | 2017-12-13 23:32:30 +0100 |
---|---|---|
committer | Ivan Topolnjak <ivantopo@gmail.com> | 2017-12-14 00:05:55 +0100 |
commit | 622c8d12735c1a8de3716984686e52bc33368004 (patch) | |
tree | 6665d553b6fbea36391e7eb4b25f2fbfc4526f58 /kamon-core/src/main/scala/kamon/util/Clock.scala | |
parent | 4a2d29852c8fc558ae1eaf61a25bde5a0bc161bc (diff) | |
download | Kamon-622c8d12735c1a8de3716984686e52bc33368004.tar.gz Kamon-622c8d12735c1a8de3716984686e52bc33368004.tar.bz2 Kamon-622c8d12735c1a8de3716984686e52bc33368004.zip |
use java.time.Instant with nanoseconds precision in the Tracer
Diffstat (limited to 'kamon-core/src/main/scala/kamon/util/Clock.scala')
-rw-r--r-- | kamon-core/src/main/scala/kamon/util/Clock.scala | 59 |
1 files changed, 50 insertions, 9 deletions
diff --git a/kamon-core/src/main/scala/kamon/util/Clock.scala b/kamon-core/src/main/scala/kamon/util/Clock.scala index 4f4561b5..48a88968 100644 --- a/kamon-core/src/main/scala/kamon/util/Clock.scala +++ b/kamon-core/src/main/scala/kamon/util/Clock.scala @@ -18,26 +18,67 @@ package kamon.util import java.time.{Instant, ZoneId, Clock => JavaClock} abstract class Clock extends JavaClock { - def micros(): Long - def relativeNanos(): Long + def nanos(): Long + def nanosBetween(left: Instant, right: Instant): Long + def toInstant(nanos: Long): Instant } object Clock { + private val MillisInSecond = 1000L + private val MicrosInSecond = 1000000L + private val NanosInSecond = 1000000000L + class Default extends Clock { private val systemClock = JavaClock.systemUTC() - private val startTimeMillis = System.currentTimeMillis() - private val startNanoTime = System.nanoTime() - private val startMicroTime = startTimeMillis * 1000L + private val (startTimeMillis, startNanoTime) = { + var calibrationIterations = 1000 + var millis = System.currentTimeMillis() + var nanos = System.nanoTime() + var isCandidate = false + + while(calibrationIterations > 0) { + val currentMillis = System.currentTimeMillis() + val currentNanos = System.nanoTime() + + if(isCandidate && millis != currentMillis) { + millis = currentMillis + nanos = currentNanos + calibrationIterations = 0 + } else { + if(millis == currentMillis) { + isCandidate = true + } else { + millis = currentMillis + nanos = currentNanos + } + } + + calibrationIterations -= 1 + } - override def micros(): Long = - startMicroTime + ((System.nanoTime() - startNanoTime) / 1000L) + (millis, nanos) + } - override def relativeNanos(): Long = + private val startSecondTime = Math.floorDiv(startTimeMillis, MillisInSecond) + private val startSecondNanoOffset = Math.multiplyExact(Math.floorMod(startTimeMillis, MillisInSecond), MicrosInSecond) + + override def nanos(): Long = System.nanoTime() + override def toInstant(nanos: Long): Instant = { + val nanoOffset = nanos - startNanoTime + startSecondNanoOffset + Instant.ofEpochSecond(startSecondTime, nanoOffset) + } + override def instant(): Instant = - systemClock.instant() + toInstant(System.nanoTime()) + + override def nanosBetween(left: Instant, right: Instant): Long = { + val secsDiff = Math.subtractExact(right.getEpochSecond, left.getEpochSecond) + val totalNanos = Math.multiplyExact(secsDiff, NanosInSecond) + return Math.addExact(totalNanos, right.getNano - left.getNano) + } override def withZone(zone: ZoneId): JavaClock = systemClock.withZone(zone) |