opentelemetry-lambda
opentelemetry-lambda copied to clipboard
Need guidance on how to customize NodeJS Lambda Layer
Two previous PRs (#36 and #215) added this capability to customize instrumentation, but there is no documentation on how to utilize this functionality, and I have not been able to successfully use this feature.
What have I tried:
- Added an environment variable
NODE_OPTIONS = --require globals
- Added a file in my AWS Lambda named
globals.js
"use strict";
console.log('Loading globals.js');
global.configureLambdaInstrumentation = function () {
console.log("Inside configureLambdaInstrumentation");
return {
requestHook: () => {
console.log('Inside requestHook');
}
};
};
console.log('Loaded globals.js');
What I am expecting:
It should log "Inside configureLambdaInstrumentation" immediately after "Registering OpenTelemetry"
Actual result (from CloudWatch)
| 2022-04-06T14:25:16.032-04:00 | Loading globals.js
| 2022-04-06T14:25:16.245-04:00 | Loaded globals.js
| 2022-04-06T14:25:16.447-04:00 | Registering OpenTelemetry
| 2022-04-06T14:25:16.447-04:00 | EXTENSION Name: collector State: Ready Events: [INVOKE,SHUTDOWN]
| 2022-04-06T14:25:16.449-04:00 | 2022/04/06 18:25:16 [collector] Received event: {
How can I add a global configureLambdaInstrumentation
function?
If you create a configureLambdaInstrumentation
function as below in a file and require
this in via NODE_OPTIONS
this will be loaded into the layer environment (the wrapper script passes NODE_OPTIONS
into the runtime, with its own options rolled in) - so e.g. if you create a file distributed with your lambda as below named customiseInstrumentation.js
and include --require ./customiseInstrumentation.js
in your NODE_OPTIONS
for your lambda function
import { AwsLambdaInstrumentationConfig } from '@opentelemetry/instrumentation-aws-lambda'
import {
context,
propagation
} from '@opentelemetry/api'
declare global {
function configureLambdaInstrumentation (config: AwsLambdaInstrumentationConfig): AwsLambdaInstrumentationConfig
}
global.configureLambdaInstrumentation = (config: AwsLambdaInstrumentationConfig): AwsLambdaInstrumentationConfig => {
return {
...config,
disableAwsContextPropagation: true
}
}
This looks broadly like what you are doing with the only major difference being that you're completely overwriting the config rather than amending it but I can't see that it really matters either way, so I suppose the only difference is that we're using a customised build of the layer at present, however that is only because we're waiting for a PR #225 to be merged and referenced, then released in a layer, however this isn't strictly functionality you're after, and from what I can see the PRs you referenced are in the public layer already.
Update: Actually I've just spotted that the ARN arn:aws:lambda:\<region>:901920570463:layer:aws-otel-nodejs-amd64-ver-1-0-1:1
in the AWS Distro for OpenTelemetry Lambda docs isn't the latest release of the layer (which is arn:aws:lambda:\<region>:901920570463:layer:aws-otel-nodejs-amd64-ver-1-0-1:2
as per https://github.com/aws-observability/aws-otel-lambda/commit/375fcad221d453329b3bf37d0f0f8197791cce80) - the prior version won't contain these PRs and that would absolutely explain the behaviour that you're seeing.
Hey @chrisrichardsevergreen thanks for the suggestion to use the new layer, it is working now with aws-otel-nodejs-amd64-ver-1-0-1:2
!
My config is like NODE_OPTIONS
=--require /var/task/instrumentation
and I have a file named instrumenation.js
Aside, it still would be really helpful to newbies like myself if there was a short doc that explains the need for NODE_OPTIONS
. I only guessed myself towards that because I had seen that flag used with other OpenTelemetry setups (outside this layer's usage).
Knowing that this was an option would have saved me a huge amount of time :+1: to including this in the main README