Skip to content

Commit c838d2b

Browse files
jcrossleyjenkins
authored and
jenkins
committed
finagle/finagle-core: VerboseRequestTracer filter that adds tracing through the finagle stack
Problem We want to be able to trace requests throughout the finagle stack during testing. Solution Add a filter, VerboseRequestTracer, that adds this functionality for traced requests. It is disabled by default and can be enabled via flag `com.twitter.finagle.filter.verboseRequestTracing`. Differential Revision: https://phabricator.twitter.biz/D1182361
1 parent 171b881 commit c838d2b

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

finagle-core/src/main/scala/com/twitter/finagle/client/EndpointerStackClient.scala

+8-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.twitter.finagle.client
33
import com.twitter.finagle._
44
import com.twitter.finagle.client.EndpointerStackClient.DimensionalClientScopes
55
import com.twitter.finagle.filter.RequestLogger
6+
import com.twitter.finagle.filter.VerboseRequestTracer
67
import com.twitter.finagle.naming.BindingFactory
78
import com.twitter.finagle.param._
89
import com.twitter.finagle.stack.nilStack
@@ -135,13 +136,19 @@ trait EndpointerStackClient[Req, Rep, This <: EndpointerStackClient[Req, Rep, Th
135136

136137
val originalStack = {
137138
val baseStack = stack ++ (endpointer +: nilStack)
138-
params[RequestLogger.Param] match {
139+
val stackWithRequestTracing = params[RequestLogger.Param] match {
139140
case RequestLogger.Param.Enabled =>
140141
val transformer = RequestLogger.newStackTransformer(clientLabel)
141142
transformer(baseStack)
142143
case RequestLogger.Param.Disabled =>
143144
baseStack
144145
}
146+
params[VerboseRequestTracer.Param] match {
147+
case VerboseRequestTracer.Param.Enabled =>
148+
VerboseRequestTracer.stackTransformer(stackWithRequestTracing)
149+
case VerboseRequestTracer.Param.Disabled =>
150+
stackWithRequestTracing
151+
}
145152
}
146153

147154
val transformedStack =
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package com.twitter.finagle.filter
2+
3+
import com.twitter.app.GlobalFlag
4+
import com.twitter.finagle.ClientConnection
5+
import com.twitter.finagle.Service
6+
import com.twitter.finagle.ServiceFactory
7+
import com.twitter.finagle.ServiceFactoryProxy
8+
import com.twitter.finagle.ServiceProxy
9+
import com.twitter.finagle.Stack
10+
import com.twitter.finagle.tracing.Trace
11+
import com.twitter.util.Future
12+
13+
object verboseRequestTracing
14+
extends GlobalFlag[Boolean](
15+
"""Experimental flag. Enables verbose request tracing, which includes tracing though the finagle stack""".stripMargin
16+
)
17+
18+
private[twitter] object VerboseRequestTracer {
19+
20+
sealed trait Param {
21+
def mk(): (Param, Stack.Param[Param]) = (this, Param.param)
22+
}
23+
24+
private[finagle] object Param {
25+
case object Disabled extends Param
26+
case object Enabled extends Param
27+
28+
implicit val param: Stack.Param[Param] = new Stack.Param[Param] {
29+
lazy val default: Param = {
30+
verboseRequestTracing.get match {
31+
case Some(value) if value => Enabled
32+
case _ => Disabled
33+
}
34+
}
35+
}
36+
}
37+
38+
/**
39+
* Enables the [[VerboseRequestTracer]].
40+
*/
41+
val Enabled: Param = Param.Enabled
42+
43+
/**
44+
* Disables the [[VerboseRequestTracer]] (disabled by default).
45+
*/
46+
val Disabled: Param = Param.Disabled
47+
48+
private[finagle] val stackTransformer: Stack.Transformer =
49+
new Stack.Transformer {
50+
def apply[Req, Rep](stack: Stack[ServiceFactory[Req, Rep]]): Stack[ServiceFactory[Req, Rep]] =
51+
stack.map((hd, sf) => withRequestTracing(hd.role, sf))
52+
}
53+
54+
private[this] def withRequestTracing[Req, Rep](
55+
role: Stack.Role,
56+
svcFac: ServiceFactory[Req, Rep]
57+
): ServiceFactory[Req, Rep] =
58+
new ServiceFactoryProxy[Req, Rep](svcFac) {
59+
override def apply(conn: ClientConnection): Future[Service[Req, Rep]] = {
60+
super.apply(conn).map { svc =>
61+
new ServiceProxy[Req, Rep](svc) {
62+
override def apply(request: Req): Future[Rep] = {
63+
if (!Trace.isActivelyTracing) {
64+
super.apply(request)
65+
} else {
66+
Trace.traceLocalFuture(role.name + "_async") {
67+
Trace.traceLocal(role.name + "_sync") {
68+
super.apply(request)
69+
}
70+
}
71+
}
72+
}
73+
}
74+
}
75+
}
76+
}
77+
}

0 commit comments

Comments
 (0)