-
Notifications
You must be signed in to change notification settings - Fork 580
AWS Lambda Instrumentation causes lambda failures when using streaming response #2827
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
cc @jj22ee (component owner) |
@thpierce It might also help to ask in the |
Regarding Solution 1:We'll need a mechanism is disable the Lambda instrumentation. The current question is how to differentiate between regular Lambda handlers ( Seeing how Lambda provides different inputs into the Lambda function solely based on having Digging around I found that what makes it special is that it contains a special "Symbol" property:
In this example I tried, you can trick Lambda into "enable streaming" for this regular Lambda by adding this property: // handler will error out but still print out the logs to console
export const handler = async (event, context, callback, arg4) => {
console.log(event)
console.log(context) // This now becomes a "responseStream" instead of context
console.log(callback) // This becomes a "context" instead of callback function
console.log(arg4)
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
// Make Lambda treat this normal handler as an "awslambda.streamifyResponse" handler
handler[Symbol.for("aws.lambda.runtime.handler.streaming")] = "response" Conversely, you can trick Lambda into thinking that this "streaming enabled" Lambda is a normal handler by deleting that property: export const handler = awslambda.streamifyResponse(
async (event, responseStream, _context, d) => {
console.log(event)
console.log(responseStream) // This now becomes a "context" instead of responseStream
console.log(_context) // This now becomes a "callback function" instead of a context
console.log(d)
// console.log(process.env)
// console.log(handler)
// responseStream.write('test payload'); // Won't work after deleting the Symbol property
// responseStream.end();
}
)
// Make Lambda treat this "awslambda.streamifyResponse" handler as a normal handler
delete handler[Symbol.for("aws.lambda.runtime.handler.streaming")] That said, we can probably disable the Lambda instrumentation by not patching the Lambda handler here if the original handler contains this property, and just continue to use the original handler. Regarding Solution 2:Given what we know now, we could (probably) extend the current Lambda Instrumentation to better support patching There might be more to this though, there are other possible properties that may also need to be preserved from the original handler like |
Uh oh!
There was an error while loading. Please reload this page.
What version of OpenTelemetry are you using?
1.9.0 (api), 2.0.0 (core)
What version of Node are you using?
Node.js 22.x
What did you do?
nodejs
foldernpm install
&npm run build
AWS_LAMBDA_EXEC_WRAPPER /opt/otel-handler
TypeError: responseStream.write is not a function
What did you expect to see?
Expected instrumentation to work.
What did you see instead?
Instrumentation caused my lambda to fail.
Additional context
The problem appears to be
opentelemetry-instrumentation-aws-lambda
. The instrumentation basically looks for anyhandler
and replaces it with a patchedhandler
that has 3 args: event, context, and callback. However, with streaming response lambdas the handler isstreamifyReponse
which needs 4 args: event, context, responseStream, and callback. So,responseStream
is overwritten with callback and becomes unusable.Two solutions:
handler
is astreamifyReponse
- Callout, this means streaming response lambdas will not be supportedstreamifyResponse
, fully supporting both "normal" and streaming response lambdas.Let me know if I should cut a separate issue for 2, above.
The text was updated successfully, but these errors were encountered: