Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize Brave Zipkin tracing for Dropwizard servers and JAX RS clients #235

Closed
wants to merge 3 commits into from

Conversation

schlosna
Copy link
Contributor

@schlosna schlosna commented Sep 21, 2016

Introduces a Tracer wrapping Brave to produce Zipkin traces and spans to the "tracing" slf4j logger.

Typically a Dropwizard server should call com.palantir.remoting1.servers.DropwizardServers#configure as part of startup initialization, which will take care of registering the Brave singleton tracer in com.palantir.remoting1.servers.Tracers#activeTracer as a Jersey server interceptor.

JAX RS clients created via com.palantir.remoting1.jaxrs.JaxRsClient#builder(com.palantir.remoting1.clients.ClientConfig) will inherit the active tracer by default, or can provide their own via ClientConfig.

Similarly the Tracer allows for initiating local traces with its API.

Addresses #115

…ents

Introduces a Tracer wrapping Brave to produce Zipkin traces and spans to
the "tracing" slf4j logger.

Typically a Dropwizard server should call
`com.palantir.remoting1.servers.DropwizardServers#configure` as part of
startup initialization, which will take care of registering the Brave
singleton tracer in `com.palantir.remoting1.servers.Tracers#activeTracer`
as a Jersey server interceptor.

JAX RS clients created via `com.palantir.remoting1.jaxrs.JaxRsClient#
builder(com.palantir.remoting1.clients.ClientConfig)` will inherit the
active tracer by default, or can provide their own via `ClientConfig`.

Similarly the Tracer allows for initiating local traces with its API.
@schlosna
Copy link
Contributor Author

schlosna commented Sep 21, 2016

@uschi2000 @markelliot @clockfort for SA

@schlosna
Copy link
Contributor Author

We still need to fix the span collection plumbing, sampling configuration, and a few more things, but I'm considering those for a followup PR for now.

@uschi2000
Copy link
Contributor

before I start reading the code changes: what's the high-level goal of this change?

@schlosna
Copy link
Contributor Author

Rob, the high level goal is to provide a single unified Brave instance to Dropwizard based applications so that they can do local tracing, and inherit the proper incoming server trace & span as top level local spans' parents.

@uschi2000
Copy link
Contributor

Got it, thanks

On Thu, Sep 22, 2016 at 4:01 PM David Schlosnagle notifications@github.com
wrote:

Rob, the high level goal is to provide a single unified Brave instance to
Dropwizard based applications so that they can do local tracing, and
inherit the proper incoming server trace & span as top level local spans'
parents.


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
#235 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AGOdwUkEThpDiCIig_Ncln9a8SaAS5xRks5qsoosgaJpZM4KDLsA
.

@schlosna
Copy link
Contributor Author

schlosna commented Sep 22, 2016

This will require some tweaking as http-remoting is shading some Brave components which causes the following issue when using this:

Exception in thread "main" java.lang.NoSuchMethodError: com.palantir.remoting1.servers.BraveTracer.defaultClock()Lcom/github/kristofa/brave/AnnotationSubmitter$Clock;
  at com.palantir.remoting1.servers.DropwizardTracingFilters.createBraveTracer(DropwizardTracingFilters.java:99)
  at com.palantir.remoting1.servers.DropwizardTracingFilters.getOrCreateBraveTracer(DropwizardTracingFilters.java:82)
  at com.palantir.remoting1.servers.DropwizardTracingFilters.registerTracers(DropwizardTracingFilters.java:63)
  at com.palantir.remoting1.servers.DropwizardServers.configure(DropwizardServers.java:50)

Might also be worth separating the tracing initialization from the other aspects in DropwizardServers as the tracing needs to be setup first before anything creates JAX RS clients or nothing will be traced.

@uschi2000
Copy link
Contributor

uschi2000 commented Sep 23, 2016

