From 09b8555007c3c05ad046dd67925f3640a7b35fbe Mon Sep 17 00:00:00 2001 From: Yaniv Davidi Date: Mon, 24 Jan 2022 13:45:15 +0200 Subject: [PATCH] feat(aws-sdk): add http status code attribute to aws sdk span (#844) * feat(aws-sdk): add http status code attribute to aws sdk span * chore: pr comment to improve coding style --- .../src/aws-sdk.ts | 19 ++++++++++++++++ .../test/aws-sdk-v2.test.ts | 22 +++++++++++++++++++ .../test/aws-sdk-v3.test.ts | 11 ++++++++++ 3 files changed, 52 insertions(+) diff --git a/plugins/node/opentelemetry-instrumentation-aws-sdk/src/aws-sdk.ts b/plugins/node/opentelemetry-instrumentation-aws-sdk/src/aws-sdk.ts index 31d3ff87ef..5d9eddaf8a 100644 --- a/plugins/node/opentelemetry-instrumentation-aws-sdk/src/aws-sdk.ts +++ b/plugins/node/opentelemetry-instrumentation-aws-sdk/src/aws-sdk.ts @@ -57,6 +57,7 @@ import { removeSuffixFromStringIfExists, } from './utils'; import { RequestMetadata } from './services/ServiceExtension'; +import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; const V3_CLIENT_CONFIG_KEY = Symbol( 'opentelemetry.instrumentation.aws-sdk.client.config' @@ -328,6 +329,14 @@ export class AwsInstrumentation extends InstrumentationBase { } span.setAttribute(AttributeNames.AWS_REQUEST_ID, response.requestId); + + const httpStatusCode = response.httpResponse?.statusCode; + if (httpStatusCode) { + span.setAttribute( + SemanticAttributes.HTTP_STATUS_CODE, + httpStatusCode + ); + } span.end(); }); }); @@ -472,6 +481,16 @@ export class AwsInstrumentation extends InstrumentationBase { if (requestId) { span.setAttribute(AttributeNames.AWS_REQUEST_ID, requestId); } + + const httpStatusCode = + response.output?.$metadata?.httpStatusCode; + if (httpStatusCode) { + span.setAttribute( + SemanticAttributes.HTTP_STATUS_CODE, + httpStatusCode + ); + } + const extendedRequestId = response.output?.$metadata?.extendedRequestId; if (extendedRequestId) { diff --git a/plugins/node/opentelemetry-instrumentation-aws-sdk/test/aws-sdk-v2.test.ts b/plugins/node/opentelemetry-instrumentation-aws-sdk/test/aws-sdk-v2.test.ts index 7a0caa3e18..d8c2fd09be 100644 --- a/plugins/node/opentelemetry-instrumentation-aws-sdk/test/aws-sdk-v2.test.ts +++ b/plugins/node/opentelemetry-instrumentation-aws-sdk/test/aws-sdk-v2.test.ts @@ -32,16 +32,23 @@ import { SpanStatusCode, Span } from '@opentelemetry/api'; import { AttributeNames } from '../src/enums'; import { mockV2AwsSend } from './testing-utils'; import * as expect from 'expect'; +import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; describe('instrumentation-aws-sdk-v2', () => { const responseMockSuccess = { requestId: '0000000000000', error: null, + httpResponse: { + statusCode: 200, + }, }; const responseMockWithError = { requestId: '0000000000000', error: 'something went wrong', + httpResponse: { + statusCode: 400, + }, }; const getAwsSpans = (): ReadableSpan[] => { @@ -111,6 +118,9 @@ describe('instrumentation-aws-sdk-v2', () => { expect(spanCreateBucket.attributes[AttributeNames.AWS_REGION]).toBe( 'us-east-1' ); + expect( + spanCreateBucket.attributes[SemanticAttributes.HTTP_STATUS_CODE] + ).toBe(200); expect(spanCreateBucket.name).toBe('S3.CreateBucket'); @@ -136,6 +146,9 @@ describe('instrumentation-aws-sdk-v2', () => { 'us-east-1' ); expect(spanPutObject.name).toBe('S3.PutObject'); + expect( + spanPutObject.attributes[SemanticAttributes.HTTP_STATUS_CODE] + ).toBe(200); }); it('adds proper number of spans with correct attributes if both, promise and callback were used', async () => { @@ -184,6 +197,9 @@ describe('instrumentation-aws-sdk-v2', () => { expect(spanPutObjectCb.attributes[AttributeNames.AWS_REGION]).toBe( 'us-east-1' ); + expect( + spanPutObjectCb.attributes[SemanticAttributes.HTTP_STATUS_CODE] + ).toBe(200); }); it('adds proper number of spans with correct attributes if only promise was used', async () => { @@ -219,6 +235,9 @@ describe('instrumentation-aws-sdk-v2', () => { expect(spanPutObjectCb.attributes[AttributeNames.AWS_REGION]).toBe( 'us-east-1' ); + expect( + spanPutObjectCb.attributes[SemanticAttributes.HTTP_STATUS_CODE] + ).toBe(200); }); it('should create span if no callback is supplied', done => { @@ -259,6 +278,9 @@ describe('instrumentation-aws-sdk-v2', () => { expect(spanCreateBucket.attributes[AttributeNames.AWS_ERROR]).toBe( responseMockWithError.error ); + expect( + spanCreateBucket.attributes[SemanticAttributes.HTTP_STATUS_CODE] + ).toBe(400); }); }); }); diff --git a/plugins/node/opentelemetry-instrumentation-aws-sdk/test/aws-sdk-v3.test.ts b/plugins/node/opentelemetry-instrumentation-aws-sdk/test/aws-sdk-v3.test.ts index e49ee97268..84a14c6c78 100644 --- a/plugins/node/opentelemetry-instrumentation-aws-sdk/test/aws-sdk-v3.test.ts +++ b/plugins/node/opentelemetry-instrumentation-aws-sdk/test/aws-sdk-v3.test.ts @@ -78,6 +78,7 @@ describe('instrumentation-aws-sdk-v3', () => { expect(span.attributes[SemanticAttributes.RPC_SERVICE]).toEqual('S3'); expect(span.attributes[AttributeNames.AWS_REGION]).toEqual(region); expect(span.name).toEqual('S3.PutObject'); + expect(span.attributes[SemanticAttributes.HTTP_STATUS_CODE]).toEqual(200); }); it('callback interface', done => { @@ -104,6 +105,9 @@ describe('instrumentation-aws-sdk-v3', () => { expect(span.attributes[SemanticAttributes.RPC_SERVICE]).toEqual('S3'); expect(span.attributes[AttributeNames.AWS_REGION]).toEqual(region); expect(span.name).toEqual('S3.PutObject'); + expect(span.attributes[SemanticAttributes.HTTP_STATUS_CODE]).toEqual( + 200 + ); done(); }); }); @@ -131,6 +135,7 @@ describe('instrumentation-aws-sdk-v3', () => { expect(span.attributes[SemanticAttributes.RPC_SERVICE]).toEqual('S3'); expect(span.attributes[AttributeNames.AWS_REGION]).toEqual(region); expect(span.name).toEqual('S3.PutObject'); + expect(span.attributes[SemanticAttributes.HTTP_STATUS_CODE]).toEqual(200); }); it('aws error', async () => { @@ -315,6 +320,9 @@ describe('instrumentation-aws-sdk-v3', () => { expect(span.attributes[SemanticAttributes.MESSAGING_URL]).toEqual( params.QueueUrl ); + expect(span.attributes[SemanticAttributes.HTTP_STATUS_CODE]).toEqual( + 200 + ); }); it('sqs receive add messaging attributes and context', done => { @@ -353,6 +361,9 @@ describe('instrumentation-aws-sdk-v3', () => { expect(attributes[SemanticAttributes.MESSAGING_OPERATION]).toMatch( MessagingOperationValues.RECEIVE ); + expect(span.attributes[SemanticAttributes.HTTP_STATUS_CODE]).toEqual( + 200 + ); done(); }); });