opentelemetry-js
opentelemetry-js copied to clipboard
Create sync resource with some attributes that resolve asynchronously
Which problem is this PR solving?
Fixes #2912
Short description of the changes
I spoke to @aabmass and agreed on taking on this issue and reopening his PR #2933 and build on it, as I think he has one of the best solutions for this issue.
- In
@opentelemetry/sdk-node- Adds an optional Promise<ResourceAttributes> to the Resource constructor which can asynchronously resolve some attributes. When this promise resolves, the attributes will be merged with the "synchronous" attributes.
- Deprecated
detectResources()in favor of a new methoddetectResourcesSync()which defers promises into the resource to be resolved later - Update
Detector.detect()signature to allow it to be synchronous and updated documentation that the synchronous variant should be used
- In
@opentelemetry/sdk-node- Updated
NodeSDK.start()and its dependencies to now be synchronous (doesn't return a promise). This is a breaking change, but that package is experimental.
- Updated
- Updated
BatchSpanProcessorBaseandSimpleSpanProcessorto await the resource promise before calling exporters, if the resource has asynchronous attributes AND they have not already resolved. I.e. if there is no promise in the Resource (the case for existing detectors and code), the behavior is unchanged.
Type of change
- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing functionality not to work as expected)
How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
- [x] Existing tests pass with no modification
- [x] Added new tests to Resource.test.ts
- [x] Added detect-resources.test.ts
Checklist:
- [x] Followed the style guidelines of this project
- [x] Unit tests have been added
- [ ] Documentation has been updated
Codecov Report
Merging #3460 (c8bd141) into main (3bc0807) will increase coverage by
1.71%. The diff coverage is88.01%.
:exclamation: Current head c8bd141 differs from pull request most recent head 60a161a. Consider uploading reports for the commit 60a161a to get more accurate results
Additional details and impacted files
@@ Coverage Diff @@
## main #3460 +/- ##
==========================================
+ Coverage 92.32% 94.04% +1.71%
==========================================
Files 153 268 +115
Lines 3608 7920 +4312
Branches 727 1641 +914
==========================================
+ Hits 3331 7448 +4117
- Misses 277 472 +195
| Impacted Files | Coverage Δ | |
|---|---|---|
| ...ntelemetry-browser-detector/src/BrowserDetector.ts | 14.28% <0.00%> (ø) |
|
| packages/opentelemetry-sdk-trace-base/src/Span.ts | 98.58% <ø> (+0.70%) |
:arrow_up: |
| ...ackages/opentelemetry-sdk-trace-base/src/Tracer.ts | 98.59% <ø> (ø) |
|
| packages/sdk-metrics/src/export/MetricData.ts | 100.00% <ø> (ø) |
|
| ...es/opentelemetry-resources/src/detect-resources.ts | 64.58% <64.58%> (ø) |
|
| ...opentelemetry-resources/src/platform/node/utils.ts | 66.66% <66.66%> (ø) |
|
| ...etrics/src/export/PeriodicExportingMetricReader.ts | 92.98% <70.00%> (ø) |
|
| ...dk-trace-base/src/export/BatchSpanProcessorBase.ts | 92.30% <78.57%> (-2.26%) |
:arrow_down: |
| ...y-sdk-trace-base/src/export/SimpleSpanProcessor.ts | 91.42% <90.00%> (+7.42%) |
:arrow_up: |
| ...lemetry-resources/src/detectors/EnvDetectorSync.ts | 94.11% <94.11%> (ø) |
|
| ... and 138 more |
What if we remove the concept of async resources entirely? We could simply update the SDK to accept sync resource detectors and/or sync resource objects (all stable components already assume resource is sync). Any resource which is gathered async would be the responsibility of the end-user to decide how to start their application. The future appendable resources would also work well in that sync-only world.
/cc @open-telemetry/javascript-maintainers see the above comment
@dyladan What if we remove the concept of async resources entirely? We could simply update the SDK to accept sync resource detectors and/or sync resource objects (all stable components already assume resource is sync). Any resource which is gathered async would be the responsibility of the end-user to decide how to start their application. The future appendable resources would also work well in that sync-only world.
It sounds very promising to distinguish the synchronicity of Detectors at startup rather than burdening the downstream consumers of Resource at runtime -- like the iteration to find un-resolved resources in every export of the BatchSpanProcessor. My +1 for the proposed approach.
What if we remove the concept of async resources entirely? We could simply update the SDK to accept sync resource detectors and/or sync resource objects (all stable components already assume resource is sync). Any resource which is gathered async would be the responsibility of the end-user to decide how to start their application. The future appendable resources would also work well in that sync-only world.
We know that users need async resources, so these users will now have to modify their code and how it starts (in a non trivial manner). This means they cannot use shelf-made SDKs and auto instrumentation agents, and they will have a hard time with frameworks, cloud functions, and such where they do not control how the code starts.
I think this will cause friction and users will ask for help and guidance and I am not sure we will always have solutions for them.
Thanks for working on this!
LGTM. This can merge as far as I am concerned.
Thanks a lot for taking this important and complicated task
Thank you for taking the time to review! :)