Hmm, I find this all very hard to understand :( There's a strange mixture between static state (e.g., Tracers.getActiveTracer()) and injected state (e.g., ClientConfig#setTracer). David, can we brainstorm a little in person to find a simpler solution?

(Or maybe I'm just not getting the point...)

@@ -57,32 +60,45 @@ private DropwizardTracingFilters() {}
* TODO(rfink) Is there a more stable way to retrieve IP/Port information?
*/
static void registerTracers(Environment environment, Configuration config, String tracerName) {
ServerTracer serverTracer = getServerTracer(extractIp(config), extractPort(config), tracerName);
final BraveTracer tracer = getOrCreateBraveTracer(config, tracerName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final isn't normally used in this codebase

private final Brave brave;
private final SpanId spanId;

@SuppressWarnings("WeakerAccess") // public API
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to suppress the intelliJ hint?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this suppresses an IntelliJ warning since this is unused in this project

@Test
public void traceCallable() throws Exception {
@SuppressWarnings("unchecked") // yay generic type erasure
Callable<String> mockCallable = mock(Callable.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can get around this with annotation-based mocking:

@Mock
private Foo<Bar> foo;

/**
* Begins a trace context for the specified component and operation.
*
* @param component component name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

* @param component component name
* @param operation operation name
*
* @return new trace context
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

/**
* Utility methods for tracing components and operations.
*/
@SuppressWarnings("WeakerAccess")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a fan of this

Copy link
Contributor

@uschi2000 uschi2000 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still struggling with the semi-coupled nature of our Tracers wrapper and the Brave implementation. Is there a particular reason we need to wrap Brave?

*/
TraceContext begin(String component, String operation);

Class<? extends TraceContext> getContextClass();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this?

@schlosna
Copy link
Contributor Author

I'd be fine with exposing Brave directly to both servers (and possibly clients) for use as needed for local tracing -- my main goal here is to get the inheritable state shared across server, client, and local tracers, as well as have a consistent mechanism for configuring the Brave instance to sample & collect spans, so that we can have the configuration injected via service discovery.

The main concern for exposing Brave here is that we're tying ourselves to a concrete API. I don't have strong objections to that as I think we can handle breaks and incompatibility as needed for our own http-remoting consumers.

Another option might be to use the opentracing-api from
https://github.com/opentracing/opentracing-java and the brave-opentracing bridge from https://github.com/openzipkin/brave-opentracing . That route might lose some of the access to Brave niceties, but I haven't looked into that route quite yet.

@uschi2000
Copy link
Contributor

The current PR feels like a limbo with some parts wrapped in our own API
and some parts using Brave directly.

On Wed, Sep 28, 2016 at 7:26 PM David Schlosnagle notifications@github.com
wrote:

I'd be fine with exposing Brave directly to both servers (and possibly
clients) for use as needed for local tracing -- my main goal here is to get
the inheritable state shared across server, client, and local tracers, as
well as have a consistent mechanism for configuring the Brave instance to
sample & collect spans, so that we can have the configuration injected via
service discovery.

The main concern for exposing Brave here is that we're tying ourselves to
a concrete API. I don't have strong objections to that as I think we can
handle breaks and incompatibility as needed for our own http-remoting
consumers.

Another option might be to use the opentracing-api from
https://github.com/opentracing/opentracing-java and the brave-opentracing
bridge from https://github.com/openzipkin/brave-opentracing . That route
might lose some of the access to Brave niceties, but I haven't looked into
that route quite yet.


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
#235 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AGOdwXOTWaG4-kQoEE8XMjNl4AJG_IjEks5qurFKgaJpZM4KDLsA
.

@uschi2000
Copy link
Contributor

(Sorry, I have to run now.)

On Wed, Sep 28, 2016 at 7:31 PM Robert Fink rf@robertfink.de wrote:

The current PR feels like a limbo with some parts wrapped in our own API
and some parts using Brave directly.

On Wed, Sep 28, 2016 at 7:26 PM David Schlosnagle <
notifications@github.com> wrote:

I'd be fine with exposing Brave directly to both servers (and possibly
clients) for use as needed for local tracing -- my main goal here is to get
the inheritable state shared across server, client, and local tracers, as
well as have a consistent mechanism for configuring the Brave instance to
sample & collect spans, so that we can have the configuration injected via
service discovery.

The main concern for exposing Brave here is that we're tying ourselves to
a concrete API. I don't have strong objections to that as I think we can
handle breaks and incompatibility as needed for our own http-remoting
consumers.

Another option might be to use the opentracing-api from
https://github.com/opentracing/opentracing-java and the brave-opentracing
bridge from https://github.com/openzipkin/brave-opentracing . That route
might lose some of the access to Brave niceties, but I haven't looked into
that route quite yet.


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
#235 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AGOdwXOTWaG4-kQoEE8XMjNl4AJG_IjEks5qurFKgaJpZM4KDLsA
.

@markelliot
Copy link
Contributor

I think the challenge with this PR is that it's not a full-measure for wrapping Brave. My basic stance (and I don't feel strongly about which of these to choose) is that we need to either:

  1. Just use Brave as-is and live with its semantics
  2. Use our own tracing shim (which is less code than this PR and will have precisely the semantics we want) + write an adapter from that shim to integrate with Zipkin

If I had to choose, I'd prefer 2.

@schlosna
Copy link
Contributor Author

@markelliot I don't really want to wrap Brave, I'd rather inject it into all of the places that we want to do tracing, but a lot of the http-remoting APIs currently prevent that and make this more difficult than it needs to be -- e.g. we need to push the trace config into the JaxRs ClientConfig so that tracing there knows what to trace and where to push it. This is made more difficult by the shading done by http-remoting and dependency limitations, which is how I ended up with this PR for the time being.

@markelliot
Copy link
Contributor

Not sure I grok what you're saying – we own all of the JaxRs code, so we could in theory make this simpler?

@schlosna
Copy link
Contributor Author

schlosna commented Oct 2, 2016

I have a cleanup that I think is cleaner -- it will add brace-core and brace-okhttp dependency for http-clients-api.
I will push later tonight or tomorrow once I increase test coverage.

@uschi2000
Copy link
Contributor

Cheers David

On Sun, Oct 2, 2016, 13:24 David Schlosnagle notifications@github.com
wrote:

I have a cleanup that I think is cleaner -- it will add brace-core and
brace-okhttp dependency for http-clients-api.
I will push later tonight or tomorrow once I increase test coverage.


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
#235 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AGOdwa5xxDcG49fk8lmWKYMBlOckGBh2ks5qwBLkgaJpZM4KDLsA
.

@schlosna
Copy link
Contributor Author

See also #115

@schlosna schlosna closed this Oct 15, 2016
@schlosna schlosna deleted the davids/brave-tracer branch October 15, 2016 14:32
@markelliot markelliot mentioned this pull request Mar 28, 2017
hsaraogi pushed a commit to hsaraogi/http-remoting that referenced this pull request May 7, 2019
###### _excavator_ is a bot for automating changes across repositories.

Changes produced by the roomba/roomba-lint check.

{runtimeCheckDesc}
To enable or disable this check, please contact the maintainers of Excavator.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants