# Specify instrument modules instead of automatic detection

**URL:** <https://discuss.elastic.co/t/specify-instrument-modules-instead-of-automatic-detection/262559>\
**Category:** APM\
**Tags:** nodejs\
**Created:** [January 28, 2021, 7:57pm UTC](https://discuss.elastic.co/t/specify-instrument-modules-instead-of-automatic-detection/262559 "2021-01-28T19:57:52Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ebuildy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ebuildy/32/6070_2.png) [@ebuildy](https://discuss.elastic.co/u/ebuildy)\
**Post date:** [January 28, 2021, 7:57pm UTC](https://discuss.elastic.co/t/specify-instrument-modules-instead-of-automatic-detection/262559/1 "2021-01-28T19:57:52Z")

</div>

Using nodeJS 12 / ES6.

Some libraries are not detected because: `import * as IORedis from 'ioredis';`

We had to change it to `require("ioredis");` to have ioredis lib detected.

I see there is something called "require-in-the-middle" that spy all nodejs `require` to detect automatically libraries used.

What about adding an option to specify this list instead of detecting it?

---

<div class="post-metadata">

**Author:** ![alanstorm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/alanstorm/32/77134_2.png) [@alanstorm](https://discuss.elastic.co/u/alanstorm)\
**Post date:** [January 28, 2021, 9:30pm UTC](https://discuss.elastic.co/t/specify-instrument-modules-instead-of-automatic-detection/262559/2 "2021-01-28T21:30:12Z")

</div>

Thanks for reporting @ebuildy -- we've recently opened an issue to track our support for ECMAScript/`import` modules. You can find that issue [on GitHub](https://github.com/elastic/apm-agent-nodejs/issues/1952) -- if you have additional thoughts we'd welcome your feedback there as well.

For broader context -- the `require-in-the-middle` module is how the Node.js knows you've called a certain method in your application, and how we add out method/span timings. A standard module for doing similar things with ECMAScript modules hasn't emerged yet.

If you have a moment to answer a question -- how are you using ECMAScript import statements in your Node 12 project? Are you compiling/transpiling your program, or are you using the `experimental` flags with Node.js to enable this feature? Or some third thing?

Thanks again for your feedback -- it helps us make the product better for everyone.

---

<div class="post-metadata">

**Author:** ![ebuildy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ebuildy/32/6070_2.png) [@ebuildy](https://discuss.elastic.co/u/ebuildy)\
**Post date:** [January 29, 2021, 8:27am UTC](https://discuss.elastic.co/t/specify-instrument-modules-instead-of-automatic-detection/262559/3 "2021-01-29T08:27:31Z")

</div>

Thanks you, we use TypeScript , with target: es2017.

Is it possible to manually set instrumentation modules instead of relying on detection (which seem broken and also cost performance)?

---

<div class="post-metadata">

**Author:** ![trentm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/trentm/32/77647_2.png) [@trentm](https://discuss.elastic.co/u/trentm)\
**Post date:** [January 29, 2021, 5:36pm UTC](https://discuss.elastic.co/t/specify-instrument-modules-instead-of-automatic-detection/262559/4 "2021-01-29T17:36:19Z")

</div>

@ebuildy Hi. Currently, no, there isn't a config variable to specify modules to instrument. There is [this issue](https://github.com/elastic/apm-agent-nodejs/issues/1915) that considers a `requireInstrumentations` option that would support that.

I'll add a note on that ticket about this discussion/use case -- which helps with prioritization.

Note that there are still potential surprises when using ES modules (`import ...`). Because `import`s fully parse and execute all imports in a file before executing that file, that means that something like:

```auto
import apm from 'elastic-apm-node'
apm.start(/* my config ... */)

```

can result in instrumentation of modules happening _after_ user code has references to those modules. _Some_ instrumentation still works in this case, some doesn't.

As well, it is possible that some 3rd party packages will provide separate ES module and CommonJS module files. User usage of `import 'foo'`, plus APM instrumentation of `require('foo')` will then lead to two separate loads of the same package, and hence broken instrumentation.

---

<div class="post-metadata">

**Author:** ![trentm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/trentm/32/77647_2.png) [@trentm](https://discuss.elastic.co/u/trentm)\
**Post date:** [January 29, 2021, 5:40pm UTC](https://discuss.elastic.co/t/specify-instrument-modules-instead-of-automatic-detection/262559/5 "2021-01-29T17:40:44Z")

</div>

@ebuildy I was playing around a little bit, and here is a possible workaround. I'm not sure on how well this would integrate with your TypeScript usage.

Instead of starting your initial script with:

```auto
import apm from 'elastic-apm-node/start.js'

```

write a CommonJS apmsetup.cjs file like this:

```auto
'use strict'
module.exports = (function () {
    const apm = require('elastic-apm-node')
    apm.start({
        // ...
    })
    // Pre-require modules for instrumentation as a workaround for
    // `import 'foo'` not being detected.
    require('http')
    require('ioredis')
    return apm
})()

```

and replace the `import apm ...` above with:

```auto
import apm from './apmsetup.cjs'

```

In my small test that resulted in successfully getting http and ioredis instrumentation. I'm curious if this works for you.

---

<div class="post-metadata">

**Author:** ![alanstorm](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/alanstorm/32/77134_2.png) [@alanstorm](https://discuss.elastic.co/u/alanstorm)\
**Post date:** [January 29, 2021, 8:50pm UTC](https://discuss.elastic.co/t/specify-instrument-modules-instead-of-automatic-detection/262559/6 "2021-01-29T20:50:53Z")

</div>

Ah ha, that's interesting @ebuildy. I had not realized you were using typescript, and presumed you were using node 12's experimental support for ECMAScript modules. The Node.js Agent does support (certain configurations of) typescript. Now that we know you're using typescript I have a few additional questions/comments that might help/inform us here.

You mentioned you're using typescript with

```auto
target: es2017

```

First -- what is your `module` configuration set to? If it's set to `"module": "commonjs"` (TypeScript's default) you should end up with code that uses native `require` statements. They, in turn, should work with the agent. If it's set to something else, what is it set to?

Second -- how are you compiling your typescript? Is there a bundler (webpack, bablel, etc.) involved? If so, bundlers can often move/disrupt the requirement that the Node.js Agent be the first thing that's loaded in the program. If that's the case, loading the agent with a `--require` option

```auto
node --require elastic-apm-node [...other flags if you have them...] path/to/start/file.js

```

and using env variables for configuration can solve a whole host of issues related to a bundler/compilers that can't comply with "the agent must be first".

Thanks again for taking the time to report/answer these question. Getting these discussions out in the open almost always helps other folks who may be having similar issues, and helps make our product better.

---

<div class="post-metadata">

**Author:** ![ebuildy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ebuildy/32/6070_2.png) [@ebuildy](https://discuss.elastic.co/u/ebuildy)\
**Post date:** [February 2, 2021, 8:55am UTC](https://discuss.elastic.co/t/specify-instrument-modules-instead-of-automatic-detection/262559/7 "2021-02-02T08:55:42Z")

</div>

Hello,

Sure I am always happy to help elastic guys, I follow elasticsearch from the beginning and love the products and also the philosophy (especially this last time!).

I am not the nodejs dev, so I try to give you best answer as possible:

File tsconfig.json:

```auto
{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "paths": {
      "@app/*": ["src/*"],
      "@test/*": ["test/*"]
    }
  },
  "exclude": ["node_modules", "dist"]
}

```

This is a nestJS application, we setup elasticAPM in the main.ts file.

**Actually I have found the issue, `import * as IORedis from 'ioredis';` was ignored! I have added a dummy `new IORedis();` then its ok!**

So I am sorry, the root cause was include ioredis before `apm.start();`. But this do not work if we do this after, I am investigating.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [February 23, 2021, 4:55am UTC](https://discuss.elastic.co/t/specify-instrument-modules-instead-of-automatic-detection/262559/8 "2021-02-23T04:55:49Z")

</div>

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.
