Skip to content

Commit aa9710f

Browse files
authored
fix(detector-aws): suppress internal tracing for all detectors (#2433)
1 parent 80c2f1a commit aa9710f

File tree

5 files changed

+115
-6
lines changed

5 files changed

+115
-6
lines changed

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { diag } from '@opentelemetry/api';
17+
import { context, diag } from '@opentelemetry/api';
18+
import { suppressTracing } from '@opentelemetry/core';
19+
1820
import {
1921
DetectorSync,
2022
IResource,
@@ -63,7 +65,10 @@ export class AwsBeanstalkDetectorSync implements DetectorSync {
6365
}
6466

6567
detect(config?: ResourceDetectionConfig): IResource {
66-
return new Resource({}, this._getAttributes());
68+
const attributes = context.with(suppressTracing(context.active()), () =>
69+
this._getAttributes()
70+
);
71+
return new Resource({}, attributes);
6772
}
6873

6974
/**

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17+
import { context } from '@opentelemetry/api';
18+
import { suppressTracing } from '@opentelemetry/core';
1719
import {
1820
DetectorSync,
1921
IResource,
@@ -56,7 +58,10 @@ class AwsEc2DetectorSync implements DetectorSync {
5658
readonly MILLISECOND_TIME_OUT = 5000;
5759

5860
detect(_config?: ResourceDetectionConfig): IResource {
59-
return new Resource({}, this._getAttributes());
61+
const attributes = context.with(suppressTracing(context.active()), () =>
62+
this._getAttributes()
63+
);
64+
return new Resource({}, attributes);
6065
}
6166

6267
/**

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { diag } from '@opentelemetry/api';
17+
import { context, diag } from '@opentelemetry/api';
18+
import { suppressTracing } from '@opentelemetry/core';
1819
import {
1920
DetectorSync,
2021
IResource,
@@ -70,7 +71,10 @@ export class AwsEcsDetectorSync implements DetectorSync {
7071
private static readFileAsync = util.promisify(fs.readFile);
7172

7273
detect(): IResource {
73-
return new Resource({}, this._getAttributes());
74+
const attributes = context.with(suppressTracing(context.active()), () =>
75+
this._getAttributes()
76+
);
77+
return new Resource({}, attributes);
7478
}
7579

7680
private async _getAttributes(): Promise<ResourceAttributes> {

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17+
import { context } from '@opentelemetry/api';
18+
import { suppressTracing } from '@opentelemetry/core';
1719
import {
1820
DetectorSync,
1921
IResource,
@@ -62,7 +64,10 @@ export class AwsEksDetectorSync implements DetectorSync {
6264
private static fileAccessAsync = util.promisify(fs.access);
6365

6466
detect(_config?: ResourceDetectionConfig): IResource {
65-
return new Resource({}, this._getAttributes());
67+
const attributes = context.with(suppressTracing(context.active()), () =>
68+
this._getAttributes()
69+
);
70+
return new Resource({}, attributes);
6671
}
6772

6873
/**
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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 * as assert from 'assert';
18+
19+
import { FsInstrumentation } from '@opentelemetry/instrumentation-fs';
20+
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
21+
import {
22+
InMemorySpanExporter,
23+
SimpleSpanProcessor,
24+
} from '@opentelemetry/sdk-trace-base';
25+
import { NodeSDK } from '@opentelemetry/sdk-node';
26+
import { DetectorSync } from '@opentelemetry/resources';
27+
28+
describe('[Integration] Internal tracing', () => {
29+
it('should not start spans for any network or fs operation in any detector', async () => {
30+
// For ECS detector we setup a mock URL to fetch metadata
31+
process.env.ECS_CONTAINER_METADATA_URI_V4 =
32+
'http://169.254.169.254/metadata';
33+
34+
const memoryExporter = new InMemorySpanExporter();
35+
const sdk = new NodeSDK({
36+
instrumentations: [new FsInstrumentation(), new HttpInstrumentation()],
37+
spanProcessors: [new SimpleSpanProcessor(memoryExporter)],
38+
});
39+
sdk.start();
40+
41+
// NOTE: detectors implementing the `DetectorSync` interface and starting
42+
// HTTP requests within the `detect` method will produce Noop Spans since
43+
// the SDK resolves the trace provider after resource detectors are triggered.
44+
// Ref: https://github.com/open-telemetry/opentelemetry-js/blob/38f6689480d28dcbdafcb7b5ba4b14025328ffda/experimental/packages/opentelemetry-sdk-node/src/sdk.ts#L210-L240
45+
//
46+
// So having the detector in the config would result in no spans for Azure requests
47+
// being exported which is what we want. Although we may think we're safe of sending
48+
// internal tracing any change that delays these request will result in internal
49+
// tracing being exported. We do the detection outside the SDK constructor to have such
50+
// scenario.
51+
const {
52+
awsBeanstalkDetectorSync,
53+
awsEc2DetectorSync,
54+
awsEcsDetectorSync,
55+
awsEksDetectorSync,
56+
awsLambdaDetectorSync,
57+
} = require('../../build/src');
58+
59+
// NOTE: the require process makes use of the fs API so spans are being exported.
60+
// We reset the exporter to have a clean state for assertions
61+
await new Promise(r => setTimeout(r, 0));
62+
memoryExporter.reset();
63+
64+
const detectors = [
65+
awsBeanstalkDetectorSync,
66+
awsEc2DetectorSync,
67+
awsEcsDetectorSync,
68+
awsEksDetectorSync,
69+
awsLambdaDetectorSync,
70+
] as DetectorSync[];
71+
72+
for (const d of detectors) {
73+
const r = d.detect();
74+
await r.waitForAsyncAttributes?.();
75+
}
76+
77+
// Wait for the next loop to let the span close properly
78+
await new Promise(r => setTimeout(r, 0));
79+
const spans = memoryExporter.getFinishedSpans();
80+
81+
assert.equal(
82+
spans.length,
83+
0,
84+
'no spans exported from any AWS resource detector'
85+
);
86+
87+
await sdk.shutdown();
88+
delete process.env.ECS_CONTAINER_METADATA_URI_V4;
89+
}).timeout(10000);
90+
});

0 commit comments

Comments
 (0)