Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
define TraceReceiver & add support in the server builder.
some renaming to make things clearer.
- Loading branch information
Showing
11 changed files
with
210 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
finagle-core/src/main/scala/com/twitter/finagle/tracing/Trace.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,112 @@ | |||
package com.twitter.finagle.tracing | |||
|
|||
/** | |||
* Support for tracing in finagle. The main abstraction herein is the | |||
* "Trace", which is a local that contains various metadata required | |||
* for distributed tracing as well as references to the local traced | |||
* events. We mimic Dapper in many ways, including borrowing its | |||
* nomenclature. | |||
* | |||
* “Dapper, a Large-Scale Distributed Systems Tracing Infrastructure”, | |||
* Benjamin H. Sigelman, Luiz André Barroso, Mike Burrows, Pat | |||
* Stephenson, Manoj Plakal, Donald Beaver, Saul Jaspan, Chandan | |||
* Shanbhag, 2010. | |||
* | |||
* http://research.google.com/pubs/archive/36356.pdf | |||
*/ | |||
|
|||
import scala.util.Random | |||
|
|||
import com.twitter.util.{Local, Time, TimeFormat, RichU64Long} | |||
|
|||
case class TraceID( | |||
var span: Long, | |||
var parentSpan: Option[Long], | |||
val host: Int, | |||
val vm: String) | |||
{ | |||
override def toString = { | |||
val spanHex = new RichU64Long(span).toU64HexString | |||
val parentSpanHex = parentSpan map (new RichU64Long(_).toU64HexString) | |||
|
|||
val spanString = parentSpanHex match { | |||
case Some(parentSpanHex) => "%s<:%s".format(spanHex, parentSpanHex) | |||
case None => spanHex | |||
} | |||
|
|||
"%s,%s".format(spanString, vm) | |||
} | |||
} | |||
|
|||
object Span { | |||
private[Span] val timeFormat = | |||
new TimeFormat("yyyyMMdd.HHmmss") | |||
} | |||
|
|||
case class Span( | |||
var traceID: TraceID, | |||
var startTime: Time, | |||
var endTime: Time, | |||
var transcript: Transcript) | |||
{ | |||
override def toString = { | |||
"%s: %s+%d".format( | |||
traceID, | |||
Span.timeFormat.format(startTime), | |||
(endTime - startTime).inMilliseconds) | |||
} | |||
} | |||
|
|||
object Trace { | |||
private[this] val rng = new Random | |||
private[this] val current = new Local[Span] | |||
|
|||
private[this] def newSpan() = { | |||
val traceID = TraceID(rng.nextLong(), None, Host(), VMID()) | |||
Span(traceID, Time.now, Time.epoch, NullTranscript) | |||
} | |||
|
|||
def update(ctx: Span) { | |||
current() = ctx | |||
} | |||
|
|||
def apply(): Span = { | |||
if (!current().isDefined) | |||
current() = newSpan() | |||
|
|||
current().get | |||
} | |||
|
|||
def clear() { | |||
current.clear() | |||
} | |||
|
|||
def startSpan() { | |||
this() = newSpan() | |||
} | |||
|
|||
def startSpan(parentSpanID: Long) { | |||
startSpan() | |||
this().traceID.parentSpan = Some(parentSpanID) | |||
} | |||
|
|||
def endSpan(): Span = { | |||
Trace().endTime = Time.now | |||
val span = Trace() | |||
clear() | |||
span | |||
} | |||
|
|||
def debug(isOn: Boolean) { | |||
if (isOn && !Trace().transcript.isRecording) | |||
Trace().transcript = new BufferingTranscript(Trace().traceID) | |||
else if (!isOn && Trace().transcript.isRecording) | |||
Trace().transcript = NullTranscript | |||
} | |||
|
|||
def spanID = Trace().traceID.span | |||
|
|||
def record(message: => String) { | |||
Trace().transcript.record(message) | |||
} | |||
} |
60 changes: 0 additions & 60 deletions
60
finagle-core/src/main/scala/com/twitter/finagle/tracing/TraceContext.scala
This file was deleted.
Oops, something went wrong.
20 changes: 20 additions & 0 deletions
20
finagle-core/src/main/scala/com/twitter/finagle/tracing/TraceReceiver.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,20 @@ | |||
package com.twitter.finagle.tracing | |||
|
|||
/** | |||
* Trace receivers are called after the completion of every span. These | |||
* in turn can be used to implement trace collection ala Dapper. | |||
*/ | |||
|
|||
trait TraceReceiver { | |||
/** | |||
* receiveSpan is called for every span production (at the | |||
* completion of a request from the server) | |||
*/ | |||
def receiveSpan(span: Span): Unit | |||
} | |||
|
|||
class ConsoleTraceReceiver extends TraceReceiver { | |||
def receiveSpan(span: Span) { | |||
println(span) | |||
} | |||
} |
21 changes: 21 additions & 0 deletions
21
finagle-core/src/main/scala/com/twitter/finagle/tracing/TracingFilter.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,21 @@ | |||
package com.twitter.finagle.tracing | |||
|
|||
/** | |||
* The TracingFilter takes care of span lifecycle events. It is always | |||
* placed first in the server filter chain so that protocols with | |||
* trace support will override the span resets, and still be properly | |||
* reported here. | |||
*/ | |||
|
|||
import com.twitter.finagle.{Service, SimpleFilter} | |||
|
|||
class TracingFilter[Req, Rep](receiver: TraceReceiver) | |||
extends SimpleFilter[Req, Rep] | |||
{ | |||
def apply(request: Req, service: Service[Req, Rep]) = { | |||
Trace.startSpan() | |||
service(request) ensure { | |||
receiver.receiveSpan(Trace.endSpan()) | |||
} | |||
} | |||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.