From a0a57b110a3ee4876797ab51c4758525d166796f Mon Sep 17 00:00:00 2001 From: Ivan Topolnak Date: Thu, 30 Jan 2014 18:23:33 -0300 Subject: wip --- .../src/main/scala/kamon/trace/Segments.scala | 5 +- kamon-core/src/main/scala/kamon/trace/Trace.scala | 22 ++-- .../src/main/scala/kamon/trace/TraceContext.scala | 17 +-- .../src/main/scala/kamon/trace/TraceCtx.scala | 125 +++++++++++++++++++++ .../trace/logging/LogbackTraceTokenConverter.scala | 4 +- 5 files changed, 142 insertions(+), 31 deletions(-) create mode 100644 kamon-core/src/main/scala/kamon/trace/TraceCtx.scala (limited to 'kamon-core/src/main/scala/kamon/trace') diff --git a/kamon-core/src/main/scala/kamon/trace/Segments.scala b/kamon-core/src/main/scala/kamon/trace/Segments.scala index 0bc68ee7..e6d9745b 100644 --- a/kamon-core/src/main/scala/kamon/trace/Segments.scala +++ b/kamon-core/src/main/scala/kamon/trace/Segments.scala @@ -16,7 +16,8 @@ package kamon.trace -import kamon.trace.Trace.SegmentCompletionHandle + +import kamon.trace.TraceOld.SegmentCompletionHandle object Segments { @@ -34,5 +35,5 @@ object Segments { var completionHandle: Option[SegmentCompletionHandle] } - trait ContextAndSegmentCompletionAware extends ContextAware with SegmentCompletionHandleAware + trait ContextAndSegmentCompletionAware extends TraceContextAware with SegmentCompletionHandleAware } diff --git a/kamon-core/src/main/scala/kamon/trace/Trace.scala b/kamon-core/src/main/scala/kamon/trace/Trace.scala index 7dd3a6f8..bdfd6aa3 100644 --- a/kamon-core/src/main/scala/kamon/trace/Trace.scala +++ b/kamon-core/src/main/scala/kamon/trace/Trace.scala @@ -18,14 +18,14 @@ package kamon.trace import kamon.Kamon import akka.actor._ import scala.Some -import kamon.trace.Trace.Register +import kamon.trace.TraceOld.Register import scala.concurrent.duration._ import java.util.concurrent.atomic.AtomicLong import scala.util.Try import java.net.InetAddress -object Trace extends ExtensionId[TraceExtension] with ExtensionIdProvider { - def lookup(): ExtensionId[_ <: Extension] = Trace +object TraceOld extends ExtensionId[TraceExtension] with ExtensionIdProvider { + def lookup(): ExtensionId[_ <: Extension] = TraceOld def createExtension(system: ExtendedActorSystem): TraceExtension = new TraceExtension(system) /*** Protocol */ @@ -33,16 +33,16 @@ object Trace extends ExtensionId[TraceExtension] with ExtensionIdProvider { /** User API */ //private[trace] val traceContext = new DynamicVariable[Option[TraceContext]](None) - private[trace] val traceContext = new ThreadLocal[Option[TraceContext]] { - override def initialValue(): Option[TraceContext] = None + private[trace] val traceContext = new ThreadLocal[Option[TraceContextOld]] { + override def initialValue(): Option[TraceContextOld] = None } private[trace] val tranid = new AtomicLong() def context() = traceContext.get - private def set(ctx: Option[TraceContext]) = traceContext.set(ctx) + private def set(ctx: Option[TraceContextOld]) = traceContext.set(ctx) def clear: Unit = traceContext.remove() - def start(name: String, token: Option[String])(implicit system: ActorSystem): TraceContext = { + def start(name: String, token: Option[String])(implicit system: ActorSystem): TraceContextOld = { val ctx = newTraceContext(name, token.getOrElse(TraceToken.generate())) ctx.start(name) set(Some(ctx)) @@ -50,7 +50,7 @@ object Trace extends ExtensionId[TraceExtension] with ExtensionIdProvider { ctx } - def withContext[T](ctx: Option[TraceContext])(thunk: ⇒ T): T = { + def withContext[T](ctx: Option[TraceContextOld])(thunk: ⇒ T): T = { val oldval = context set(ctx) @@ -58,11 +58,11 @@ object Trace extends ExtensionId[TraceExtension] with ExtensionIdProvider { finally set(oldval) } - def transformContext(f: TraceContext ⇒ TraceContext): Unit = { + def transformContext(f: TraceContextOld ⇒ TraceContextOld): Unit = { context.map(f).foreach(ctx ⇒ set(Some(ctx))) } - def finish(): Option[TraceContext] = { + def finish(): Option[TraceContextOld] = { val ctx = context() ctx.map(_.finish) clear @@ -70,7 +70,7 @@ object Trace extends ExtensionId[TraceExtension] with ExtensionIdProvider { } // TODO: FIX - def newTraceContext(name: String, token: String)(implicit system: ActorSystem): TraceContext = TraceContext(Kamon(Trace).api, tranid.getAndIncrement, name, token) + def newTraceContext(name: String, token: String)(implicit system: ActorSystem): TraceContextOld = TraceContextOld(Kamon(TraceOld).api, tranid.getAndIncrement, name, token) def startSegment(category: Segments.Category, description: String = "", attributes: Map[String, String] = Map()): SegmentCompletionHandle = { val start = Segments.Start(category, description, attributes) diff --git a/kamon-core/src/main/scala/kamon/trace/TraceContext.scala b/kamon-core/src/main/scala/kamon/trace/TraceContext.scala index 5780b749..95a3a8b2 100644 --- a/kamon-core/src/main/scala/kamon/trace/TraceContext.scala +++ b/kamon-core/src/main/scala/kamon/trace/TraceContext.scala @@ -23,7 +23,7 @@ import kamon.Kamon import kamon.trace.UowTracing.{ Finish, Start } // TODO: Decide if we need or not an ID, generating it takes time and it doesn't seem necessary. -case class TraceContext(private val collector: ActorRef, id: Long, name: String, token: String, userContext: Option[Any] = None) { +case class TraceContextOld(private val collector: ActorRef, id: Long, name: String, token: String, userContext: Option[Any] = None) { def start(name: String) = { collector ! Start(id, name) @@ -34,18 +34,3 @@ case class TraceContext(private val collector: ActorRef, id: Long, name: String, } } - -trait ContextAware { - def traceContext: Option[TraceContext] -} - -object ContextAware { - def default: ContextAware = new ContextAware { - val traceContext: Option[TraceContext] = Trace.context() - } -} - -trait TimedContextAware { - def timestamp: Long - def traceContext: Option[TraceContext] -} diff --git a/kamon-core/src/main/scala/kamon/trace/TraceCtx.scala b/kamon-core/src/main/scala/kamon/trace/TraceCtx.scala new file mode 100644 index 00000000..1e552563 --- /dev/null +++ b/kamon-core/src/main/scala/kamon/trace/TraceCtx.scala @@ -0,0 +1,125 @@ +/* + * ========================================================================================= + * Copyright © 2013 the kamon project + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * ========================================================================================= + */ + +package kamon.trace + +import akka.actor.{ExtendedActorSystem, ActorSystem} +import akka.dispatch.AbstractNodeQueue +import kamon.Kamon +import kamon.metrics.{TraceMetrics, Metrics} +import java.util.concurrent.atomic.AtomicLong + +sealed trait TracingLevelOfDetail +case object OnlyMetrics extends TracingLevelOfDetail +case object SimpleTrace extends TracingLevelOfDetail +case object FullTrace extends TracingLevelOfDetail + +trait TraceContext { + def token: String + def name: String + def rename(newName: String): Unit + def levelOfDetail: TracingLevelOfDetail + def startSegment + def finish(metadata: Map[String, String]) + +} + +trait TraceContextAware { + def captureMark: Long + def traceContext: Option[TraceContext] +} + +object TraceContextAware { + def default: TraceContextAware = new TraceContextAware { + val captureMark = System.nanoTime() + val traceContext = TraceRecorder.currentContext + } +} + +object TraceContext { + +} + +class SimpleMetricCollectionContext(val token: String, @volatile private var _name: String, val system: ActorSystem, + metadata: Map[String, String]) extends TraceContext { + val levelOfDetail = OnlyMetrics + + @volatile private var _isOpen = true + + val startMark = System.nanoTime() + + def name: String = _name + + def rename(newName: String): Unit = _name = newName + + def isOpen(): Boolean = _isOpen + + def finish(metadata: Map[String, String]): Unit = { + val finishMark = System.nanoTime() + + // Store all metrics! + val metricsExtension = Kamon(Metrics)(system) + val metricRecorder = metricsExtension.register(name, TraceMetrics) + + metricRecorder.map { traceMetrics => + traceMetrics.elapsedTime.record(finishMark - startMark) + } + + } + + override def startSegment: Unit = ??? + + +} + +private[kamon] class SegmentRecordingQueue extends AbstractNodeQueue[String] + + + + +class TraceRecorder(system: ExtendedActorSystem) { + +} + +object TraceRecorder { + private val tokenCounter = new AtomicLong + private val traceContextStorage = new ThreadLocal[Option[TraceContext]] { + override def initialValue(): Option[TraceContext] = None + } + + private def newTraceContext(name: String, token: Option[String], metadata: Map[String, String], system: ActorSystem): TraceContext = ??? + + def setContext(context: Option[TraceContext]): Unit = traceContextStorage.set(context) + + def clearContext: Unit = traceContextStorage.set(None) + + def currentContext: Option[TraceContext] = traceContextStorage.get() + + def start(name: String, token: Option[String] = None, metadata: Map[String, String] = Map.empty)(implicit system: ActorSystem) = { + val ctx = newTraceContext(name, token, metadata, system) + traceContextStorage.set(Some(ctx)) + } + + def withContext[T](context: Option[TraceContext])(thunk: => T): T = { + val oldContext = currentContext + setContext(context) + + try thunk finally setContext(oldContext) + } + + def finish(metadata: Map[String, String] = Map.empty): Unit = currentContext.map(_.finish(metadata)) + +} diff --git a/kamon-core/src/main/scala/kamon/trace/logging/LogbackTraceTokenConverter.scala b/kamon-core/src/main/scala/kamon/trace/logging/LogbackTraceTokenConverter.scala index 403e4ee7..4b7dbb28 100644 --- a/kamon-core/src/main/scala/kamon/trace/logging/LogbackTraceTokenConverter.scala +++ b/kamon-core/src/main/scala/kamon/trace/logging/LogbackTraceTokenConverter.scala @@ -17,8 +17,8 @@ package kamon.trace.logging import ch.qos.logback.classic.pattern.ClassicConverter import ch.qos.logback.classic.spi.ILoggingEvent -import kamon.trace.Trace +import kamon.trace.TraceRecorder class LogbackTraceTokenConverter extends ClassicConverter { - def convert(event: ILoggingEvent): String = Trace.context().map(_.token).getOrElse("undefined") + def convert(event: ILoggingEvent): String = TraceRecorder.currentContext.map(_.token).getOrElse("undefined") } -- cgit v1.2.3