Skip to content

Commit 8416e56

Browse files
committed
feat(instrumentation-aws-sdk): Add semconv attributes for AWS Step Functions
This PR adds the aws.step_functions.activity.arn and aws.step_functions.state_machine.arn semantic convention attributes for the following AWS resources: AWS Step Functions SDK The ARNs are extracted from request objects, and this behavior is covered by unit tests. Tests Run: npm run compile npm run lint npm run test All newly added tests pass, and no regressions were found. Backward Compatibility: This change is fully backward compatible. It introduces instrumentation for an additional AWS resource without modifying existing behavior in the auto-instrumentation library.
1 parent 8623268 commit 8416e56

File tree

5 files changed

+190
-0
lines changed

5 files changed

+190
-0
lines changed

packages/instrumentation-aws-sdk/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
"@aws-sdk/client-kinesis": "^3.85.0",
6060
"@aws-sdk/client-lambda": "^3.85.0",
6161
"@aws-sdk/client-s3": "^3.85.0",
62+
"@aws-sdk/client-sfn": "^3.85.0",
6263
"@aws-sdk/client-sns": "^3.85.0",
6364
"@aws-sdk/client-sqs": "^3.85.0",
6465
"@aws-sdk/types": "^3.370.0",

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,23 @@ export const GEN_AI_TOKEN_TYPE_VALUE_OUTPUT = 'output' as const;
168168
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
169169
*/
170170
export const ATTR_AWS_SNS_TOPIC_ARN = 'aws.sns.topic.arn' as const;
171+
172+
/**
173+
* The ARN of the AWS Step Functions Activity.
174+
* Originally from '@opentelemetry/semantic-conventions/incubating'
175+
* https://github.com/open-telemetry/semantic-conventions/blob/main/docs/registry/attributes/aws.md#amazon-step-functions-attributes
176+
* @example arn:aws:states:us-east-1:123456789012:activity:get-greeting
177+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
178+
*/
179+
export const ATTR_AWS_STEP_FUNCTIONS_ACTIVITY_ARN =
180+
'aws.step_functions.activity.arn' as const;
181+
182+
/**
183+
* The ARN of the AWS Step Functions State Machine.
184+
* Originally from '@opentelemetry/semantic-conventions/incubating'
185+
* https://github.com/open-telemetry/semantic-conventions/blob/main/docs/registry/attributes/aws.md#amazon-step-functions-attributes
186+
* @example arn:aws:states:us-east-1:123456789012:stateMachine:myStateMachine:1
187+
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
188+
*/
189+
export const ATTR_AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN =
190+
'aws.step_functions.state_machine.arn' as const;

