apm-agent-nodejs
apm-agent-nodejs copied to clipboard
log correlation + webpack may not work
(I'm splitting out one of the listed issues on https://github.com/elastic/apm-agent-nodejs/issues/1967#issuecomment-919370647 to this new issue.)
Scenario:
- A node.js project using winston, and
@elastic/ecs-winston-formatfor ECS logging formatting. - It is using elastic-apm-node for tracing and should also log correlation with the ecs formatter.
- It is also using webpack bundling.
Is there a way to configure and use webpack so that (a) the APM agent works and (b) log correlation works? See coming docs from https://github.com/elastic/apm-agent-nodejs/pull/2837 about using the agent with webpack. Those docs should potentially be updated if there are changes required to get the above to work.
Using 'externals' in webpack.config.js like this:
...
externals: {
'elastic-apm-node': 'commonjs elastic-apm-node'
},
...
naively works to get instrumentation of core node modules only, e.g. the http module. It may work for adding other modules as well:
...
externals: {
'elastic-apm-node': 'commonjs elastic-apm-node',
'pg': 'commonjs pg'
},
...
However, it does not work for log correlation via:
...
externals: {
'elastic-apm-node': 'commonjs elastic-apm-node',
'@elastic/ecs-winston-format': 'commonjs @elastic/ecs-winston-format'
},
...
because I found that the built "dist/app.js" replaces the require('elastic-apm-node') in ecs-winston-format with the __webpack_require__, breaking the sniffing. Solutions:
-
Something about the more complete 'webpack-node-externals' module works (and for all packages). So this is probably our best current workaround answer. However it may defeat the user's use case for webpack, perhaps not.
// webpack.config.js const nodeExternals = require('webpack-node-externals') ... externals: [nodeExternals()], ... -
If we switch to the global var, this might just work. We should probably do that anyway, to handle the "weird, hard" case.
-
Perhaps, however, it would be better for log correlation here to be from the APM side. It shouldn't just be Elastic APM here. The circular dep issue might be different here then.
can we build a "native" solution for bundlers?
you could hook when the webpack is compiling a given package like pg and modify to have your instrumentation version
we can have a list of packages that needs to be external to make elastic apm instrumentation to work
can elastic-apm-node logs what modules/dependencies/packages are being instrumented?
can we build a "native" solution for bundlers?
@sibelius Hi. A native solution for bundlers will likely require a separate package/plugin/something for each bundler (e.g. one for webpack, one for esbuild, etc.), assuming the given bundler supports customization like that. I believe doing so is possible, yes, but it will take some investigation and prioritizing doing that. It is on my radar, but nothing is currently planned.
we can have a list of packages that needs to be external to make elastic apm instrumentation to work
The best such list in here: https://github.com/elastic/apm-agent-nodejs/blob/5c372b6c60d18ed797ad3f68c348dd93cdd6ebdc/lib/instrumentation/index.js#L37-L86
These are all the modules that the APM agent will possible instrument.
can elastic-apm-node
logswhat modules/dependencies/packages are being instrumented?
It often does log at "debug" level when it is instrumenting a particular part of a module, e.g.:
agent.logger.debug('shimming generic-pool.Pool')
agent.logger.debug('shimming koa-router prototype.match function')
agent.logger.debug('wrapping fastify build function')
However, it does not currently do so consistently.
I would like to see logs that packages that should be instrumented but were not instrumented
like
we tried to instrument mongodb but didn't work
but I think this won't be easy or even possible
we tried to instrument
mongodbbut didn't workbut I think this won't be easy or even possible
The issue in a bundler is that the hook the APM agent puts on require() doesn't get called at all, so the APM agent cannot know when mongodb is require()d. So, yes, in the current state of things, it isn't possible for the APM agent to warn at runtime.
here is an article https://dev.to/woovi/using-webpack-to-slim-your-docker-image-1b1n
of how we are using elastic apm with webpack (bundling), and enabling instrumentation
we move all required packages that need instrumentation outside bundling, as externals
and install them in the docker afterwards