Skip to content
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(detector-alibaba)!: change implementation to DetectorSync interface #2328

Merged

Conversation

david-luna
Copy link
Contributor

@david-luna david-luna commented Jul 12, 2024

Context

In order to fix #2320 we need to suppress tracing when this detector is doing HTTP requests or using any other instrumented API. IMO this would be easier if we already have the detectors implementing the DetectorSync interface moving away from the deprecated Detector. This PR is adding a new sync detector that will be used by the SDK and auto-instrumentations package (to be changed in a follow-up PR).

Follow-up PRs will be created to:

  • suppressTracing
  • use the sync detector in auto-instrumentations

Short description of the changes

  • Make the current detector implement the DetectorSync interface
  • update tests

Test changes

The new detector's detect method becomes synchronous and therefore there is no way to throw an exception in it for an async HTTP error. The refactor makes this detector to return and empty resource if an async error occurs, so the test does not expect an exception anymore but an empty resource.

Also this aligns with @opentelemetry/resources logic used by the NodeSDK which catches any exception from the detector and returns an empty resource.
https://github.com/open-telemetry/opentelemetry-js/blob/54b14fbbe33e0cf38115ee8c5c934a4e27786186/packages/opentelemetry-resources/src/detect-resources.ts#L32

Copy link

codecov bot commented Jul 12, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 90.40%. Comparing base (dfb2dff) to head (fe26750).
Report is 199 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2328      +/-   ##
==========================================
- Coverage   90.97%   90.40%   -0.57%     
==========================================
  Files         146      149       +3     
  Lines        7492     7361     -131     
  Branches     1502     1527      +25     
==========================================
- Hits         6816     6655     -161     
- Misses        676      706      +30     
Files Coverage Δ
...aba-cloud/src/detectors/AlibabaCloudEcsDetector.ts 97.77% <100.00%> (+0.10%) ⬆️
...urce-detector-alibaba-cloud/src/detectors/index.ts 100.00% <100.00%> (ø)

... and 66 files with indirect coverage changes

Copy link
Member

@legendecas legendecas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @opentelemetry/resources version requirement in the package.json needs to be updated as ^1.10.0.

