-
Notifications
You must be signed in to change notification settings - Fork 457
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
feat: add default resource in TracerProvider if user didn't provide one. #571
Conversation
Codecov Report
@@ Coverage Diff @@
## main #571 +/- ##
======================================
Coverage 54.7% 54.7%
======================================
Files 101 102 +1
Lines 8667 8840 +173
======================================
+ Hits 4744 4839 +95
- Misses 3923 4001 +78
Continue to review full report at Codecov.
|
vec![Box::new(SdkProvidedResourceDetector)], | ||
); | ||
if config.resource.is_none() { | ||
config.resource = Some(Arc::new(sdk_provided_resource)) |
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.
We may want to consider the perf impact here, I believe that cloning the resource had a measurable impact on spans with few attributes.
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.
Sounds reasonable. But I'd argue this usually only happens when the application starts so it may not impact performance that much. I can create sdk_provided_resource
only when there isn't a resource already configured so that could reduce some overhead.
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.
Was thinking more about the clone each time a span is exported, could check
trace_benchmark_group(c, "start-end-span", |tracer| tracer.start("foo").end()); |
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.
Yeah, you are right. This will add an attribute to each span by default. But users can avoid that by passing an empty resource in the config. Will benchmark it before mark this ready.
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 ran the bench. With default resource & required attributes:
start-end-span/always-sample
time: [536.05 ns 538.61 ns 541.21 ns]
change: [+18.240% +18.917% +19.533%] (p = 0.00 < 0.05)
Performance has regressed.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
start-end-span/never-sample
time: [166.50 ns 166.98 ns 167.66 ns]
change: [+0.1332% +0.4798% +0.8373%] (p = 0.01 < 0.05)
Change within noise threshold.
Found 3 outliers among 100 measurements (3.00%)
1 (1.00%) high mild
2 (2.00%) high severe
The performance impact is concerning. But looking at the spec
The SDK MUST provide access to a Resource with at least the attributes listed at Semantic Attributes with SDK-provided Default Value. This resource MUST be associated with a TracerProvider or MeterProvider if another resource was not explicitly specified.
I think it's clear we need to build a resource with service.name
and associate it with TracerProvider
.
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.
Hmm, I don't think that works for resources created from environment variables? Because we cannot know the value in the compile time. I am thinking if users can somehow explicitly says they don't want any resource maybe we could avoid the overhead.
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.
@jtescher I guess a workaround here is to explicitly pass an empty resource into the config to indicate users don't want any resource including the one provided by SDK by default. Then we won't have any performance impact on users.
We can check if the resource is empty in Builder::build()
and if it's empty we just replace it with None
because Some(Resource::empty())
is the same in this case.
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.
Hm yeah that's a possibility. Wonder if there should be an explicit method in the builder or otherwise more discoverable method. People doing comparisons like https://github.com/tikv/minitrace-rust/blob/master/benches/compare.rs will likely miss the possible optimizations otherwise.
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.
Added a with_no_resource
method for that purpose.
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 can merge this for now and add a check in the 1.0 readiness to see if breaking changes are necessary for perf reasons
* Add get method for Resource.
* Add testing/metrics.rs.
Using SDK to provide a default service name if none is provided by users.
Since the resource is immutable. Some(Resource::empty()) should be equal to None and None will have better performance in this case.
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.
Looks good for now, we can re-assess if changes are needed to fix the perf issues before 1.0
Okay thank goodness I'm going to be in the car |
MeterProvider
s.- [ ] Add more resource detector?Will probably do it in another PR.fix #558
This PR:
SdkProvidedResourceDetector
to detect attributes that should be provided by SDK if not specified otherwise. As for now, it'sservice.name