Skip to content

Commit dfa4c57

Browse files
committed
feat(detector-aws): add attributes to aws lambda detector
1 parent f97bd70 commit dfa4c57

File tree

2 files changed

+71
-26
lines changed

2 files changed

+71
-26
lines changed

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

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,43 +22,62 @@ import {
2222
ResourceDetectionConfig,
2323
} from '@opentelemetry/resources';
2424
import {
25+
// AWS attributes
26+
ATTR_AWS_LOG_GROUP_NAMES,
27+
// Cloud attributes
2528
ATTR_CLOUD_PROVIDER,
2629
ATTR_CLOUD_PLATFORM,
2730
ATTR_CLOUD_REGION,
28-
ATTR_FAAS_VERSION,
29-
ATTR_FAAS_NAME,
31+
// Cloud values (AWS)
3032
CLOUD_PROVIDER_VALUE_AWS,
3133
CLOUD_PLATFORM_VALUE_AWS_LAMBDA,
34+
// FaaS attributes
35+
ATTR_FAAS_NAME,
36+
ATTR_FAAS_VERSION,
37+
ATTR_FAAS_INSTANCE,
38+
ATTR_FAAS_MAX_MEMORY,
3239
} from '@opentelemetry/semantic-conventions/incubating';
3340

3441
/**
3542
* The AwsLambdaDetector can be used to detect if a process is running in AWS Lambda
3643
* and return a {@link Resource} populated with data about the environment.
3744
* Returns an empty Resource if detection fails.
45+
*
46+
* AWS Lambda documentation for available environment variables within the Lambda runtimes.
47+
* @see https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime
3848
*/
3949
export class AwsLambdaDetectorSync implements DetectorSync {
4050
detect(_config?: ResourceDetectionConfig): IResource {
41-
const functionName = process.env.AWS_LAMBDA_FUNCTION_NAME;
42-
if (!functionName) {
51+
// Check if running inside AWS Lambda environment, return early if not
52+
const executionEnv = process.env.AWS_EXECUTION_ENV;
53+
if (!executionEnv?.startsWith('AWS_Lambda_')) {
4354
return Resource.empty();
4455
}
4556

46-
const functionVersion = process.env.AWS_LAMBDA_FUNCTION_VERSION;
47-
const region = process.env.AWS_REGION;
57+
// These environment variables are guaranteed to be present in AWS Lambda
58+
const region = process.env.AWS_REGION!;
59+
const functionName = process.env.AWS_LAMBDA_FUNCTION_NAME!;
60+
const functionVersion = process.env.AWS_LAMBDA_FUNCTION_VERSION!;
61+
const memorySize = process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE!;
4862

4963
const attributes: ResourceAttributes = {
50-
[ATTR_CLOUD_PROVIDER]: String(CLOUD_PROVIDER_VALUE_AWS),
51-
[ATTR_CLOUD_PLATFORM]: String(CLOUD_PLATFORM_VALUE_AWS_LAMBDA),
64+
[ATTR_CLOUD_PROVIDER]: CLOUD_PROVIDER_VALUE_AWS,
65+
[ATTR_CLOUD_PLATFORM]: CLOUD_PLATFORM_VALUE_AWS_LAMBDA,
66+
[ATTR_FAAS_NAME]: functionName,
67+
[ATTR_CLOUD_REGION]: region,
68+
[ATTR_FAAS_VERSION]: functionVersion,
69+
[ATTR_FAAS_MAX_MEMORY]: parseInt(memorySize) * 1024 * 1024,
5270
};
53-
if (region) {
54-
attributes[ATTR_CLOUD_REGION] = region;
55-
}
5671

57-
if (functionName) {
58-
attributes[ATTR_FAAS_NAME] = functionName;
72+
// These environment variables are not available in Lambda SnapStart
73+
const logGroupName = process.env.AWS_LAMBDA_LOG_GROUP_NAME;
74+
const logStreamName = process.env.AWS_LAMBDA_LOG_STREAM_NAME;
75+
76+
if (logStreamName) {
77+
attributes[ATTR_FAAS_INSTANCE] = logStreamName;
5978
}
60-
if (functionVersion) {
61-
attributes[ATTR_FAAS_VERSION] = functionVersion;
79+
if (logGroupName) {
80+
attributes[ATTR_AWS_LOG_GROUP_NAMES] = [logGroupName];
6281
}
6382

6483
return new Resource(attributes);

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

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,20 @@
1616

1717
import * as assert from 'assert';
1818
import {
19-
assertCloudResource,
2019
assertEmptyResource,
2120
} from '@opentelemetry/contrib-test-utils';
21+
import {
22+
ATTR_CLOUD_PROVIDER,
23+
ATTR_CLOUD_PLATFORM,
24+
ATTR_CLOUD_REGION,
25+
ATTR_FAAS_NAME,
26+
ATTR_FAAS_VERSION,
27+
ATTR_FAAS_INSTANCE,
28+
ATTR_FAAS_MAX_MEMORY,
29+
ATTR_AWS_LOG_GROUP_NAMES,
30+
CLOUD_PROVIDER_VALUE_AWS,
31+
CLOUD_PLATFORM_VALUE_AWS_LAMBDA,
32+
} from '@opentelemetry/semantic-conventions/incubating';
2233

2334
import { awsLambdaDetectorSync } from '../../src';
2435

@@ -35,25 +46,40 @@ describe('awsLambdaDetectorSync', () => {
3546

3647
describe('on lambda', () => {
3748
it('fills resource', async () => {
49+
process.env.AWS_EXECUTION_ENV = 'AWS_Lambda_nodejs22.x';
50+
process.env.AWS_REGION = 'us-east-1';
3851
process.env.AWS_LAMBDA_FUNCTION_NAME = 'name';
3952
process.env.AWS_LAMBDA_FUNCTION_VERSION = 'v1';
40-
process.env.AWS_REGION = 'us-east-1';
53+
process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE = '128';
54+
process.env.AWS_LAMBDA_LOG_GROUP_NAME = '/aws/lambda/name';
55+
process.env.AWS_LAMBDA_LOG_STREAM_NAME = '2024/03/14/[$LATEST]123456';
4156

4257
const resource = awsLambdaDetectorSync.detect();
4358

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');
59+
assert.strictEqual(resource.attributes[ATTR_CLOUD_PROVIDER], CLOUD_PROVIDER_VALUE_AWS);
60+
assert.strictEqual(resource.attributes[ATTR_CLOUD_PLATFORM], CLOUD_PLATFORM_VALUE_AWS_LAMBDA);
61+
assert.strictEqual(resource.attributes[ATTR_CLOUD_REGION], 'us-east-1');
62+
assert.strictEqual(resource.attributes[ATTR_FAAS_NAME], 'name');
63+
assert.strictEqual(resource.attributes[ATTR_FAAS_VERSION], 'v1');
64+
assert.strictEqual(resource.attributes[ATTR_FAAS_INSTANCE], '2024/03/14/[$LATEST]123456');
65+
assert.strictEqual(resource.attributes[ATTR_FAAS_MAX_MEMORY], 128 * 1024 * 1024);
66+
assert.deepStrictEqual(resource.attributes[ATTR_AWS_LOG_GROUP_NAMES], ['/aws/lambda/name']);
5167
});
5268
});
5369

5470
describe('not on lambda', () => {
55-
it('returns empty resource', async () => {
56-
process.env.AWS_LAMBDA_FUNCTION_VERSION = 'v1';
71+
it('returns empty resource if AWS_EXECUTION_ENV is not set', async () => {
72+
process.env.AWS_LAMBDA_FUNCTION_NAME = 'name';
73+
process.env.AWS_REGION = 'us-east-1';
74+
75+
const resource = awsLambdaDetectorSync.detect();
76+
77+
assertEmptyResource(resource);
78+
});
79+
80+
it('returns empty resource if AWS_EXECUTION_ENV is not Lambda', async () => {
81+
process.env.AWS_EXECUTION_ENV = 'AWS_EC2';
82+
process.env.AWS_LAMBDA_FUNCTION_NAME = 'name';
5783
process.env.AWS_REGION = 'us-east-1';
5884

5985
const resource = awsLambdaDetectorSync.detect();

0 commit comments

Comments
 (0)