diff options
Diffstat (limited to 'kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala')
-rw-r--r-- | kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala b/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala index 34b68f38..973eab5a 100644 --- a/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala +++ b/kamon-core/src/main/scala/kamon/trace/MetricsOnlyContext.scala @@ -1,6 +1,6 @@ /* * ========================================================================================= - * Copyright © 2013-2014 the kamon project <http://kamon.io/> + * Copyright © 2013-2016 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 @@ -21,17 +21,18 @@ import java.util.concurrent.ConcurrentLinkedQueue import akka.event.LoggingAdapter import kamon.Kamon import kamon.metric.{ SegmentMetrics, TraceMetrics } +import kamon.trace.States.Status import kamon.util.{ NanoInterval, RelativeNanoTimestamp } import scala.annotation.tailrec import scala.collection.concurrent.TrieMap -private[kamon] class MetricsOnlyContext(traceName: String, val token: String, traceTags: Map[String, String], izOpen: Boolean, val levelOfDetail: LevelOfDetail, +private[kamon] class MetricsOnlyContext(traceName: String, val token: String, traceTags: Map[String, String], currentStatus: Status, val levelOfDetail: LevelOfDetail, val startTimestamp: RelativeNanoTimestamp, log: LoggingAdapter) extends TraceContext { @volatile private var _name = traceName - @volatile private var _isOpen = izOpen + @volatile private var _status = currentStatus @volatile protected var _elapsedTime = NanoInterval.default private val _finishedSegments = new ConcurrentLinkedQueue[SegmentLatencyData]() @@ -39,30 +40,38 @@ private[kamon] class MetricsOnlyContext(traceName: String, val token: String, tr private val _tags = TrieMap.empty[String, String] ++= traceTags def rename(newName: String): Unit = - if (isOpen) + if (States.Open == status) _name = newName else log.warning("Can't rename trace from [{}] to [{}] because the trace is already closed.", name, newName) def name: String = _name def isEmpty: Boolean = false - def isOpen: Boolean = _isOpen - + def status: Status = _status def addMetadata(key: String, value: String): Unit = {} - def addTag(key: String, value: String): Unit = _tags.put(key, value) def removeTag(key: String, value: String): Boolean = _tags.remove(key, value) - def finish(): Unit = { - _isOpen = false + private def finish(withError: Boolean): Unit = { + _status = if (withError) States.FinishedWithError else States.FinishedSuccessfully val traceElapsedTime = NanoInterval.since(startTimestamp) _elapsedTime = traceElapsedTime - if (Kamon.metrics.shouldTrack(name, TraceMetrics.category)) - Kamon.metrics.entity(TraceMetrics, name, _tags.toMap).elapsedTime.record(traceElapsedTime.nanos) + if (Kamon.metrics.shouldTrack(name, TraceMetrics.category)) { + val traceEntity = Kamon.metrics.entity(TraceMetrics, name) + traceEntity.elapsedTime.record(traceElapsedTime.nanos) + if (withError) traceEntity.errors.increment() + } drainFinishedSegments() } + def finish(): Unit = finish(withError = false) + + def finishWithError(cause: Throwable): Unit = { + //we should do something with the Throwable in a near future + finish(withError = true) + } + def startSegment(segmentName: String, category: String, library: String): Segment = startSegment(segmentName, category, library, Map.empty[String, String]) @@ -77,14 +86,17 @@ private[kamon] class MetricsOnlyContext(traceName: String, val token: String, tr "category" -> segment.category, "library" -> segment.library) - if (Kamon.metrics.shouldTrack(segment.name, SegmentMetrics.category)) - Kamon.metrics.entity(SegmentMetrics, segment.name, defaultTags ++ segment.tags).elapsedTime.record(segment.duration.nanos) + if (Kamon.metrics.shouldTrack(segment.name, SegmentMetrics.category)) { + val segmentEntity = Kamon.metrics.entity(SegmentMetrics, segment.name, defaultTags ++ segment.tags) + segmentEntity.elapsedTime.record(segment.duration.nanos) + if (segment.isFinishedWithError) segmentEntity.errors.increment() + } drainFinishedSegments() } } - protected def finishSegment(segmentName: String, category: String, library: String, duration: NanoInterval, segmentTags: Map[String, String]): Unit = { - _finishedSegments.add(SegmentLatencyData(segmentName, category, library, duration, segmentTags)) + protected def finishSegment(segmentName: String, category: String, library: String, duration: NanoInterval, segmentTags: Map[String, String], isFinishedWithError: Boolean): Unit = { + _finishedSegments.add(SegmentLatencyData(segmentName, category, library, duration, segmentTags, isFinishedWithError)) if (isClosed) { drainFinishedSegments() @@ -104,36 +116,42 @@ private[kamon] class MetricsOnlyContext(traceName: String, val token: String, tr @volatile private var _segmentName = segmentName @volatile private var _elapsedTime = NanoInterval.default - @volatile private var _isOpen = true + @volatile private var _status: Status = States.Open def name: String = _segmentName def isEmpty: Boolean = false - def isOpen: Boolean = _isOpen - + def status: Status = _status def addMetadata(key: String, value: String): Unit = {} - def addTag(key: String, value: String): Unit = _tags.put(key, value) def removeTag(key: String, value: String): Boolean = _tags.remove(key, value) def rename(newName: String): Unit = - if (isOpen) + if (States.Open == status) _segmentName = newName else log.warning("Can't rename segment from [{}] to [{}] because the segment is already closed.", name, newName) - def finish: Unit = { - _isOpen = false + private def finish(withError: Boolean): Unit = { + _status = if (withError) States.FinishedWithError else States.FinishedSuccessfully val segmentElapsedTime = NanoInterval.since(_startTimestamp) _elapsedTime = segmentElapsedTime - finishSegment(name, category, library, segmentElapsedTime, _tags.toMap) + finishSegment(name, category, library, segmentElapsedTime, _tags.toMap, withError) + } + + def finishWithError(cause: Throwable): Unit = { + //we should do something with the Throwable in a near future + finish(withError = true) } + def finish(): Unit = finish(withError = false) + // Handle with care and make sure that the segment is closed before calling this method, otherwise // NanoInterval.default will be returned. def elapsedTime: NanoInterval = _elapsedTime def startTimestamp: RelativeNanoTimestamp = _startTimestamp + } } -case class SegmentLatencyData(name: String, category: String, library: String, duration: NanoInterval, tags: Map[String, String]) +case class SegmentLatencyData(name: String, category: String, library: String, duration: NanoInterval, tags: Map[String, String], isFinishedWithError: Boolean)
\ No newline at end of file |