Skip to content

Latest commit

 

History

History
116 lines (86 loc) · 4.9 KB

esm.asciidoc

File metadata and controls

116 lines (86 loc) · 4.9 KB
Note
For the best reading experience, please view this documentation at elastic.co

ECMAScript module support

Note
ECMAScript module support is currently incomplete and experimental. It was added in version REPLACEME.

The Elastic APM Node.js agent includes limited and experimental support for auto-instrumentation of ECMAScript modules (ESM) — i.e. modules loaded via the import …​ statement or the import(…​) expression. Support is based on the experimental Node.js Loaders API, which requires passing the --experimental-loader option to node.

As a first example, the APM agent can provide HTTP tracing for the following Express server:

// server.mjs
import bodyParser from 'body-parser'
import express from 'express'

const app = express()
app.use(bodyParser.json())
app.get('/hello/:name', function (request, reply) {
  reply.send({ hello: request.params.name })
})

app.listen({ port: 3000}, () => {
  console.log('Server is listening. Try:\n  curl -i http://localhost:3000/hello/grace')
})

when invoked as follows:

export ELASTIC_APM_SERVER_URL='https://...apm...cloud.es.io:443'
export ELASTIC_APM_SECRET_TOKEN='...'
node -r elastic-apm-node/start.js \
  --experimental-loader=elastic-apm-node/loader.mjs' \
  node server.mjs

The current ESM support is limited — only a subset of the modules listed at [supported-technologies] are implemented. More will be added in subsequent releases. See below for full details.

The ESM limitations only affects the agent’s automatic instrumentation. Other functionality — such as metrics collection, manual instrumentation and error capture — still work when using ES modules.

Enabling ESM auto-instrumentation

Enabling ESM auto-instrumentation requires starting Node.js with the --experimental-loader=elastic-apm-node/loader.mjs option. This can be done by passing the argument on the command line or by setting the NODE_OPTIONS environment variable.

node --experimental-loader=elastic-apm-node/loader.mjs server.mjs

# or

NODE_OPTIONS='--experimental-loader=elastic-apm-node/loader.mjs'
node server.mjs

As well, the APM agent must also be separately started — for example via --require=elastic-apm-node/start.js. See [starting-the-agent] for the various ways of starting the APM agent.

Supported Node.js versions

Automatic instrumentation of ES modules is based on the experimental Node.js Loaders API. ESM support in the Elastic APM Node.js agent will remain experimental while the Loaders API is experimental.

ESM auto-instrumentation is only supported for Node.js versions that match ^12.20.0 || ^14.13.1 || ^16.0.0 || >=18.1.0. The behavior when using node --experimental-loader=elastic-apm-node/loader.mjs with earlier Node.js versions is undefined and unsupported.

Supported modules

Automatic instrumentation of ES modules is currently limited as described here. Note that the supported module version ranges often differ from those for CommonJS (i.e. require()) auto-instrumentation.

Module Version Note

@aws-sdk/client-s3

>=3.15.0 <4

express

^4.0.0

fastify

>=3.5.0

http

See Supported Node.js versions above.

https

See Supported Node.js versions above.

ioredis

>=2 <6

knex

>=0.20.0 <3

Also, only with pg@8.

pg

^8

Troubleshooting ESM support

If you see an error like the following, then you are attempting to use ESM auto-instrumentation support with too early of a version of Node.js. See Supported Node.js versions above.

file:///.../node_modules/import-in-the-middle/hook.mjs:6
import { createHook } from './hook.js'
         ^^^^^^^^^^
SyntaxError: The requested module './hook.js' is expected to be of type CommonJS, which does not support named exports. CommonJS modules can be imported by importing the default export.
For example:
import pkg from './hook.js';
const { createHook } = pkg;
    at ModuleJob._instantiate (internal/modules/esm/module_job.js:98:21)
    at async ModuleJob.run (internal/modules/esm/module_job.js:137:5)
    at async Loader.import (internal/modules/esm/loader.js:165:24)
    at async internal/process/esm_loader.js:57:9
    at async Object.loadESM (internal/process/esm_loader.js:67:5)