RUM-3536 Introduce the TraceContextInjection to handle sampling in distributed traces#2111
Conversation
256c37e to
8b3c6ab
Compare
07e0c12 to
bc386dd
Compare
| private val sampleRate: Float = DEFAULT_SAMPLE_RATE | ||
| ) : AppGlideModule() { | ||
|
|
||
| private val firstPartyHostsWithHeaderType = firstPartyHosts.associateWith { |
There was a problem hiding this comment.
the only problem I see with this is that some users will not know what to use for their tracing header types values so we might want to provide a Public Constant: DEFAULT_TYPES here ?
There was a problem hiding this comment.
why then we need to provide association if setOf(TracingHeaderType.DATADOG, TracingHeaderType.TRACECONTEXT) is what already set in the SDK by default? Shouldn't we have a public API for both firstPartyHosts and firstPartyHostsWithHeaderType as we have now?
There was a problem hiding this comment.
we could but the way I see it firstPartyHosts is mandatory (not optional) so it will have to be in the Builder constructor. If we want to introduce both APIs and if a user wants to provide custom headerTypes for each host it will look like this:
val builder = Builder(tracedHosts).setFirstPartyHostsWithHeaderTypes(firstPartyHostsWithHeaderTypes)
I do not like that.
There was a problem hiding this comment.
otherwise we could have:
val builder = Builder().setFirstPartyHostsWithHeaderTypes(firstPartyHostsWithHeaderTypes)
val builder = Builder().setFirstPartyHosts(firstPartyHosts)
But this will mean that some users will forget to set this up in the builder and will create support issues.
| ) | ||
| val interceptorBuilder = DatadogInterceptor.Builder(firstPartyHostsWithHeaderType) | ||
| .setTraceSampler(RateBasedSampler(sampleRate)) | ||
| sdkInstanceName?.let { interceptorBuilder.setSdkInstanceName(it) } |
There was a problem hiding this comment.
I would pull sdkInstanceName to the DatadogInterceptor.Builder constructor - SDK core association is a major part of the API, not something optional.
There was a problem hiding this comment.
in the same time we have it optional now, I would only do that if we do not allow it as optional anymore otherwise it doesn't make sense to have it in the constructor if it can be NULL
| private val sampleRate: Float = DEFAULT_SAMPLE_RATE | ||
| ) : AppGlideModule() { | ||
|
|
||
| private val firstPartyHostsWithHeaderType = firstPartyHosts.associateWith { |
There was a problem hiding this comment.
why then we need to provide association if setOf(TracingHeaderType.DATADOG, TracingHeaderType.TRACECONTEXT) is what already set in the SDK by default? Shouldn't we have a public API for both firstPartyHosts and firstPartyHostsWithHeaderType as we have now?
| /** | ||
| * A Builder for the [DatadogInterceptor]. | ||
| */ | ||
| open class Builder(tracedHosts: Map<String, Set<TracingHeaderType>>) : |
There was a problem hiding this comment.
We probably need to remove open modifier from here and DatadogInterceptor as well. I think it was originally added because we have RumInterceptor : DatadogInterceptor.
But removing it involves a risk - some customers may have already sub-classed DatadogInterceptor.
There was a problem hiding this comment.
I don't want to do that, at least not now.
| /** | ||
| * A Builder for the [DatadogInterceptor]. | ||
| */ | ||
| open class Builder(tracedHosts: Map<String, Set<TracingHeaderType>>) : |
There was a problem hiding this comment.
IMO having a map here is unnecessary complication and it should be just tracedHosts: List<String>. Asking to provide tracing header types may be too advanced and increases setup curve. Probably default header types will work for 90%+ installations.
There was a problem hiding this comment.
it will but then we will have to provide the setTracedHostWithHeaderTypes method in the Builder and that will create some confusion. It will look like this:
val builder = Builder(tracedHosts).setFirstPartyHostsWithHeaderTypes(firstPartyHostsWithHeaderTypes)
It will look ugly and users will wonder what is the need for the tracedHosts in the Builder.
There was a problem hiding this comment.
we will have to provide the setTracedHostWithHeaderTypes method in the Builder
It won't be needed if constructor itself will have another overload. APM setup is already quite complicated, we need to have it simpler with reasonable defaults.
There was a problem hiding this comment.
so we provide overloads to this Builder constructor ? I would rather not and just provide a public api DEFAULT_HEADER_TYPES = setOf(TracingHeaderType.DATADOG, TracingHeaderType.TRACECONTEXT)
We are trying to run away from overloads. I am opened to any of this options but I would prefer the one without overloads.
@xgouchet @plousada , what do you think ?
There was a problem hiding this comment.
We are trying to run away from overloads
It is just because there were too much of them in the original constructor. Basically we need to put what is mandatory in the constructor and cannot be replaced by some default value.
For now it is only the list of the traced hosts, and the rest of the pieces needed to make interceptor work can have a default value, so they go into the methods of the Builder - this separation was missing in the original design of the DatadogInterceptor. So having an overload just because of the single mandatory parameter looks fine to me.
|
|
||
| private var rumResourceAttributesProvider: RumResourceAttributesProvider = NoOpRumResourceAttributesProvider() | ||
|
|
||
| override fun getThis(): Builder { |
There was a problem hiding this comment.
Generics check the Builder and BaseBuilder class. It is just a patter for having a BaseBuilder using Java Generics. In any case this is internal
There was a problem hiding this comment.
Tip
Maybe this method could be protected, otherwise it might be confusing to our customers
@xgouchet it is internal and not visible from outside the package. Check the method definition in the BaseBuilder class.
|
|
||
| /** | ||
| * Sets the [RumResourceAttributesProvider] to use to provide custom attributes to the RUM. | ||
| * By default, it is a NoOp. |
There was a problem hiding this comment.
| * By default, it is a NoOp. | |
| * By default, it won't attach any custom attributes. |
8b3c6ab to
446a7b4
Compare
595cd99 to
9e0b008
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #2111 +/- ##
===========================================
- Coverage 70.03% 69.92% -0.11%
===========================================
Files 721 722 +1
Lines 26773 26859 +86
Branches 4499 4506 +7
===========================================
+ Hits 18749 18780 +31
- Misses 6771 6819 +48
- Partials 1253 1260 +7
|
9e0b008 to
1225d92
Compare
|
|
||
| private var rumResourceAttributesProvider: RumResourceAttributesProvider = NoOpRumResourceAttributesProvider() | ||
|
|
||
| override fun getThis(): Builder { |
There was a problem hiding this comment.
Tip
Maybe this method could be protected, otherwise it might be confusing to our customers
@xgouchet it is internal and not visible from outside the package. Check the method definition in the BaseBuilder class.
1225d92 to
5dfc191
Compare
| class Builder : BaseBuilder<DatadogInterceptor, Builder> | ||
| constructor(Map<String, Set<com.datadog.android.trace.TracingHeaderType>>) | ||
| constructor(List<String>) | ||
| override fun getThis(): Builder |
There was a problem hiding this comment.
blocking: we shouldn't have this as a part of the public API. Is there a way to avoid that?
There was a problem hiding this comment.
hmm I really do not know why is added here as it is marked as internal. I need to check again. Thanks for spotting this. Do you have any idea why it still appears here ?
There was a problem hiding this comment.
maybe I should mark it as internal also when I override...let me try that...that will be stupid
| } | ||
|
|
||
| fun getExpectedOrigin(): String? { | ||
| return fakeOrigin |
There was a problem hiding this comment.
Minor: Why do we need this method and not compare directly to fakeOrigin? Also, can this return a null value? fakeOrigin is defined as an alphabetical string so should be non-null
There was a problem hiding this comment.
just legacy code that I did not change
e22f2fd to
39f6e13
Compare
0xnm
left a comment
There was a problem hiding this comment.
reviewed only prod files (not tests), looks good to me. I left some suggestions.
| public fun <init> (Ljava/util/Map;)V | ||
| public fun build ()Lcom/datadog/android/okhttp/DatadogInterceptor; | ||
| public synthetic fun build ()Lcom/datadog/android/okhttp/trace/TracingInterceptor; | ||
| public synthetic fun getThis$dd_sdk_android_okhttp_release ()Lcom/datadog/android/okhttp/trace/TracingInterceptor$BaseBuilder; |
There was a problem hiding this comment.
we are still exposing such things in Java API. Maybe there is some annotation which may hide it?
There was a problem hiding this comment.
will try but honestly if there's not any I will not fix this tool in this PR
| /** | ||
| * A Builder for the [DatadogInterceptor]. | ||
| * @param tracedHostsWithHeaderType a list of all the hosts and header types that you want to | ||
| * be automatically tracked by this interceptor. If registering a GlobalTracer, the tracer must be |
There was a problem hiding this comment.
| * be automatically tracked by this interceptor. If registering a GlobalTracer, the tracer must be | |
| * be automatically tracked by this interceptor. If registering a [GlobalTracer], the tracer must be |
| /** | ||
| * A Builder class for the [TracingInterceptor]. | ||
| * @param tracedHostsWithHeaderType a list of all the hosts and header types that you want to | ||
| * be automatically tracked by this interceptor. If registering a GlobalTracer, the tracer must be |
There was a problem hiding this comment.
| * be automatically tracked by this interceptor. If registering a GlobalTracer, the tracer must be | |
| * be automatically tracked by this interceptor. If registering a [GlobalTracer], the tracer must be |
| return getThis() | ||
| } | ||
|
|
||
| @Suppress("UndocumentedPublicFunction") |
There was a problem hiding this comment.
can be removed, it is not a public function anymore
| internal abstract fun getThis(): R | ||
|
|
||
| /** | ||
| * Build the [TracingInterceptor]. |
There was a problem hiding this comment.
| * Build the [TracingInterceptor]. | |
| * Build the interceptor. |
39f6e13 to
0470b37
Compare
What does this PR do?
Following the requirements specified in this RFC we are adding this new API and fixing the traces propagation in our
TracingInterceptor.This also fixes the issue: #2124
Motivation
What inspired you to submit this pull request?
Additional Notes
Anything else we should know when reviewing?
Review checklist (to be filled by reviewers)