elastic / apm-agent-nodejs

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

Control which framework/technology transactions are created from #3756

Open thorhj opened 11 months ago

thorhj commented 11 months ago

The problem I am hosting fastify APIs in AWS Lambda functions, using API Gateway as a proxy to route requests to the lambda. I am using fastify/aws-lambda-fastify to do this.

In a non-Lambda context, when I start the APM agent, it will hook in to the fastify context and create transactions based on routes that are hit. For instance, if a user navigate to

GET /users/3ffb7b9c-655e-4a87-b094-8eea9c725d0d/profile
GET /users/3ffb7b9c-655e-4a87-b094-8eea9c725d0d/roles
DELETE /users/3ffb7b9c-655e-4a87-b094-8eea9c725d0d

then the resulting transactions would be based on the registered route configuration to group related requests, so it would end up in APM something like this:

GET /users/:userId/profile
GET /users/:userId/roles
DELETE /users/:userId

The problem is when I use the Elastic APM agent on fastify APIs hosted in Lambda functions as described, the transaction is based on the API Gateway context. Given that I am proxying all traffic from API Gateway the examples above will show up as:

GET /users/{proxy+}
GET /users/{proxy+}
DELETE /users/{proxy+}

Of course this grouping is not desirable, as it only really separates routes by HTTP method and not by the URL.

Suggested solution I would like some setting to control which technology/framework to base transactions on. As far as I can tell I have no way to do this now. In my case I would want APM to use fastify instead of AWS Lambda/API Gateway. It could possibly look something like this:

// On the agent:
apm.usePreferredFramework("fastify") // "awslambda" | "fastify" | "nextjs" | "azurefunction" | ...

// Or as an environment variable:
ELASTIC_APM_USE_PREFERRED_FRAMEWORK=fastify

Alternatives I have looked into usePathAsTransactionName, but that setting eliminates all grouping so this is not desirable either. Having looked through the documentation I have not been able to find a suitable workaround.

trentm commented 11 months ago

@thorhj Thank you for the issue and the suggestion. I think you are correct that the agent currently doesn't support this, so we'd need to add support for it. We'll discuss this internally soon.

One thing that would very much help when we come around to implementing this would be a small repro case. Looking at https://github.com/fastify/aws-lambda-fastify#example it should be very straightforward for me to whip up an example for testing. However, in case you have a small example lambda handler file (and app.js if separate) that you could post here, that would be great.

thorhj commented 11 months ago

Thanks @trentm. I think I can manage to create a repository with a fastify API within a few days 👍

thorhj commented 11 months ago

Hi @trentm.

I have created a repository to illustrate this issue: thorhj/fastify-lambda-apm-test.

The built lambda function code can be found in lambda/index.js. This can be used directly. I have made a step-by-step guide in README.md for how I set up the Lambda function and API Gateway proxy through AWS Console.

The API has two endpoints:

Let me know if anything is unclear.