-
Notifications
You must be signed in to change notification settings - Fork 820
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
fix(instrumentation-http): Ensure instrumentation of http.get
and https.get
work when used in ESM code
#4866
Conversation
…https.get` work when used in ESM code The issue was that the `_wrap`ing of `http.get` was getting the just-wrapped `http.request` by accessing `moduleExports.request`. However, when wrapping an ES module the `moduleExports` object from IITM is a Proxy object that allows setting a property, but *not* re-getting that set property. The fix is to use the wrapped `http.request` from the `this._wrap` call. That required fixing a bug in the IITM code-path of `InstrumentationBase.prototype._wrap` to return the wrapped property. (The previous code was doing `return Object.defineProperty(...)`, which returns the moduleExports, not the defined property.) Fixes: open-telemetry#4857
experimental/packages/opentelemetry-instrumentation-http/test/integrations/esm.test.mjs
Fixed
Show resolved
Hide resolved
experimental/packages/opentelemetry-instrumentation-http/test/integrations/esm.test.mjs
Fixed
Show fixed
Hide fixed
"test": "nyc mocha test/**/*.test.ts", | ||
"test:cjs": "nyc mocha test/**/*.test.ts", | ||
"test:esm": "nyc node --experimental-loader=@opentelemetry/instrumentation/hook.mjs ../../../node_modules/.bin/mocha 'test/**/*.test.mjs'", | ||
"test": "npm run test:cjs && npm run test:esm", |
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.
Reviewer note: This test:esm
script follows the same pattern used for ESM tests in opentelemetry-instrumentation.
@@ -49,7 +49,7 @@ | |||
"tdd:node": "npm run test -- --watch-extensions ts --watch", | |||
"tdd:browser": "karma start", | |||
"test:cjs": "nyc mocha 'test/**/*.test.ts' --exclude 'test/browser/**/*.ts'", | |||
"test:esm": "nyc node --experimental-loader=./hook.mjs ../../../node_modules/mocha/bin/mocha 'test/node/*.test.mjs' test/node/*.test.mjs", | |||
"test:esm": "nyc node --experimental-loader=./hook.mjs ../../../node_modules/mocha/bin/mocha 'test/node/*.test.mjs'", |
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.
Reviewer note: I think this was a typo from when this was originally added. The additional test/node/*.test.mjs
arg is redundant.
value: wrapped, | ||
}); | ||
return wrapped; |
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.
Reviewer note: From a quick check, I didn't see any core or contrib-repo instrumentations using the return value of this._wrap
. Arguably this is a "fix" for @opentelemetry/instrumentation
, but I didn't mention it in the CHANGELOG.
experimental/packages/opentelemetry-instrumentation/test/node/EsmInstrumentation.test.mjs
Show resolved
Hide resolved
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.
just a nit, otherwise LGTM
@trentm sorry I'm terrible with acronyms, what IITM means? |
My bad: It is import-in-the-middle (https://github.com/nodejs/import-in-the-middle). (And often RITM for require-in-the-middle.) |
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.
LGTM
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.
This is great, thanks for working on this! Appreciate the test updates as well. I left a few nits around the tests but the functionality itself is good. I'm now wondering about other instrumentations and what can be done there... but for now 🚀
experimental/packages/opentelemetry-instrumentation-http/test/integrations/esm.test.mjs
Outdated
Show resolved
Hide resolved
experimental/packages/opentelemetry-instrumentation-http/test/integrations/esm.test.mjs
Outdated
Show resolved
Hide resolved
experimental/packages/opentelemetry-instrumentation-http/test/integrations/esm.test.mjs
Outdated
Show resolved
Hide resolved
experimental/packages/opentelemetry-instrumentation-http/test/integrations/esm.test.mjs
Outdated
Show resolved
Hide resolved
return new InstrumentationNodeModuleDefinition( | ||
'test-esm-module', | ||
['*'], | ||
moduleExports => { | ||
this._wrap(moduleExports, 'testFunction', () => { | ||
return () => 'patched'; | ||
const wrapRetval = this._wrap(moduleExports, 'testFunction', () => { |
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.
const wrapRetval = this._wrap(moduleExports, 'testFunction', () => { | |
const wrappedReturnValue = this._wrap(moduleExports, 'testFunction', () => { |
This is a total nit, but I wonder if we could use a full name for this - primarily because this tends to be a confusing functionality and I'm a sucker for detailed variable names. Maybe something like patchedModule
, similar to the patchedRequest
you have in the http code? Nonblocking, especially since it's a test.
experimental/packages/opentelemetry-instrumentation-http/test/integrations/esm.test.mjs
Outdated
Show resolved
Hide resolved
Also I think this updates open-telemetry/opentelemetry-js-contrib#1942 now for http instrumentation? |
Co-authored-by: Jamie Danielson <[email protected]>
Co-authored-by: Jamie Danielson <[email protected]>
Co-authored-by: Jamie Danielson <[email protected]>
Co-authored-by: Jamie Danielson <[email protected]>
experimental/packages/opentelemetry-instrumentation-http/test/integrations/esm.test.mjs
Dismissed
Show dismissed
Hide dismissed
experimental/packages/opentelemetry-instrumentation-http/test/integrations/esm.test.mjs
Dismissed
Show dismissed
Hide dismissed
…https.get` work when used in ESM code (open-telemetry#4866) * fix(instrumentation-http): Ensure instrumentation of `http.get` and `https.get` work when used in ESM code The issue was that the `_wrap`ing of `http.get` was getting the just-wrapped `http.request` by accessing `moduleExports.request`. However, when wrapping an ES module the `moduleExports` object from IITM is a Proxy object that allows setting a property, but *not* re-getting that set property. The fix is to use the wrapped `http.request` from the `this._wrap` call. That required fixing a bug in the IITM code-path of `InstrumentationBase.prototype._wrap` to return the wrapped property. (The previous code was doing `return Object.defineProperty(...)`, which returns the moduleExports, not the defined property.) Fixes: open-telemetry#4857 * correct typo in the changelog message * does this fix the test:esm script running on windows? * remove other console.logs (presumably dev leftovers) from tests in this file * test name suggestion Co-authored-by: Jamie Danielson <[email protected]> * test name suggestion Co-authored-by: Jamie Danielson <[email protected]> * test name suggestion Co-authored-by: Jamie Danielson <[email protected]> * test name suggestion Co-authored-by: Jamie Danielson <[email protected]> * var naming suggestion: expand cres and creq, the abbrev isn't obvious --------- Co-authored-by: Jamie Danielson <[email protected]>
The issue was that the
_wrap
ing ofhttp.get
was getting thejust-wrapped
http.request
by accessingmoduleExports.request
.However, when wrapping an ES module the
moduleExports
object from IITMis a Proxy object that allows setting a property, but not re-getting
that set property.
The fix is to use the wrapped
http.request
from thethis._wrap
call.That required fixing a bug in the IITM code-path of
InstrumentationBase.prototype._wrap
to return the wrapped property.(The previous code was doing
return Object.defineProperty(...)
, whichreturns the moduleExports, not the defined property.)
Fixes: #4857