apm-agent-nodejs icon indicating copy to clipboard operation
apm-agent-nodejs copied to clipboard

ECMAScript Module Support

Open astorm opened this issue 4 years ago • 2 comments

In order to detect when certain methods are called and provide timings for those method calls, the Node.js Agent uses a module named require-in-the-middle. This module "hooks" (monkey-patches, intercepts, etc.) the initial loading of Node.js CommonJS module and allows us to wrap the methods we want with our custom timing and span generation.

Node 15 (and it's LTS support partner, Node 16) mark the support of ECMAScript modules (also known as ES6 modules) as non-experimental. https://nodejs.org/docs/latest-v15.x/api/esm.html#esm_modules_ecmascript_modules

This means third part code can begin using ECMAScript modules (import) in place of CommonJS modules (require). The require-in-the-middle module does not hook these new import/ECMAScript modules. This means any normally instrumented module that uses ECMAScript modules will not be instrumented by the Node.js Agent.

We need to determine the best was to hook these new modules. (perhaps the experimental loaders, perhaps compilation/transpilation, perhaps something else).

This will be a long term effort. If folks have ideas on approaches we'd love to hear about them.

Work Around: In the meantime, users can fallback to importing modules via require. If there's an instrumented module that's providing ECMAScript only modules, or the agent is somehow not working with the new ECMAScript features, we'd like to hear about them.

Todo:

  • [ ] #2343

astorm avatar Jan 28 '21 21:01 astorm

Relevant to Kibana here: https://github.com/elastic/kibana/issues/106868

trentm avatar Aug 03 '22 15:08 trentm

It would be really great to have esm support as it broadly used nowadays. Modern fullstack tooling like vite depends heavily on esm and it is either not possible or really time-consuming to convert all the generated code to cjs again. In my case I'm trying to set up apm with Sveltekit which kind of works, but in many cases I need to start transactions myself because modules cannot be monkey-patched. So I'm really looking forward to this feature.

nhe23 avatar Sep 09 '22 06:09 nhe23

+1 for node based backend with ts-node or others use .ts directly.

hjhjdev avatar Mar 08 '23 06:03 hjhjdev

We encountered this problem yesterday. Will this be delivered in 8.8? I can see it was originally considered for 8.1, 8.2 and 8.3 previously so trying to assess whether we hang fire for 8.8 or come up with alternative solutions.

cdavid15 avatar Mar 15 '23 07:03 cdavid15

@cdavid15 No, unfortunately 8.8 won't provide a complete solution for this. Full ESM support is a big change. It will rely on Node.js loader hooks, which are currently experimental and expected to change/break. It will require significant changes to how this agent is doing its auto-instrumentation to most, if not all, supported modules.

We've been using this issue over multiple milestones to do investigatory work. Apologies that that ends up being a bit misleading when we have it on a particular milestone. We're keen to have a solution for instrumenting ESM modules, but don't have an expected or firm target timeline for it yet.

trentm avatar Mar 24 '23 16:03 trentm

@trentm I have been keeping an eye on this ticket and latest activity suggests things may be more positive and moving forward now.

Any update on a target timeline even if not fully confirmed for the time being?

cdavid15 avatar Jun 02 '23 11:06 cdavid15

@cdavid15 I hope to have experimental support in a release in the next month or so -- but no promises on a date. ;) You can track my progress here: https://github.com/elastic/apm-agent-nodejs/pull/3381 So far it is going well.

trentm avatar Jun 02 '23 16:06 trentm

@trentm that's great news! Will keep a close eye on it!

cdavid15 avatar Jun 07 '23 07:06 cdavid15

Just upgraded and while following the docs to use the experimental loader I received an error as loader.mjs doesn’t exist int the published 3.48.0 package.

I downloaded the source directly from GitHub and dropped in the missing files and our APM transactions are now picked up again which is great but wanted to flag that I think the published package is invalid (unless I’ve missed something).

Will I create a new issue for this?

cdavid15 avatar Jul 26 '23 17:07 cdavid15

(Sorry for the slow reply. I was away last week.)

as loader.mjs doesn’t exist int the published 3.48.0 package.

@cdavid15 GAH! Thanks for reporting this. I am embarrassed to have missed this. I will get a fix in soon.

trentm avatar Aug 01 '23 21:08 trentm

(Sorry for the slow reply. I was away last week.)

as loader.mjs doesn’t exist int the published 3.48.0 package.

@cdavid15 GAH! Thanks for reporting this. I am embarrassed to have missed this. I will get a fix in soon.

Perfect thanks @trentm! Will keep an eye out for 3.49.0!

cdavid15 avatar Aug 02 '23 09:08 cdavid15

@cdavid15 3.49.0 is out now. Thanks.

trentm avatar Aug 03 '23 15:08 trentm