Skip to content

Commit bef920a

Browse files
authored
feat(detector-aws): add more lambda semconv attributes (#2589)
1 parent fd547c8 commit bef920a

File tree

4 files changed

+102
-29
lines changed

4 files changed

+102
-29
lines changed

detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsLambdaDetectorSync.ts

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@ import {
2222
ResourceDetectionConfig,
2323
} from '@opentelemetry/resources';
2424
import {
25-
ATTR_CLOUD_PROVIDER,
25+
ATTR_AWS_LOG_GROUP_NAMES,
2626
ATTR_CLOUD_PLATFORM,
27+
ATTR_CLOUD_PROVIDER,
2728
ATTR_CLOUD_REGION,
28-
ATTR_FAAS_VERSION,
29+
ATTR_FAAS_INSTANCE,
2930
ATTR_FAAS_NAME,
31+
ATTR_FAAS_MAX_MEMORY,
32+
ATTR_FAAS_VERSION,
3033
CLOUD_PROVIDER_VALUE_AWS,
3134
CLOUD_PLATFORM_VALUE_AWS_LAMBDA,
3235
} from '../semconv';
@@ -38,27 +41,37 @@ import {
3841
*/
3942
export class AwsLambdaDetectorSync implements DetectorSync {
4043
detect(_config?: ResourceDetectionConfig): IResource {
41-
const functionName = process.env.AWS_LAMBDA_FUNCTION_NAME;
42-
if (!functionName) {
44+
// Check if running inside AWS Lambda environment
45+
const executionEnv = process.env.AWS_EXECUTION_ENV;
46+
if (!executionEnv?.startsWith('AWS_Lambda_')) {
4347
return Resource.empty();
4448
}
4549

46-
const functionVersion = process.env.AWS_LAMBDA_FUNCTION_VERSION;
50+
// These environment variables are guaranteed to be present in Lambda environment
51+
// https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime
4752
const region = process.env.AWS_REGION;
53+
const functionName = process.env.AWS_LAMBDA_FUNCTION_NAME;
54+
const functionVersion = process.env.AWS_LAMBDA_FUNCTION_VERSION;
55+
const memorySize = process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE;
56+
57+
// These environment variables are not available in Lambda SnapStart functions
58+
const logGroupName = process.env.AWS_LAMBDA_LOG_GROUP_NAME;
59+
const logStreamName = process.env.AWS_LAMBDA_LOG_STREAM_NAME;
4860

4961
const attributes: ResourceAttributes = {
50-
[ATTR_CLOUD_PROVIDER]: String(CLOUD_PROVIDER_VALUE_AWS),
51-
[ATTR_CLOUD_PLATFORM]: String(CLOUD_PLATFORM_VALUE_AWS_LAMBDA),
62+
[ATTR_CLOUD_PROVIDER]: CLOUD_PROVIDER_VALUE_AWS,
63+
[ATTR_CLOUD_PLATFORM]: CLOUD_PLATFORM_VALUE_AWS_LAMBDA,
64+
[ATTR_CLOUD_REGION]: region,
65+
[ATTR_FAAS_NAME]: functionName,
66+
[ATTR_FAAS_VERSION]: functionVersion,
67+
[ATTR_FAAS_MAX_MEMORY]: parseInt(memorySize!) * 1024 * 1024,
5268
};
53-
if (region) {
54-
attributes[ATTR_CLOUD_REGION] = region;
55-
}
5669

57-
if (functionName) {
58-
attributes[ATTR_FAAS_NAME] = functionName;
70+
if (logGroupName) {
71+
attributes[ATTR_AWS_LOG_GROUP_NAMES] = [logGroupName];
5972
}
60-
if (functionVersion) {
61-
attributes[ATTR_FAAS_VERSION] = functionVersion;
73+
if (logStreamName) {
74+
attributes[ATTR_FAAS_INSTANCE] = logStreamName;
6275
}
6376

6477
return new Resource(attributes);

detectors/node/opentelemetry-resource-detector-aws/src/semconv.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,28 @@ export const ATTR_CONTAINER_NAME = 'container.name';
239239
*/
240240
export const ATTR_FAAS_NAME = 'faas.name';
241241

242+
/**
243+
* The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version.
244+
*
245+
* @example 2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de
246+
*
247+
* @note * **AWS Lambda:** Use the (full) log stream name.
248+
*
249+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
250+
*/
251+
export const ATTR_FAAS_INSTANCE = 'faas.instance';
252+
253+
/**
254+
* The amount of memory available to the serverless function converted to Bytes.
255+
*
256+
* @example 134217728
257+
*
258+
* @note It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information (which must be multiplied by 1,048,576).
259+
*
260+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
261+
*/
262+
export const ATTR_FAAS_MAX_MEMORY = 'faas.max_memory';
263+
242264
/**
243265
* The immutable version of the function being executed.
244266
*

detectors/node/opentelemetry-resource-detector-aws/test/detectors/AwsLambdaDetector.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ describe('awsLambdaDetector', () => {
3535

3636
describe('on lambda', () => {
3737
it('fills resource', async () => {
38+
process.env.AWS_EXECUTION_ENV = 'AWS_Lambda_nodejs22.x';
3839
process.env.AWS_LAMBDA_FUNCTION_NAME = 'name';
3940
process.env.AWS_LAMBDA_FUNCTION_VERSION = 'v1';
4041
process.env.AWS_REGION = 'us-east-1';

detectors/node/opentelemetry-resource-detector-aws/test/detectors/AwsLambdaDetectorSync.test.ts

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,20 @@
1515
*/
1616

1717
import * as assert from 'assert';
18-
import {
19-
assertCloudResource,
20-
assertEmptyResource,
21-
} from '@opentelemetry/contrib-test-utils';
22-
18+
import { assertEmptyResource } from '@opentelemetry/contrib-test-utils';
2319
import { awsLambdaDetectorSync } from '../../src';
20+
import {
21+
ATTR_AWS_LOG_GROUP_NAMES,
22+
ATTR_CLOUD_PLATFORM,
23+
ATTR_CLOUD_PROVIDER,
24+
ATTR_CLOUD_REGION,
25+
ATTR_FAAS_INSTANCE,
26+
ATTR_FAAS_NAME,
27+
ATTR_FAAS_MAX_MEMORY,
28+
ATTR_FAAS_VERSION,
29+
CLOUD_PROVIDER_VALUE_AWS,
30+
CLOUD_PLATFORM_VALUE_AWS_LAMBDA,
31+
} from '../../src/semconv';
2432

2533
describe('awsLambdaDetectorSync', () => {
2634
let oldEnv: NodeJS.ProcessEnv;
@@ -35,25 +43,54 @@ describe('awsLambdaDetectorSync', () => {
3543

3644
describe('on lambda', () => {
3745
it('fills resource', async () => {
46+
process.env.AWS_EXECUTION_ENV = 'AWS_Lambda_nodejs22.x';
47+
process.env.AWS_REGION = 'us-east-1';
3848
process.env.AWS_LAMBDA_FUNCTION_NAME = 'name';
3949
process.env.AWS_LAMBDA_FUNCTION_VERSION = 'v1';
40-
process.env.AWS_REGION = 'us-east-1';
50+
process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE = '128';
51+
process.env.AWS_LAMBDA_LOG_GROUP_NAME = '/aws/lambda/name';
52+
process.env.AWS_LAMBDA_LOG_STREAM_NAME = '2024/03/14/[$LATEST]123456';
4153

4254
const resource = awsLambdaDetectorSync.detect();
4355

44-
assertCloudResource(resource, {
45-
provider: 'aws',
46-
region: 'us-east-1',
47-
});
48-
49-
assert.strictEqual(resource.attributes['faas.name'], 'name');
50-
assert.strictEqual(resource.attributes['faas.version'], 'v1');
56+
assert.strictEqual(
57+
resource.attributes[ATTR_CLOUD_PROVIDER],
58+
CLOUD_PROVIDER_VALUE_AWS
59+
);
60+
assert.strictEqual(
61+
resource.attributes[ATTR_CLOUD_PLATFORM],
62+
CLOUD_PLATFORM_VALUE_AWS_LAMBDA
63+
);
64+
assert.strictEqual(resource.attributes[ATTR_CLOUD_REGION], 'us-east-1');
65+
assert.strictEqual(resource.attributes[ATTR_FAAS_NAME], 'name');
66+
assert.strictEqual(resource.attributes[ATTR_FAAS_VERSION], 'v1');
67+
assert.strictEqual(
68+
resource.attributes[ATTR_FAAS_INSTANCE],
69+
'2024/03/14/[$LATEST]123456'
70+
);
71+
assert.strictEqual(
72+
resource.attributes[ATTR_FAAS_MAX_MEMORY],
73+
128 * 1024 * 1024
74+
);
75+
assert.deepStrictEqual(resource.attributes[ATTR_AWS_LOG_GROUP_NAMES], [
76+
'/aws/lambda/name',
77+
]);
5178
});
5279
});
5380

5481
describe('not on lambda', () => {
55-
it('returns empty resource', async () => {
56-
process.env.AWS_LAMBDA_FUNCTION_VERSION = 'v1';
82+
it('returns empty resource if AWS_EXECUTION_ENV is not set', async () => {
83+
process.env.AWS_LAMBDA_FUNCTION_NAME = 'name';
84+
process.env.AWS_REGION = 'us-east-1';
85+
86+
const resource = awsLambdaDetectorSync.detect();
87+
88+
assertEmptyResource(resource);
89+
});
90+
91+
it('returns empty resource if AWS_EXECUTION_ENV is not Lambda', async () => {
92+
process.env.AWS_EXECUTION_ENV = 'AWS_ECS_EC2';
93+
process.env.AWS_LAMBDA_FUNCTION_NAME = 'name';
5794
process.env.AWS_REGION = 'us-east-1';
5895

5996
const resource = awsLambdaDetectorSync.detect();

0 commit comments

Comments
 (0)