Skip to content

Commit 35ac722

Browse files
authored
chore(instrumentation-aws-lambda): update semconv usage to ATTR_ exports (#3049)
Refs: #2377
1 parent 0092d99 commit 35ac722

File tree

4 files changed

+111
-36
lines changed

4 files changed

+111
-36
lines changed

packages/instrumentation-aws-lambda/src/instrumentation.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,9 @@ import {
3939
ROOT_CONTEXT,
4040
Attributes,
4141
} from '@opentelemetry/api';
42-
import {
43-
ATTR_URL_FULL,
44-
SEMATTRS_FAAS_EXECUTION,
45-
SEMRESATTRS_CLOUD_ACCOUNT_ID,
46-
SEMRESATTRS_FAAS_ID,
47-
} from '@opentelemetry/semantic-conventions';
48-
import { ATTR_FAAS_COLDSTART } from './semconv';
42+
import { ATTR_URL_FULL } from '@opentelemetry/semantic-conventions';
43+
import { ATTR_CLOUD_ACCOUNT_ID, ATTR_FAAS_COLDSTART } from './semconv';
44+
import { ATTR_FAAS_EXECUTION, ATTR_FAAS_ID } from './semconv-obsolete';
4945

5046
import {
5147
APIGatewayProxyEventHeaders,
@@ -239,12 +235,11 @@ export class AwsLambdaInstrumentation extends InstrumentationBase<AwsLambdaInstr
239235
{
240236
kind: SpanKind.SERVER,
241237
attributes: {
242-
[SEMATTRS_FAAS_EXECUTION]: context.awsRequestId,
243-
[SEMRESATTRS_FAAS_ID]: context.invokedFunctionArn,
244-
[SEMRESATTRS_CLOUD_ACCOUNT_ID]:
245-
AwsLambdaInstrumentation._extractAccountId(
246-
context.invokedFunctionArn
247-
),
238+
[ATTR_FAAS_EXECUTION]: context.awsRequestId,
239+
[ATTR_FAAS_ID]: context.invokedFunctionArn,
240+
[ATTR_CLOUD_ACCOUNT_ID]: AwsLambdaInstrumentation._extractAccountId(
241+
context.invokedFunctionArn
242+
),
248243
[ATTR_FAAS_COLDSTART]: requestIsColdStart,
249244
...AwsLambdaInstrumentation._extractOtherEventFields(event),
250245
},
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/*
18+
* This file contains constants for values that where replaced/removed from
19+
* Semantic Conventions long enough ago that they do not have `ATTR_*`
20+
* constants in the `@opentelemetry/semantic-conventions` package. Eventually
21+
* it is expected that this instrumention will be updated to emit telemetry
22+
* using modern Semantic Conventions, dropping the need for the constants in
23+
* this file.
24+
*/
25+
26+
/**
27+
* The execution ID of the current function execution.
28+
*
29+
* @deprecated Use ATTR_FAAS_INVOCATION_ID in [incubating entry-point]({@link https://github.com/open-telemetry/opentelemetry-js/blob/main/semantic-conventions/README.md#unstable-semconv}).
30+
*/
31+
export const ATTR_FAAS_EXECUTION = 'faas.execution' as const;
32+
33+
/**
34+
* The unique ID of the single function that this runtime instance executes.
35+
*
36+
* Note: Depending on the cloud provider, use:
37+
38+
* **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html).
39+
Take care not to use the &#34;invoked ARN&#34; directly but replace any
40+
[alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) with the resolved function version, as the same runtime instance may be invokable with multiple
41+
different aliases.
42+
* **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names)
43+
* **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id).
44+
45+
On some providers, it may not be possible to determine the full ID at startup,
46+
which is why this field cannot be made required. For example, on AWS the account ID
47+
part of the ARN is not available without calling another AWS API
48+
which may be deemed too slow for a short-running lambda function.
49+
As an alternative, consider setting `faas.id` as a span attribute instead.
50+
*
51+
* @deprecated Use ATTR_CLOUD_RESOURCE_ID in [incubating entry-point]({@link https://github.com/open-telemetry/opentelemetry-js/blob/main/semantic-conventions/README.md#unstable-semconv}).
52+
*/
53+
export const ATTR_FAAS_ID = 'faas.id' as const;

packages/instrumentation-aws-lambda/src/semconv.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,46 @@
2020
* @see https://github.com/open-telemetry/opentelemetry-js/tree/main/semantic-conventions#unstable-semconv
2121
*/
2222

23+
/**
24+
* The cloud account ID the resource is assigned to.
25+
*
26+
* @example 111111111111
27+
* @example opentelemetry
28+
*
29+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
30+
*/
31+
export const ATTR_CLOUD_ACCOUNT_ID = 'cloud.account.id' as const;
32+
2333
/**
2434
* A boolean that is true if the serverless function is executed for the first time (aka cold-start).
2535
*
2636
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
2737
*/
28-
export const ATTR_FAAS_COLDSTART = 'faas.coldstart';
38+
export const ATTR_FAAS_COLDSTART = 'faas.coldstart' as const;
39+
40+
/**
41+
* The name of the single function that this runtime instance executes.
42+
*
43+
* @example my-function
44+
* @example myazurefunctionapp/some-function-name
45+
*
46+
* @note This is the name of the function as configured/deployed on the FaaS
47+
* platform and is usually different from the name of the callback
48+
* function (which may be stored in the
49+
* [`code.namespace`/`code.function.name`](/docs/general/attributes.md#source-code-attributes)
50+
* span attributes).
51+
*
52+
* For some cloud providers, the above definition is ambiguous. The following
53+
* definition of function name **MUST** be used for this attribute
54+
* (and consequently the span name) for the listed cloud providers/products:
55+
*
56+
* - **Azure:** The full name `<FUNCAPP>/<FUNC>`, i.e., function app name
57+
* followed by a forward slash followed by the function name (this form
58+
* can also be seen in the resource JSON for the function).
59+
* This means that a span attribute **MUST** be used, as an Azure function
60+
* app can host multiple functions that would usually share
61+
* a TracerProvider (see also the `cloud.resource_id` attribute).
62+
*
63+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
64+
*/
65+
export const ATTR_FAAS_NAME = 'faas.name' as const;

packages/instrumentation-aws-lambda/test/integrations/lambda-handler.test.ts

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,10 @@ import { Context } from 'aws-lambda';
3434
import * as assert from 'assert';
3535
import {
3636
ATTR_URL_FULL,
37-
SEMATTRS_EXCEPTION_MESSAGE,
38-
SEMATTRS_FAAS_COLDSTART,
39-
SEMATTRS_FAAS_EXECUTION,
40-
SEMRESATTRS_FAAS_NAME,
37+
ATTR_EXCEPTION_MESSAGE,
4138
} from '@opentelemetry/semantic-conventions';
39+
import { ATTR_FAAS_COLDSTART, ATTR_FAAS_NAME } from '../../src/semconv';
40+
import { ATTR_FAAS_EXECUTION } from '../../src/semconv-obsolete';
4241
import {
4342
Context as OtelContext,
4443
context,
@@ -60,10 +59,7 @@ const memoryExporter = new InMemorySpanExporter();
6059
const assertSpanSuccess = (span: ReadableSpan) => {
6160
assert.strictEqual(span.kind, SpanKind.SERVER);
6261
assert.strictEqual(span.name, 'my_function');
63-
assert.strictEqual(
64-
span.attributes[SEMATTRS_FAAS_EXECUTION],
65-
'aws_request_id'
66-
);
62+
assert.strictEqual(span.attributes[ATTR_FAAS_EXECUTION], 'aws_request_id');
6763
assert.strictEqual(span.attributes['faas.id'], 'my_arn');
6864
assert.strictEqual(span.status.code, SpanStatusCode.UNSET);
6965
assert.strictEqual(span.status.message, undefined);
@@ -72,16 +68,13 @@ const assertSpanSuccess = (span: ReadableSpan) => {
7268
const assertSpanFailure = (span: ReadableSpan) => {
7369
assert.strictEqual(span.kind, SpanKind.SERVER);
7470
assert.strictEqual(span.name, 'my_function');
75-
assert.strictEqual(
76-
span.attributes[SEMATTRS_FAAS_EXECUTION],
77-
'aws_request_id'
78-
);
71+
assert.strictEqual(span.attributes[ATTR_FAAS_EXECUTION], 'aws_request_id');
7972
assert.strictEqual(span.attributes['faas.id'], 'my_arn');
8073
assert.strictEqual(span.status.code, SpanStatusCode.ERROR);
8174
assert.strictEqual(span.status.message, 'handler error');
8275
assert.strictEqual(span.events.length, 1);
8376
assert.strictEqual(
84-
span.events[0].attributes![SEMATTRS_EXCEPTION_MESSAGE],
77+
span.events[0].attributes![ATTR_EXCEPTION_MESSAGE],
8578
'handler error'
8679
);
8780
};
@@ -299,12 +292,12 @@ describe('lambda handler', () => {
299292
assert.strictEqual(result1, 'ok');
300293
assertSpanSuccess(span1);
301294
assert.strictEqual(span1.parentSpanContext?.spanId, undefined);
302-
assert.strictEqual(span1.attributes[SEMATTRS_FAAS_COLDSTART], true);
295+
assert.strictEqual(span1.attributes[ATTR_FAAS_COLDSTART], true);
303296

304297
assert.strictEqual(result2, 'ok');
305298
assertSpanSuccess(span2);
306299
assert.strictEqual(span2.parentSpanContext?.spanId, undefined);
307-
assert.strictEqual(span2.attributes[SEMATTRS_FAAS_COLDSTART], false);
300+
assert.strictEqual(span2.attributes[ATTR_FAAS_COLDSTART], false);
308301
});
309302

310303
it('should record coldstart with provisioned concurrency', async () => {
@@ -331,7 +324,7 @@ describe('lambda handler', () => {
331324
assert.strictEqual(spans.length, 1);
332325
assertSpanSuccess(span);
333326
assert.strictEqual(span.parentSpanContext?.spanId, undefined);
334-
assert.strictEqual(span.attributes[SEMATTRS_FAAS_COLDSTART], false);
327+
assert.strictEqual(span.attributes[ATTR_FAAS_COLDSTART], false);
335328
});
336329

337330
it('should record coldstart with proactive initialization', async () => {
@@ -358,7 +351,7 @@ describe('lambda handler', () => {
358351
assert.strictEqual(spans.length, 1);
359352
assertSpanSuccess(span);
360353
assert.strictEqual(span.parentSpanContext?.spanId, undefined);
361-
assert.strictEqual(span.attributes[SEMATTRS_FAAS_COLDSTART], false);
354+
assert.strictEqual(span.attributes[ATTR_FAAS_COLDSTART], false);
362355
});
363356

364357
it('should record error', async () => {
@@ -638,18 +631,15 @@ describe('lambda handler', () => {
638631
it('sync - success', async () => {
639632
initializeHandler('lambda-test/async.handler', {
640633
requestHook: (span, { context }) => {
641-
span.setAttribute(SEMRESATTRS_FAAS_NAME, context.functionName);
634+
span.setAttribute(ATTR_FAAS_NAME, context.functionName);
642635
},
643636
});
644637

645638
await lambdaRequire('lambda-test/async').handler('arg', ctx);
646639
const spans = memoryExporter.getFinishedSpans();
647640
const [span] = spans;
648641
assert.strictEqual(spans.length, 1);
649-
assert.strictEqual(
650-
span.attributes[SEMRESATTRS_FAAS_NAME],
651-
ctx.functionName
652-
);
642+
assert.strictEqual(span.attributes[ATTR_FAAS_NAME], ctx.functionName);
653643
assertSpanSuccess(span);
654644
});
655645
});

0 commit comments

Comments
 (0)