elastic / apm-agent-nodejs

https://www.elastic.co/guide/en/apm/agent/nodejs/current/index.html
BSD 2-Clause "Simplified" License
581 stars 224 forks source link

get working out of the box with AWS Lambda using esbuild: Agent singleton, esbuild format config, etc. #3244

Open trentm opened 1 year ago

trentm commented 1 year ago

This AWS guide pitches using esbuild, sam, and typescript for Lambdas: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-build-typescript.html

This discuss issue pointed out that attempting to import and use the APM agent in the Lambda handler code does not work.

  1. apm.isStarted() returns undefined, indicating that the in-code import is not getting the wanted shared Agent singleton from the APM agent started via NODE_OPTIONS. A fix for this might be (or at least partially) using globalThis for the singleton sharing. The current use of require.cache doesn't work with bundled modules.
  2. Another workaround might be to specify that the elastic-apm-node module be in the esbuild externals -- as documented at https://www.elastic.co/guide/en/apm/agent/nodejs/current/starting-the-agent.html#start-esbuild. Can this config be passed through via the SAM configuration? If so, we should document this example.
  3. Another possible workaround might be to not have elastic-apm-node listed in dependencies, but still import it via CommonJS require. That might result in getting the elastic-apm-node module provided by the Elastic Lambda layer. This may require configuring a linter and/or esbuild to ignore the attempt to import a module that is not listed in "dependencies".
  4. Another separate issue with general instrumentation of modules used in the bundle will likely be (a) if the module is bundled then our instrumentation won't be able to instrument them (this is also discussed at https://www.elastic.co/guide/en/apm/agent/nodejs/current/starting-the-agent.html#start-esbuild) and (b) even if marked external, the default output format of the esbuild may be using ESM which isn't currently supported by the APM agent. The solution to this is to use Format: cjs in the SAM config.

I don't know how prevalent this is, but it has come up at least once: https://discuss.elastic.co/t/how-to-send-error-message-to-elastic-apm-and-show-the-error-in-kibana-tab/329183/5 As well, the "esbuild-bundled APM agent not sharing the same singleton Agent instance" has also come up before.

trentm commented 1 year ago

The user on the discuss thread above mentioned that adding elastic-apm-node to the External config field (as mentioned at https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-build-typescript.html) resolves the issue for them.

AnYoung627 commented 3 months ago

Hi @trentm! my team is also trying to use this, but a lot of our systems currently build with esbuild, and it would be a lot simpler to run this if esbuild was supported out of the box. Was there any priority set on this?