Skip to content

fix(tracer): skip tracing CONNECT requests #4148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/features/tracer.md
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ Tracer exposes a `getRootXrayTraceId()` method that allows you to retrieve the [

=== "index.ts"

```typescript hl_lines="9"
```typescript hl_lines="13"
--8<-- "examples/snippets/tracer/accessRootTraceId.ts"
```

Expand Down
6 changes: 5 additions & 1 deletion examples/snippets/tracer/accessRootTraceId.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { Logger } from '@aws-lambda-powertools/logger';
import { Tracer } from '@aws-lambda-powertools/tracer';

const tracer = new Tracer({ serviceName: 'serverlessAirline' });
const logger = new Logger({ serviceName: 'serverlessAirline' });

export const handler = async (): Promise<unknown> => {
try {
throw new Error('Something went wrong');
} catch (_error) {
} catch (error) {
logger.error('An error occurred', { error });

const rootTraceId = tracer.getRootXrayTraceId();

// Example of returning an error response
Expand Down
11 changes: 7 additions & 4 deletions packages/tracer/src/Tracer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ class Tracer extends Utility implements TracerInterface {
}

/**
* @deprecated Use {@link captureAWSv3Client | `captureAWSv3Client()`} instead.
*
* Patch all AWS SDK v2 clients and create traces when your application makes calls to AWS services.
*
* If you want to patch a specific client use {@link captureAWSClient} and if you are using AWS SDK v3 use {@link captureAWSv3Client} instead.
Expand All @@ -305,16 +307,17 @@ class Tracer extends Utility implements TracerInterface {
* }
* ```
*
* @deprecated Use {@link captureAWSv3Client} instead.
* @param aws - AWS SDK v2 import
*/
public captureAWS<T>(aws: T): T {
/* v8 ignore start */ public captureAWS<T>(aws: T): T {
if (!this.isTracingEnabled()) return aws;

return this.provider.captureAWS(aws);
}
} /* v8 ignore stop */

/**
* @deprecated Use {@link captureAWSv3Client | `captureAWSv3Client()`} instead.
*
* Patch a specific AWS SDK v2 client and create traces when your application makes calls to that AWS service.
*
* If you want to patch all clients use {@link captureAWS} and if you are using AWS SDK v3 use {@link captureAWSv3Client} instead.
Expand All @@ -333,7 +336,7 @@ class Tracer extends Utility implements TracerInterface {
* ...
* }
* ```
* @deprecated Use {@link captureAWSv3Client} instead.
*
* @param service - AWS SDK v2 client
*/
/* v8 ignore start */ public captureAWSClient<T>(service: T): T {
Expand Down
16 changes: 8 additions & 8 deletions packages/tracer/src/provider/ProviderService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@ import {
*/
class ProviderService implements ProviderServiceInterface {
/**
* @deprecated
* @deprecated Use {@link captureAWSv3Client} instead.
*/
public captureAWS<T>(awssdk: T): T {
/* v8 ignore start */ public captureAWS<T>(awssdk: T): T {
return captureAWS(awssdk);
}
} /* v8 ignore stop */

/**
* @deprecated
* @deprecated Use {@link captureAWSv3Client} instead.
*/
public captureAWSClient<T>(service: T): T {
/* v8 ignore start */ public captureAWSClient<T>(service: T): T {
return captureAWSClient(service);
}
} /* v8 ignore stop */

public captureAWSv3Client<T>(service: T): T {
addUserAgentMiddleware(service, 'tracer');
Expand Down Expand Up @@ -119,12 +119,12 @@ class ProviderService implements ProviderServiceInterface {
*/
const onRequestStart = (message: unknown): void => {
const { request } = message as DiagnosticsChannel.RequestCreateMessage;
const method = request.method;
if (method === 'CONNECT') return;

const parentSubsegment = this.getSegment();
const requestURL = getRequestURL(request);
if (parentSubsegment && requestURL) {
const method = request.method;

const subsegment = parentSubsegment.addNewSubsegment(
requestURL.hostname
);
Expand Down
46 changes: 18 additions & 28 deletions packages/tracer/tests/unit/ProviderService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,34 +47,6 @@ describe('Class: ProviderService', () => {
vi.clearAllMocks();
});

describe('Method: captureAWS', () => {
it('calls the correct underlying function with proper arguments', () => {
// Prepare
const provider: ProviderService = new ProviderService();

// Act
provider.captureAWS({});

// Assess
expect(mocks.captureAWS).toHaveBeenCalledTimes(1);
expect(mocks.captureAWS).toHaveBeenCalledWith({});
});
});

describe('Method: captureAWSClient', () => {
it('calls the correct underlying function with proper arguments', () => {
// Prepare
const provider: ProviderService = new ProviderService();

// Act
provider.captureAWSClient({});

// Assess
expect(mocks.captureAWSClient).toHaveBeenCalledTimes(1);
expect(mocks.captureAWSClient).toHaveBeenCalledWith({});
});
});

describe('Method: captureAWSv3Client', () => {
it('calls the correct underlying function with proper arguments', () => {
// Prepare
Expand Down Expand Up @@ -657,4 +629,22 @@ describe('Class: ProviderService', () => {
)
);
});

it('skips requests with CONNECT method', () => {
// Prepare
const provider: ProviderService = new ProviderService();
const segment = new Subsegment('## dummySegment');
vi.spyOn(provider, 'getSegment').mockImplementation(() => segment);
vi.spyOn(segment, 'addNewSubsegment');

// Act
provider.instrumentFetch();
mockFetch({
origin: 'https://aws.amazon.com',
method: 'CONNECT',
});

// Assess
expect(segment.addNewSubsegment).toHaveBeenCalledTimes(0);
});
});
37 changes: 2 additions & 35 deletions packages/tracer/tests/unit/Tracer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1456,41 +1456,8 @@ describe('Class: Tracer', () => {
new Error('dummy error')
);
});
});

describe('Method: captureAWS', () => {
it('does nothing when called while tracing is disabled', () => {
// Prepare
const tracer: Tracer = new Tracer({ enabled: false });
const captureAWSSpy = vi
.spyOn(tracer.provider, 'captureAWS')
.mockImplementation(() => null);

// Act
tracer.captureAWS({});

// Assess
expect(captureAWSSpy).toBeCalledTimes(0);
});

it('returns the decorated object that was passed to it', () => {
// Prepare
const tracer: Tracer = new Tracer();
const captureAWSSpy = vi
.spyOn(tracer.provider, 'captureAWS')
.mockImplementation(() => null);

// Act
tracer.captureAWS({});

// Assess
expect(captureAWSSpy).toBeCalledTimes(1);
expect(captureAWSSpy).toBeCalledWith({});
});
});

describe('Method: captureAWSv3Client', () => {
it('does nothing when tracing is disabled', () => {
it('skips tracing AWS SDK clients when tracing is disabled', () => {
// Prepare
const tracer: Tracer = new Tracer({ enabled: false });
const captureAWSv3ClientSpy = vi
Expand All @@ -1504,7 +1471,7 @@ describe('Class: Tracer', () => {
expect(captureAWSv3ClientSpy).toBeCalledTimes(0);
});

it('returns the decorated object that was passed to it', () => {
it('returns the instrumented AWS SDK client when called', () => {
// Prepare
const tracer: Tracer = new Tracer();
const captureAWSv3ClientSpy = vi
Expand Down