Skip to content

Commit e3923f3

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

File tree

3 files changed

+85
-27
lines changed

3 files changed

+85
-27
lines changed

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

Lines changed: 33 additions & 14 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
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;
57+
// These environment variables are guaranteed to be present in AWS Lambda
4758
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;
62+
63+
// These environment variables are not available in Lambda SnapStart
64+
const logGroupName = process.env.AWS_LAMBDA_LOG_GROUP_NAME;
65+
const logStreamName = process.env.AWS_LAMBDA_LOG_STREAM_NAME;
4866

4967
const attributes: ResourceAttributes = {
50-
[ATTR_CLOUD_PROVIDER]: String(CLOUD_PROVIDER_VALUE_AWS),
51-
[ATTR_CLOUD_PLATFORM]: String(CLOUD_PLATFORM_VALUE_AWS_LAMBDA),
68+
[ATTR_CLOUD_PROVIDER]: CLOUD_PROVIDER_VALUE_AWS,
69+
[ATTR_CLOUD_PLATFORM]: CLOUD_PLATFORM_VALUE_AWS_LAMBDA,
70+
[ATTR_CLOUD_REGION]: region,
71+
[ATTR_FAAS_NAME]: functionName,
72+
[ATTR_FAAS_VERSION]: functionVersion,
73+
[ATTR_FAAS_MAX_MEMORY]: parseInt(memorySize!) * 1024 * 1024,
5274
};
53-
if (region) {
54-
attributes[ATTR_CLOUD_REGION] = region;
55-
}
5675

57-
if (functionName) {
58-
attributes[ATTR_FAAS_NAME] = functionName;
76+
if (logGroupName) {
77+
attributes[ATTR_AWS_LOG_GROUP_NAMES] = [logGroupName];
5978
}
60-
if (functionVersion) {
61-
attributes[ATTR_FAAS_VERSION] = functionVersion;
79+
if (logStreamName) {
80+
attributes[ATTR_FAAS_INSTANCE] = logStreamName;
6281
}
6382

6483
return new Resource(attributes);

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: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,19 @@
1515
*/
1616

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

2332
import { awsLambdaDetectorSync } from '../../src';
2433

@@ -35,25 +44,54 @@ describe('awsLambdaDetectorSync', () => {
3544

3645
describe('on lambda', () => {
3746
it('fills resource', async () => {
47+
process.env.AWS_EXECUTION_ENV = 'AWS_Lambda_nodejs22.x';
48+
process.env.AWS_REGION = 'us-east-1';
3849
process.env.AWS_LAMBDA_FUNCTION_NAME = 'name';
3950
process.env.AWS_LAMBDA_FUNCTION_VERSION = 'v1';
40-
process.env.AWS_REGION = 'us-east-1';
51+
process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE = '128';
52+
process.env.AWS_LAMBDA_LOG_GROUP_NAME = '/aws/lambda/name';
53+
process.env.AWS_LAMBDA_LOG_STREAM_NAME = '2024/03/14/[$LATEST]123456';
4154

4255
const resource = awsLambdaDetectorSync.detect();
4356

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');
57+
assert.strictEqual(
58+
resource.attributes[ATTR_CLOUD_PROVIDER],
59+
CLOUD_PROVIDER_VALUE_AWS
60+
);
61+
assert.strictEqual(
62+
resource.attributes[ATTR_CLOUD_PLATFORM],
63+
CLOUD_PLATFORM_VALUE_AWS_LAMBDA
64+
);
65+
assert.strictEqual(resource.attributes[ATTR_CLOUD_REGION], 'us-east-1');
66+
assert.strictEqual(resource.attributes[ATTR_FAAS_NAME], 'name');
67+
assert.strictEqual(resource.attributes[ATTR_FAAS_VERSION], 'v1');
68+
assert.strictEqual(
69+
resource.attributes[ATTR_FAAS_INSTANCE],
70+
'2024/03/14/[$LATEST]123456'
71+
);
72+
assert.strictEqual(
73+
resource.attributes[ATTR_FAAS_MAX_MEMORY],
74+
128 * 1024 * 1024
75+
);
76+
assert.deepStrictEqual(resource.attributes[ATTR_AWS_LOG_GROUP_NAMES], [
77+
'/aws/lambda/name',
78+
]);
5179
});
5280
});
5381

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

5997
const resource = awsLambdaDetectorSync.detect();

0 commit comments

Comments
 (0)