packages/instrumentation-aws-sdk/src/services/ServicesExtensions.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
import { BedrockRuntimeServiceExtension } from './bedrock-runtime';
2525
import { DynamodbServiceExtension } from './dynamodb';
2626
import { SnsServiceExtension } from './sns';
27+
import { StepFunctionsServiceExtension } from './stepfunctions';
2728
import { LambdaServiceExtension } from './lambda';
2829
import { S3ServiceExtension } from './s3';
2930
import { KinesisServiceExtension } from './kinesis';
@@ -32,6 +33,11 @@ export class ServicesExtensions implements ServiceExtension {
3233
services: Map<string, ServiceExtension> = new Map();
3334

3435
constructor() {
36+
this.registerServices();
37+
}
38+
39+
private registerServices() {
40+
this.services.set('SFN', new StepFunctionsServiceExtension());
3541
this.services.set('SQS', new SqsServiceExtension());
3642
this.services.set('SNS', new SnsServiceExtension());
3743
this.services.set('DynamoDB', new DynamodbServiceExtension());
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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+
import { Attributes, SpanKind } from '@opentelemetry/api';
17+
import {
18+
ATTR_AWS_STEP_FUNCTIONS_ACTIVITY_ARN,
19+
ATTR_AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN,
20+
} from '../semconv';
21+
import { RequestMetadata, ServiceExtension } from './ServiceExtension';
22+
import { NormalizedRequest, AwsSdkInstrumentationConfig } from '../types';
23+
24+
export class StepFunctionsServiceExtension implements ServiceExtension {
25+
requestPreSpanHook(
26+
request: NormalizedRequest,
27+
_config: AwsSdkInstrumentationConfig
28+
): RequestMetadata {
29+
const stateMachineArn = request.commandInput?.stateMachineArn;
30+
const activityArn = request.commandInput?.activityArn;
31+
const spanKind: SpanKind = SpanKind.CLIENT;
32+
const spanAttributes: Attributes = {};
33+
34+
if (stateMachineArn) {
35+
spanAttributes[ATTR_AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN] =
36+
stateMachineArn;
37+
}
38+
39+
if (activityArn) {
40+
spanAttributes[ATTR_AWS_STEP_FUNCTIONS_ACTIVITY_ARN] = activityArn;
41+
}
42+
43+
return {
44+
isIncoming: false,
45+
spanAttributes,
46+
spanKind
47+
};
48+
}
49+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
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+
import { getTestSpans } from '@opentelemetry/contrib-test-utils';
18+
import { SpanKind } from '@opentelemetry/api';
19+
import { ReadableSpan } from '@opentelemetry/sdk-trace-base';
20+
import {
21+
ATTR_AWS_STEP_FUNCTIONS_ACTIVITY_ARN,
22+
ATTR_AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN,
23+
} from '@opentelemetry/semantic-conventions/incubating';
24+
25+
import { SFN } from '@aws-sdk/client-sfn';
26+
27+
import { expect } from 'expect';
28+
import * as nock from 'nock';
29+
30+
const region = 'us-east-1';
31+
32+
describe('SFN', () => {
33+
let sfn: SFN;
34+
beforeEach(() => {
35+
sfn = new SFN({
36+
region: region,
37+
credentials: {
38+
accessKeyId: 'abcde',
39+
secretAccessKey: 'abcde',
40+
},
41+
});
42+
});
43+
44+
describe('DescribeStateMachine', () => {
45+
it('span has stateMachineArn in its attributes', async () => {
46+
const stateMachineArn =
47+
'arn:aws:states:us-east-1:123456789123:stateMachine:testStateMachine';
48+
49+
nock(`https://states.${region}.amazonaws.com/`)
50+
.post('/')
51+
.reply(200, '{}');
52+
53+
await sfn
54+
.describeStateMachine({
55+
stateMachineArn: stateMachineArn,
56+
});
57+
58+
const testSpans: ReadableSpan[] = getTestSpans();
59+
const getStateMachineAttributeSpans: ReadableSpan[] = testSpans.filter(
60+
(s: ReadableSpan) => {
61+
return s.name === 'SFN.DescribeStateMachine';
62+
}
63+
);
64+
65+
expect(getStateMachineAttributeSpans.length).toBe(1);
66+
67+
const stateMachineAttributeSpan = getStateMachineAttributeSpans[0];
68+
expect(
69+
ATTR_AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN in
70+
stateMachineAttributeSpan.attributes
71+
).toBe(true);
72+
expect(
73+
stateMachineAttributeSpan.attributes[
74+
ATTR_AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN
75+
]
76+
).toBe(stateMachineArn);
77+
expect(stateMachineAttributeSpan.kind).toBe(SpanKind.CLIENT);
78+
});
79+
});
80+
81+
describe('DescribeActivity', () => {
82+
it('span has activityArn in its attributes', async () => {
83+
const activityArn =
84+
'arn:aws:states:us-east-1:123456789123:activity:testActivity';
85+
86+
nock(`https://states.${region}.amazonaws.com/`)
87+
.post('/')
88+
.reply(200, '{}');
89+
90+
await sfn
91+
.describeActivity({
92+
activityArn: activityArn,
93+
});
94+
95+
const testSpans: ReadableSpan[] = getTestSpans();
96+
const getActivityAttributeSpans: ReadableSpan[] = testSpans.filter(
97+
(s: ReadableSpan) => {
98+
return s.name === 'SFN.DescribeActivity';
99+
}
100+
);
101+
102+
expect(getActivityAttributeSpans.length).toBe(1);
103+
104+
const activityAttributeSpan = getActivityAttributeSpans[0];
105+
expect(
106+
ATTR_AWS_STEP_FUNCTIONS_ACTIVITY_ARN in activityAttributeSpan.attributes
107+
).toBe(true);
108+
expect(
109+
activityAttributeSpan.attributes[ATTR_AWS_STEP_FUNCTIONS_ACTIVITY_ARN]
110+
).toBe(activityArn);
111+
expect(activityAttributeSpan.kind).toBe(SpanKind.CLIENT);
112+
});
113+
});
114+
});

0 commit comments

Comments
 (0)