-
Notifications
You must be signed in to change notification settings - Fork 644
Description
A mutable SpanBuilder is given to Tracer::build_with_context, which is intended to make a decision about whether the returned Span will be recording (or not) or sampled (or not). The whole goal of this api is to efficiently abstract away details which may impact the performance of instrumentation from the actual instrumenting library.
Part of the input to the decision whether to record/sample the span is the set of attributes provided by the SpanBuilder. But these attributes (and all the other information in the builder) is given up (taken away from the builder) when Tracer::build_with_context is called... even for 99.9% of all spans which are not recording in the case when sdk configures 0.1% sampling rate.
IOW, if the goal of well-performing instrumentation is to avoid unnecessary work (especially memory allocations) when instrumentation is not being recorded, then why/how does it make sense to require the API caller to allocate and give up a set of attributes just to make the sampling decision? Shouldn't the API take this information by immutable reference, then copy from it in the rare cases when the span will be selected for recording/sampling?
Referring to the spec:
The API documentation MUST state that adding attributes at span creation is preferred to calling SetAttribute later, as samplers can only consider information already present during span creation.
I think that in order to align with the intention of minimal performance overhead when not recording, we have to allow a set of immutably borrowed attributes to be the basis of the sampling decision, not ones where ownership must be given away to make each decision and initially populate the span attributes.
@jtescher, @TommyCpp, @djc would love your opinions on this. Thanks!