Skip to content
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

feat(aws-lambda)!: Remove explicit x-ray context in favor of global propagator #2369

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 29 additions & 2 deletions plugins/node/opentelemetry-instrumentation-aws-lambda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ In your Lambda function configuration, add or update the `NODE_OPTIONS` environm
| --- | --- | --- |
| `requestHook` | `RequestHook` (function) | Hook for adding custom attributes before lambda starts handling the request. Receives params: `span, { event, context }` |
| `responseHook` | `ResponseHook` (function) | Hook for adding custom attributes before lambda returns the response. Receives params: `span, { err?, res? }` |
| `disableAwsContextPropagation` | `boolean` | By default, this instrumentation will try to read the context from the `_X_AMZN_TRACE_ID` environment variable set by Lambda, set this to `true` or set the environment variable `OTEL_LAMBDA_DISABLE_AWS_CONTEXT_PROPAGATION=true` to disable this behavior |
blumamir marked this conversation as resolved.
Show resolved Hide resolved
| `eventContextExtractor` | `EventContextExtractor` (function) | Function for providing custom context extractor in order to support different event types that are handled by AWS Lambda (e.g., SQS, CloudWatch, Kinesis, API Gateway). Applied only when `disableAwsContextPropagation` is set to `true`. Receives params: `event, context` |
| `eventContextExtractor` | `EventContextExtractor` (function) | Function for providing custom context extractor in order to support different event types that are handled by AWS Lambda (e.g., SQS, CloudWatch, Kinesis, API Gateway). |
| `lambdaHandler` | `string` | By default, this instrumentation automatically determines the Lambda handler function to instrument. This option is used to override that behavior by explicitly specifying the Lambda handler to instrument. See [Specifying the Lambda Handler](#specifying-the-lambda-handler) for additional information. |

### Hooks Usage Example
Expand Down Expand Up @@ -86,6 +85,34 @@ The `lambdaHandler` should be specified as a string in the format `<file>.<handl

One way to determine if the `lambdaHandler` option should be used is to check the handler defined on your Lambda. This can be done by determining the value of the `_HANDLER` environment variable or by viewing the **Runtime Settings** of your Lambda in AWS Console. If the handler is what you expect, then the instrumentation should work without the `lambdaHandler` option. If the handler points to something else, then the `lambdaHandler` option should be used to explicitly specify the handler that should be instrumented.

### Active Tracing Context Propagation
blumamir marked this conversation as resolved.
Show resolved Hide resolved

AWS Active Tracing can provide a parent context for the span generated by this instrumentation. In order to use this context, please use the [xray-lambda](https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/propagator-aws-xray-lambda) propagator.
blumamir marked this conversation as resolved.
Show resolved Hide resolved

Example usage:

```js
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { AWSXRayLambdaPropagator } = require('@opentelemetry/propagator-aws-xray-lambda');

const provider = new NodeTracerProvider();
provider.register({
propagator: new AWSXRayLambdaPropagator()
blumamir marked this conversation as resolved.
Show resolved Hide resolved
});
```

Alternatively, you can use the [auto-configuration-propagators](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/metapackages/auto-configuration-propagators/README.md) package, which makes it possible to configure propagators via the `OTEL_PROPAGATORS` environment variable. In order to use the `AWSXRayLambdaPropagator`, set the env variable value to `xray-lambda`.
blumamir marked this conversation as resolved.
Show resolved Hide resolved
blumamir marked this conversation as resolved.
Show resolved Hide resolved
blumamir marked this conversation as resolved.
Show resolved Hide resolved

```js
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { getPropagator } = require('@opentelemetry/auto-configuration-propagators');

const provider = new NodeTracerProvider();
provider.register({
propagator: getPropagator()
});
```

## Semantic Conventions

This package uses `@opentelemetry/semantic-conventions` version `1.22+`, which implements Semantic Convention [Version 1.7.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/semantic_conventions/README.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
"devDependencies": {
"@opentelemetry/api": "^1.3.0",
"@opentelemetry/core": "^1.8.0",
"@opentelemetry/propagator-aws-xray": "^1.25.1",
"@opentelemetry/propagator-aws-xray-lambda": "^0.52.1",
"@opentelemetry/sdk-metrics": "^1.8.0",
"@opentelemetry/sdk-trace-base": "^1.8.0",
"@opentelemetry/sdk-trace-node": "^1.8.0",
Expand All @@ -58,7 +60,6 @@
},
"dependencies": {
"@opentelemetry/instrumentation": "^0.52.0",
"@opentelemetry/propagator-aws-xray": "^1.3.1",
"@opentelemetry/resources": "^1.8.0",
"@opentelemetry/semantic-conventions": "^1.22.0",
"@types/aws-lambda": "8.10.122"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,9 @@ import {
SpanKind,
SpanStatusCode,
TextMapGetter,
TraceFlags,
TracerProvider,
ROOT_CONTEXT,
} from '@opentelemetry/api';
import {
AWSXRAY_TRACE_ID_HEADER,
AWSXRayPropagator,
} from '@opentelemetry/propagator-aws-xray';
blumamir marked this conversation as resolved.
Show resolved Hide resolved
import {
SEMATTRS_FAAS_EXECUTION,
SEMRESATTRS_CLOUD_ACCOUNT_ID,
Expand All @@ -58,10 +53,8 @@ import {

import { AwsLambdaInstrumentationConfig, EventContextExtractor } from './types';
import { PACKAGE_NAME, PACKAGE_VERSION } from './version';
import { env } from 'process';
import { LambdaModule } from './internal-types';

const awsPropagator = new AWSXRayPropagator();
const headerGetter: TextMapGetter<APIGatewayProxyEventHeaders> = {
keys(carrier): string[] {
return Object.keys(carrier);
Expand All @@ -78,18 +71,6 @@ export class AwsLambdaInstrumentation extends InstrumentationBase<AwsLambdaInstr
private _metricForceFlusher?: () => Promise<void>;

constructor(config: AwsLambdaInstrumentationConfig = {}) {
if (config.disableAwsContextPropagation == null) {
if (
typeof env['OTEL_LAMBDA_DISABLE_AWS_CONTEXT_PROPAGATION'] ===
'string' &&
env[
'OTEL_LAMBDA_DISABLE_AWS_CONTEXT_PROPAGATION'
].toLocaleLowerCase() === 'true'
) {
config = { ...config, disableAwsContextPropagation: true };
}
}

super(PACKAGE_NAME, PACKAGE_VERSION, config);
}

Expand Down Expand Up @@ -186,7 +167,6 @@ export class AwsLambdaInstrumentation extends InstrumentationBase<AwsLambdaInstr
const parent = AwsLambdaInstrumentation._determineParent(
event,
context,
config.disableAwsContextPropagation === true,
config.eventContextExtractor ||
AwsLambdaInstrumentation._defaultEventContextExtractor
);
Expand Down Expand Up @@ -388,32 +368,8 @@ export class AwsLambdaInstrumentation extends InstrumentationBase<AwsLambdaInstr
private static _determineParent(
event: any,
context: Context,
disableAwsContextPropagation: boolean,
eventContextExtractor: EventContextExtractor
): OtelContext {
let parent: OtelContext | undefined = undefined;
if (!disableAwsContextPropagation) {
const lambdaTraceHeader = process.env[traceContextEnvironmentKey];
blumamir marked this conversation as resolved.
Show resolved Hide resolved
if (lambdaTraceHeader) {
parent = awsPropagator.extract(
otelContext.active(),
{ [AWSXRAY_TRACE_ID_HEADER]: lambdaTraceHeader },
headerGetter
);
}
if (parent) {
const spanContext = trace.getSpan(parent)?.spanContext();
if (
spanContext &&
(spanContext.traceFlags & TraceFlags.SAMPLED) === TraceFlags.SAMPLED
) {
// Trace header provided by Lambda only sampled if a sampled context was propagated from
// an upstream cloud service such as S3, or the user is using X-Ray. In these cases, we
// need to use it as the parent.
return parent;
}
}
}
const extractedContext = safeExecuteInTheMiddle(
() => eventContextExtractor(event, context),
e => {
Expand All @@ -428,10 +384,6 @@ export class AwsLambdaInstrumentation extends InstrumentationBase<AwsLambdaInstr
if (trace.getSpan(extractedContext)?.spanContext()) {
return extractedContext;
}
if (!parent) {
// No context in Lambda environment or HTTP headers.
return ROOT_CONTEXT;
}
return parent;
return ROOT_CONTEXT;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export type EventContextExtractor = (
export interface AwsLambdaInstrumentationConfig extends InstrumentationConfig {
requestHook?: RequestHook;
responseHook?: ResponseHook;
disableAwsContextPropagation?: boolean;
eventContextExtractor?: EventContextExtractor;
lambdaHandler?: string;
}
Loading