[SEMRESATTRS_HOST_TYPE]: instanceType,
[SEMRESATTRS_HOST_NAME]: hostname,
};
} catch {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could a diag log be added for the error?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the rejection is handled at https://github.com/open-telemetry/opentelemetry-js/blob/54b14fbbe33e0cf38115ee8c5c934a4e27786186/packages/opentelemetry-resources/src/Resource.ts#L87-L91. I think we should propagate the error instead of discarding it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree.

@legendecas
Copy link
Member

I think a more non-breaking way would be add a new AlibabaCloudEcsDetectorSync given that https://github.com/open-telemetry/opentelemetry-js/blob/54b14fbbe33e0cf38115ee8c5c934a4e27786186/packages/opentelemetry-resources/src/types.ts#L31-L41 the DetectorSync has a different method signature (return type) of detect.

@david-luna
Copy link
Contributor Author

I think a more non-breaking way would be add a new AlibabaCloudEcsDetectorSync given that https://github.com/open-telemetry/opentelemetry-js/blob/54b14fbbe33e0cf38115ee8c5c934a4e27786186/packages/opentelemetry-resources/src/types.ts#L31-L41 the DetectorSync has a different method signature (return type) of detect.

@legendecas thanks for the suggestion. I'll apply the changes here and bring it up to the JS SIG to get more feedback and, if accepted, apply it also to the other detectors.

@trentm
Copy link
Contributor

trentm commented Jul 30, 2024

THe diff got big because the implementation moved from the ...Detector.ts to ...DetectorSync.ts file. If it helps, here is the diff between the current Detector.ts file on "main" and the DetectorSync.ts file in this PR:

the diff
--- /Users/trentm/src/opentelemetry-js-contrib/detectors/node/opentelemetry-resource-detector-alibaba-cloud/src/detectors/AlibabaCloudEcsDetector.ts	2024-04-16 11:49:08
+++ AlibabaCloudEcsDetectorSync.ts	2024-07-29 17:34:07
@@ -15,8 +15,10 @@
  */

 import {
-  Detector,
+  DetectorSync,
+  IResource,
   Resource,
+  ResourceAttributes,
   ResourceDetectionConfig,
 } from '@opentelemetry/resources';
 import {
@@ -38,7 +40,7 @@
  * AlibabaCloud ECS and return a {@link Resource} populated with metadata about
  * the ECS instance. Returns an empty Resource if detection fails.
  */
-class AlibabaCloudEcsDetector implements Detector {
+class AlibabaCloudEcsDetectorSync implements DetectorSync {
   /**
    * See https://www.alibabacloud.com/help/doc-detail/67254.htm for
    * documentation about the AlibabaCloud instance identity document.
@@ -57,7 +59,14 @@
    *
    * @param config (unused) The resource detection config
    */
-  async detect(_config?: ResourceDetectionConfig): Promise<Resource> {
+  detect(_config?: ResourceDetectionConfig): IResource {
+    return new Resource({}, this._getAttributes());
+  }
+
+  /** Gets identity and host info and returns them as attribs. Empty object if fails */
+  async _getAttributes(
+    _config?: ResourceDetectionConfig
+  ): Promise<ResourceAttributes> {
     const {
       'owner-account-id': accountId,
       'instance-id': instanceId,
@@ -67,7 +76,7 @@
     } = await this._fetchIdentity();
     const hostname = await this._fetchHost();

-    return new Resource({
+    return {
       [SEMRESATTRS_CLOUD_PROVIDER]: CLOUDPROVIDERVALUES_ALIBABA_CLOUD,
       [SEMRESATTRS_CLOUD_PLATFORM]: CLOUDPLATFORMVALUES_ALIBABA_CLOUD_ECS,
       [SEMRESATTRS_CLOUD_ACCOUNT_ID]: accountId,
@@ -76,7 +85,7 @@
       [SEMRESATTRS_HOST_ID]: instanceId,
       [SEMRESATTRS_HOST_TYPE]: instanceType,
       [SEMRESATTRS_HOST_NAME]: hostname,
-    });
+    };
   }

   /**
@@ -144,4 +153,4 @@
   }
 }

-export const alibabaCloudEcsDetector = new AlibabaCloudEcsDetector();
+export const alibabaCloudEcsDetectorSync = new AlibabaCloudEcsDetectorSync();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this test file (of the old, unchanged non-Sync detector) be reverted back to its original state?

(I wonder if some of the tests below are passing because of luck.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@trentm

Since the async detector is leveraging the new sync detector there's a change in behavior that makes the original tests fail. The difference is the detector's detect method does not throw anymore.

I guess that's something we do not want. I'll share it in the upcoming SIG to get feedback.

@david-luna
Copy link
Contributor Author

david-luna commented Jul 31, 2024

Hi @legendecas

in today's JavaScript SIG we discussed this and the other detector PRs. The conclusion was it's okay to do a breaking change for non stable detectors if the owner is okay with it. In this detector you suggested a non breaking change so I've added another detector complying with DetectorSync interface and export both.

It's worth mentioning the former detector reused the new one following the pattern existing in the core repo (example). With this approach the detector does not throw but returns an empty resource, tests are changed accordingly. This was also discussed in the SIG and agreed that the change of behavior should not be considered a breaking change.

Also since were adding a new detector I'll rename this PR to feat instead of refactor

I think trent's comment points to what is the main change here.

@david-luna david-luna changed the title refactor(detector-alibaba): change implementation to DetectorSync interface feat(detector-alibaba): add AlibabaCloudDetectorSync Jul 31, 2024
@legendecas
Copy link
Member

Thanks for the update! I think I am fine with breaking if we do all the same with other detectors, given that the test might be more complex if we have two variants.

Copy link
Contributor

@trentm trentm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just the test file name nit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Ecs" in the filename was accidentally removed in the shuffling?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, my bad

@trentm
Copy link
Contributor

trentm commented Jul 31, 2024

I approved, but I guess we are now considering dropping the ...Detector non-Sync classes for all the non-stable detectors. I'm cool with that as well.

@david-luna
Copy link
Contributor Author

david-luna commented Aug 1, 2024

Thanks @legendecas & @trentm for your feedback. I think dropping the async detector is the best course of action now that we agree on it.

So I'm going to revert the changes to the 1st proposal and refactor the detector from async to sync.

@@ -14,4 +14,4 @@
* limitations under the License.
*/

export * from './detectors';
export { alibabaCloudEcsDetector } from './detectors';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to reviewer: little step forward to resolve open-telemetry/opentelemetry-js#4186

@@ -84,56 +85,47 @@ describe('alibabaCloudEcsDetector', () => {
});

describe('with unsuccessful request', () => {
it('should throw when receiving error response code', async () => {
const expectedError = new Error('Failed to load page, status code: 404');
it('should return empty resource when receiving error response code', async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to reviewer: the detector does not throw but rather returns a resource with no attribs.

@david-luna david-luna changed the title feat(detector-alibaba): add AlibabaCloudDetectorSync feat(detector-alibaba)!: change implementation to DetectorSync interface Aug 1, 2024
@david-luna david-luna merged commit 25e85c7 into open-telemetry:main Aug 2, 2024
21 checks passed
@david-luna david-luna deleted the dluna/aibaba-ecs-detector-sync branch August 2, 2024 07:25
@dyladan dyladan mentioned this pull request Aug 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

traces of resource detectors being sent
5 participants