-
Notifications
You must be signed in to change notification settings - Fork 231
Conversation
@@ -462,7 +461,7 @@ public void apply(JaegerTracer.Builder builder) { | |||
registerCodec(builder, Format.Builtin.TEXT_MAP); | |||
} | |||
|
|||
protected void registerCodec(JaegerTracer.Builder builder, Format<TextMap> format) { | |||
private void registerCodec(JaegerTracer.Builder builder, Format<TextMap> format) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Find/replace mistake. Will remove.
Codecov Report
@@ Coverage Diff @@
## master #509 +/- ##
============================================
+ Coverage 88.27% 88.42% +0.15%
- Complexity 500 505 +5
============================================
Files 65 66 +1
Lines 1850 1883 +33
Branches 239 239
============================================
+ Hits 1633 1665 +32
- Misses 140 142 +2
+ Partials 77 76 -1
Continue to review full report at Codecov.
|
f1d1085
to
1587771
Compare
@@ -46,7 +46,7 @@ | |||
private List<LogData> logs; | |||
private boolean finished = false; // to prevent the same span from getting reported multiple times | |||
|
|||
JaegerSpan( | |||
protected JaegerSpan( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@isaachier I don't think this will be enough, is it? I.e. you'd also need an overridable method that actually creates the object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer if you accompany this with a unit test showing the working subclassing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a lot more. The test definitely helped me determine what was necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://www.youtube.com/watch?v=0z_Qqnq8pI8
You have added a ton of irrelevant formatting. Where is it coming from? Don't mix formatting changes with tbhe business logic changes.
Lol I'm not trying to. Travis CI kept failing the build because of the formatting and licensing issues. |
If you need to fix formatting, then let's do it in a separate PR. |
5b167c6
to
bcf47f1
Compare
Undid the formatting fix for now. |
} | ||
|
||
private static class SpanContext extends JaegerSpanContext { | ||
SpanContext(JaegerSpanContext ctx) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not what I thought you were going after. If you extend the context, why do you need to accept it as agrument? The oss tracer currently does "new SpanContext". You can move that call into a function that you would override in the subclassed tracer and return your own subclass of SpanContext.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could redo a lot of code. The idea is to avoid code duplication by allowing base classes to do 99% of the work. Imagine the case of a JaegerTracer starting a JaegerSpan. There is a lot of logic dedicated to determining the span parent, etc. Now I could override start
because Tracer needs to return Span
instead of JaegerSpan
, but that's going to result in a huge amount of copy-paste. Isn't it easier to use a constructor Span(JaegerSpan span)
(note package visibility, not public)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not suggesting redoing any code. What I am saying is that, for example, Trace has this code in builder.createNewContext()
:
return new JaegerSpanContext(id, id, 0, flags);
createNewContext
itself is a large method we don't want to replicate. But we can change the above line to
return instantiateNewSpanContext(id, id, 0, flags);
and add method:
protected JaegerSpanContext instantiateNewSpanContext(...) {
return new JaegerSpanContext(id, id, 0, flags);
}
Then in your subclassed Tracer you just need to override this method
@Override
protected JaegerSpanContext instantiateNewSpanContext(...) {
return new SubclassedJaegerSpanContext(id, id, 0, flags);
}
Your subclassed tracer will have a total of 3 methods: constructor that directly delegates to super(....same args.....)
, and two instantiate methods, for span context and the Span that create
subclassed instances.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK now I understand. I think this is called the abstract factory pattern. That definitely makes sense. I am usually hesitant to change so much of the existing code, but I guess this is a better design.
@@ -653,19 +652,19 @@ public static SenderConfiguration fromEnv() { | |||
} | |||
} | |||
|
|||
private static String stringOrDefault(String value, String defaultValue) { | |||
protected static String stringOrDefault(String value, String defaultValue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you making them protected
so that you can use them in subclasses? Those are not part of the business of this class, I'd rather see them in a, say, StringUtils
class (as much as a I dislike utils
classes).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, my subclass doesn't use these. I thought if they were static private
utility methods here, then they ought to be static protected
for subclasses. Nonetheless, I was considering adding a new class called ConfigUtils
or something just for that purpose.
import java.util.Map; | ||
|
||
public class JaegerSubclassTest { | ||
private static class Configuration extends io.jaegertracing.Configuration { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/Configuration/CustomConfiguration/
(or anything else that won't class with i.j.Configuration)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right good idea.
} | ||
} | ||
|
||
private static class Tracer extends JaegerTracer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/Tracer/CustomTracer/
(or anything else that won't clash with io.opentracing.Tracer, which is part of the hierarchy)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely
} | ||
} | ||
|
||
Tracer(io.jaegertracing.internal.JaegerTracer tracer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You probably don't need the fully qualified class name here, do you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
} | ||
} | ||
|
||
private static class Span extends JaegerSpan { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/Span/CustomSpan
final Configuration config = new Configuration("test-service"); | ||
final Tracer tracer = config.getTracer(); | ||
final Scope scope = tracer.buildSpan("test-operation").startActive(true); | ||
Assert.assertNotNull(tracer.scopeManager().active()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that if this assertion works, then a bunch of other stuff has also worked, but it would be nice to have your "base" assertions made explicit here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ya this test isn't perfect. Needs work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be a bit better now.
5a5540e
to
848881a
Compare
} | ||
|
||
protected TracingFactory tracingFactory() { | ||
return new TracingFactory(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
factory should be instantiated only once
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about using a singleton. I guess I should.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a singleton in the sense of a private static member, but just an externally provided object.
return config; | ||
} | ||
|
||
protected void initFromEnv() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why? this is not the code we want to repeat, so why is it factored out into a method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because Configuration
has no factory method at the moment. All these static methods are problematic because they construct the concrete type instead of the subclass. In general, I was able to solve by passing or overriding the factory. I can try doing the same here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just an idea - while subclassing tracer / span is necessary, I don't think the same holds for the configuration class. It's fine to wrap it, and not provide all the functionality that exists in the oss. For example, internally we don't init from env.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. I reverted the protected methods back to private.
|
||
public JaegerSpanContext(long traceId, long spanId, long parentId, byte flags) { | ||
this(traceId, spanId, parentId, flags, Collections.<String, String>emptyMap(), null); | ||
} | ||
|
||
JaegerSpanContext( | ||
protected JaegerSpanContext( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
who would use this ctor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It isn't exactly popular, but it is the more complete constructor. If the subclass wants to override the other constructor, it would need to use this constructor and pass in a custom factory for the last argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, now that I see the constructor I understand what you mean. Will remove.
@@ -107,7 +120,11 @@ public String toString() { | |||
return contextAsString(); | |||
} | |||
|
|||
public static JaegerSpanContext contextFromString(String value) | |||
public static JaegerSpanContext contextFromString(String value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
who uses this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well it is public
and this isn't the legacy client, so I feel uncomfortable deleting it or adding a required argument. It is used internally to decode a span context from a TextMap
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would deprecate this method. I think the only reason it is public is because Codecs are in a different package. Since you already have factory.createSpanContext()
method, the only thing this is doing is parsing a string representation of the span context - arguably a function that should live in the codecs themselves, since there can be different representations like the upcoming W3C Trace Context spec. So I suggest refactoring this and moving the main logic to TextMapCodec (it can be a public static method there, always taking the factory).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll deprecate it and refactor logic in TextMapCodec.
|
||
private JaegerTracer( | ||
protected JaegerTracer( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why you need to duplicate constructors - it was private previously, nobody called it externally, so it should be ok to change its API
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I'll remove this one and any others I find that were originally private
or package scope.
@@ -177,10 +179,14 @@ | |||
*/ | |||
private JaegerTracer tracer; | |||
|
|||
public Configuration(String serviceName) { | |||
public Configuration(String serviceName, TracingFactory tracingFactory) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you see my comment? #509 (comment) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did. I'll comment more there. Need the tracing factory to construct the JaegerTracer.Builder
subclass used in the config to create the tracer.
withTracerTags(tracerTagsFromEnv()) | ||
.withReporter(ReporterConfiguration.fromEnv()) | ||
.withSampler(SamplerConfiguration.fromEnv()) | ||
.withCodec(CodecConfiguration.fromEnv()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't look like there's a change here, please undo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea.
new BigInteger(parts[3], 16).byteValue()); | ||
new BigInteger(parts[3], 16).byteValue(), | ||
Collections.<String, String>emptyMap(), | ||
null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is null? should it be factory
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually a reference to debugId
. But this should definitely take a TracingFactory
argument as well. Will fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never mind. The factory passes this
internally to the JaegerSpanContext
constructor.
@@ -166,14 +175,19 @@ boolean isDebugIdContainerOnly() { | |||
* debug trace, and the value of header recorded as a span tag to serve as a searchable | |||
* correlation ID. | |||
* | |||
* @param debugId arbitrary string used as correlation ID | |||
* @param debugId arbitrary string used as correlation ID. | |||
* @param factory tracing object factory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name TracingFactory was making me uncomfortable, I was thinking ObjectFactory, but it too was too generic. I think TracingObjectFactory is much cleaner name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK I struggled with the names. JaegerFactory or JaegerObjectFactory could work too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 JaegerObjectFactory
@@ -95,8 +99,10 @@ private JaegerTracer( | |||
this.metrics = metrics; | |||
this.zipkinSharedRpcSpan = zipkinSharedRpcSpan; | |||
this.scopeManager = scopeManager; | |||
this.baggageRestrictionManager = baggageRestrictionManager; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so, like, a bug? 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No actually just wasn't needed outside of constructor. Originally needed this when I had constructor CustomTracer(JaegerTracer tracer)
, but don't need this anymore. Will remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove
@@ -315,7 +321,7 @@ private JaegerSpanContext createNewContext(String debugId) { | |||
} | |||
} | |||
|
|||
return new JaegerSpanContext(id, id, 0, flags); | |||
return JaegerTracer.this.tracingFactory.createSpanContext(id, id, 0, flags, Collections.<String, String>emptyMap(), debugId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am seeing a mix of factory
and tracingFactory
. If you agree with my above comment to call it TracingObjectFactory
, then I'd suggest field name objectFactory
, to be used consistently
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought I renamed all factory
references to tracingFactory
. Will change to objectFactory
throughout.
@@ -354,7 +360,7 @@ private JaegerSpanContext createChildContext() { | |||
} | |||
} | |||
|
|||
return new JaegerSpanContext( | |||
return JaegerTracer.this.tracingFactory.createSpanContext( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just curious, why fully qualified accessor instead of jus tracingFactory.createSpanContext
? I think the latter is also visible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JaegerTracer.SpanBuilder
is a non-static nested class. I am able to access the tracer's tracingFactory
from the inner class. Personally, not a huge fan of non-static nested classes (prefer explicitly passing instance to static nested class instead).
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class TracingFactory { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add javadoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ya. Just need to stabilize the API, then will do.
ScopeManager scopeManager, | ||
BaggageRestrictionManager baggageRestrictionManager, | ||
boolean expandExceptionLogs) { | ||
return new JaegerTracer( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
per my comment on Configuration, I don't think this method needs to be in the factory. Here's what you can do instead, to reduce the surface area:
class Configuration {
public JaegerTracer.Builder getTracerBuilder() {
- JaegerTracer.Builder builder = tracingFactory.createTracerBuilder(serviceName)
+ JaegerTracer.Builder builder = this.createTracerBuilder(serviceName)
}
protected createTracerBuilder() // overridable method, no more dependency on the factory
}
similar thing with JaegerTracer.Builder - just implement a protected method to create the tracer.
The only time where you need the abstract factory pattern is for creating SpanBuilder/Span/SpanContext, because those are done all the time from many places. But Tracer.Builder and Tracer are only created once, there's no need to complicate that with abstract factory pattern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about doing that, but sort of wanted to do everything in factory or everything as subclass methods. This makes sense as a compromise.
@@ -15,6 +15,7 @@ | |||
package io.jaegertracing; | |||
|
|||
import io.jaegertracing.internal.JaegerTracer; | |||
import io.jaegertracing.internal.JaegerObjectFactory; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't need this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ya I use the Google formatting plugin that will adjust the import and formatting at once, so I held off to avoid the formatting issues from earlier.
references); | ||
} | ||
|
||
public JaegerSpanContext createSpanContext(long traceId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
formatting inconsistent with the previous method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ya will fix formatting after main code is good to go.
public static JaegerSpanContext withDebugId(String debugId) { | ||
return new JaegerSpanContext(0, 0, 0, (byte) 0, Collections.<String, String>emptyMap(), debugId); | ||
return withDebugId(debugId, new JaegerObjectFactory()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pretty sure we can drop this method - it's internal
package after all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. If we can use that logic, that would simplify things in a few places.
@@ -95,8 +99,10 @@ private JaegerTracer( | |||
this.metrics = metrics; | |||
this.zipkinSharedRpcSpan = zipkinSharedRpcSpan; | |||
this.scopeManager = scopeManager; | |||
this.baggageRestrictionManager = baggageRestrictionManager; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove
new BigInteger(parts[1], 16).longValue(), | ||
new BigInteger(parts[2], 16).longValue(), | ||
new BigInteger(parts[3], 16).byteValue()); | ||
@Deprecated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since this is internal
package, can probably just remove this altogether
public CustomSpan( | ||
JaegerTracer tracer, | ||
String operationName, | ||
JaegerSpanContext context, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this should be CustomSpanContext
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea.
byte flags, | ||
Map<String, String> baggage, | ||
String debugId, | ||
JaegerObjectFactory objectFactory) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CustomObjectFactory
} | ||
|
||
@Override | ||
public CustomSpanContext withFlags(byte flags) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you need to override these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly the covariant return type adds a lot of boilerplate where I have to cast things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a practical example, here is what happens if I don't override them:
CustomSpan customSpan = anotherCustomSpan.withFlags(flags); // Error: cannot assign JaegerSpan to CustomSpan.
It will probably break user code without overriding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you worried that someone would write
com.uber.jaeger.SpanContext _ = spanCtx.withFlags()
? I highly doubt it, but ok, we can leave these as a form of example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For SpanContext
, I found 19 cases in internal Uber code. For Span
I found 281.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
referring to the class, yes, but I doubt they use these methods. But ok if you want to keep them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd just be skeptical about adding them to the actual subclass (not this test)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK that helps me. Just a matter of seeing what code changes would be necessary.
} | ||
|
||
private static class CustomSpanContext extends JaegerSpanContext { | ||
public CustomSpanContext( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could it be private? go for minimum visibility
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so. Didn't want to change visibility from base class. Constructors should be okay with that.
|
||
@Override | ||
public CustomTracer.CustomSpanBuilder createSpanBuilder(JaegerTracer tracer, String operationName) { | ||
return ((CustomTracer)tracer).new CustomSpanBuilder(operationName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you actually need to override span builder? Wouldn't the default one do the trick?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wish... I have not found a way to do it in Java. Maybe by somehow (ab)using a generic helper class to generate bridge methods that are JVM generated casts.
looking much better! |
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class JaegerObjectFactory { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is a purpose of this class? Can you please document it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will very soon.
@@ -107,44 +114,22 @@ public String toString() { | |||
return contextAsString(); | |||
} | |||
|
|||
public static JaegerSpanContext contextFromString(String value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this still here? Didn't you merge it as a separate PR already? Maybe rebase from master?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No just haven't gotten to fixing it yet. Sorry.
|
||
this.version = loadVersion(); | ||
|
||
tags.put(Constants.JAEGER_CLIENT_VERSION_TAG_KEY, this.version); | ||
if (tags.get(Constants.TRACER_HOSTNAME_TAG_KEY) == null) { | ||
builder.tags.put(Constants.JAEGER_CLIENT_VERSION_TAG_KEY, this.version); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: instead of modifying builder.tags
I would create a local variable as a copy
Map<String, String> tags = new HashMap<String, String>(builder.tags);
computeDurationViaNanoTicks, | ||
tags, | ||
references); | ||
JaegerSpan jaegerSpan = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, why not JaegerSpan jaegerSpan = getObjectFactory().createSpan(
on one line?
Would be less code changes overall.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was auto-formatted. I will try your style and see what the auto-formatter does with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't let me use this format. Changed it for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean? Last I recall formatting isn't changed as part of the build.
@@ -22,7 +22,7 @@ | |||
import lombok.RequiredArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
|
|||
class PropagationRegistry { | |||
public class PropagationRegistry { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looking at https://github.com/jaegertracing/legacy-client-java/pull/20/files, I don't see it being constructed there. So why public?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My mistake. Forgot to remove.
|
||
@Override | ||
protected JaegerTracer createTracer() { | ||
return new CustomTracer(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
neat! Managed without making builder fields public/protected :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ya I forgot this feature to, but it worked.
Thanks for the review! I will update ASAP. |
overall lgtm. Let's make sure to minimize the unnecessary changes (like formatting only, or the removal of SpanContext.fromString()). Also, what's with the broken build? |
I think Travis is having issues with the checkstyle job. I reverted a change I made in a JavaDoc that crashed the checkstyle plugin. |
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
public class JaegerObjectFactoryTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
technically, this is not testing the object factory, but the extension mechanism.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. Will revert renaming.
|
||
@Test | ||
public void testTracer() { | ||
final CustomObjectFactory tracingObjectFactory = new CustomObjectFactory(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will check.
please update PR description to more clearly explain the purpose of this change. |
688a061
to
b323d5d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this diff has a lot of unnecessary formatting changes which makes it difficult to read. Could you move the formatting changes to it's own diff?
distributionBase=GRADLE_USER_HOME | ||
distributionPath=wrapper/dists | ||
zipStoreBase=GRADLE_USER_HOME | ||
zipStorePath=wrapper/dists | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-bin.zip | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like an unnecessary change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This happened automatically somehow... will revert.
.append(Long.toHexString(traceId)).append(":") | ||
.append(Long.toHexString(spanId)).append(":") | ||
.append(Long.toHexString(parentId)).append(":") | ||
.append(Long.toHexString(traceId)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to be an unnecessary change
); | ||
} | ||
|
||
@Override |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to be an unnecessary move
* Previously this would've returned null from the extract method, but now it returns a dummy | ||
* context with only debugId filled in. | ||
* | ||
* from extract() method. This happens in the situation when "jaeger-debug-id" header is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to be an unnecessary change
* Retrieves the currently active span from the {@link ScopeManager}. It cannot be guaranteed that this span | ||
* will be a {@link JaegerSpan}, as other libraries might have set this active span there. Consumers expecting | ||
* this to return a {@link JaegerSpan} should always check the type of the return and act accordingly. | ||
* Retrieves the currently active span from the {@link ScopeManager}. It cannot be guaranteed that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to be an unnecessary change
* | ||
* @return the currently active span from the {@link ScopeManager} | ||
*/ | ||
@Override | ||
public Span activeSpan() { | ||
// the active scope might have been added there through an API extension, similar to what the OT java-metrics | ||
// the active scope might have been added there through an API extension, similar to what the OT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to be an unnecessary change
@@ -219,14 +213,15 @@ public void close() { | |||
private String operationName; | |||
private long startTimeMicroseconds; | |||
/** | |||
* In 99% situations there is only one parent (childOf), so we do not want to allocate | |||
* a collection of references. | |||
* In 99% situations there is only one parent (childOf), so we do not want to allocate a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to be an unnecessary change
@@ -304,7 +299,7 @@ private JaegerSpanContext createNewContext(String debugId) { | |||
tags.put(Constants.DEBUG_ID_HEADER_KEY, debugId); | |||
metrics.traceStartedSampled.inc(1); | |||
} else { | |||
//TODO(prithvi): Don't assume operationName is set on creation | |||
// TODO(prithvi): Don't assume operationName is set on creation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to be an unnecessary change
computeDurationViaNanoTicks, | ||
tags, | ||
references); | ||
JaegerSpan jaegerSpan = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean? Last I recall formatting isn't changed as part of the build.
@@ -326,7 +322,7 @@ private JaegerSpanContext createNewContext(String debugId) { | |||
return references.get(0).getSpanContext().baggage(); | |||
} | |||
|
|||
for (Reference reference: references) { | |||
for (Reference reference : references) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to be an unnecessary change
I would like @jpkrohling or @pavolloffay or @objectiser to approve before we merge, since they've done the most work on Java client recently. |
I'm cool with that. I will admit this review is blocking some work internally. Using snapshot releases isn't easy for the projects I am dealing with, so I'd like to wrap this up ASAP. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks OK to me. There are a couple of things that could be done to resolve an appropriate object factory, but that's optional.
I would also consider changing the method signatures to public
instead of protected
: if you expect people to extend, even in an unsupported way, then make their lives easier and allow them to extend the way they want. I got bitten recently by this on TracerResolver#resolve ;)
@@ -0,0 +1,72 @@ | |||
/* | |||
* Copyright (c) 2018, Uber Technologies, Inc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: The Jaeger Authors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. This happens to be copied from other files, but we should correct them.
@@ -129,6 +140,7 @@ public JaegerSpanContext extract(TextMap carrier) { | |||
|
|||
public static class Builder { | |||
private String baggagePrefix = BAGGAGE_PREFIX; | |||
private JaegerObjectFactory objectFactory = new JaegerObjectFactory(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use the service loader API here, so that having a JaegerObjectFactory in the classpath would be sufficient to use an alternate object factory. Look at how we did it for the MetricsFactory/Sender for a reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had actually been considering something along those lines, but didn't realize there were other implementations. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel service loader is an overkill here. The goal is to allow subclassing, which is not a runtime decision.
@@ -107,7 +117,7 @@ public String toString() { | |||
return contextAsString(); | |||
} | |||
|
|||
public static JaegerSpanContext contextFromString(String value) | |||
public static JaegerSpanContext contextFromString(String value, JaegerObjectFactory objectFactory) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid breaking current code (there should be none, but still), keep the old signature, add @Deprecated
and use the new one with new JaegerObjectFactory()
(or whatever the default value should be):
/**
* @deprecated see {@link #contextFromString(String, JaegerObjectFactory)}
*/
@Deprecated
public static JaegerSpanContext contextFromString(String value) {
return contextFromString(value, new JaegerObjectFactory());
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yurishkuro points out these internal classes aren't part of official API and users are very unlikely to be calling contextFromString
directly.
@@ -0,0 +1,174 @@ | |||
/* | |||
* Copyright (c) 2018, Uber Technologies, Inc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it thanks :).
That would extend the API surface, even if internal. What does it prevent if we keep them protected? A subclass can always increase visibility if it needs that. |
Signed-off-by: Isaac Hier <ihier@uber.com>
01727da
to
e61b97c
Compare
I just squashed the commits and rebased them on top of latest master branch (includes TextMapCodec changes). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Give protected access to core Jaeger classes so that users may extend them. The main motive here is to create a bridge between the legacy
com.uber.jaeger
classes to theio.jaegertracing
classes (equivalent to atypedef
in C/C++). Note, in general it would not be wise to implement a subclass of these classes because they are internal and may change without notice!Additionally, implement abstract factory pattern to create instances of spans, span contexts, and span builders. This allows the caller to provide subclasses of the aforementioned classes. For example, when the tracer needs to create a
JaegerSpanBuilder
object, it invokescreateSpanBuilder
instead.createSpanBuilder
acts as a hook to instantiate a subclass instead of theJaegerSpanBuilder
base class.