Skip to content

Commit d55f038

Browse files
authored
Merge branch 'open-telemetry:main' into feat/nestjs-core-support-nestjs11
2 parents 09f29c9 + 7a1e8b3 commit d55f038

File tree

17 files changed

+376
-47
lines changed

17 files changed

+376
-47
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ features for unmaintained components. At least one sponsor is needed to lift the
238238
adding the requested feature. Sponsors are expected to provide reviews for that feature and be responsive on the issue.
239239

240240
Components marked as unmaintained still receive semantic conventions updates and bugfixes where possible.
241-
[@open-telemetry/javascript-triagers](https://github.com/orgs/open-telemetry/teams/javascript-triagers) may add the
241+
[@open-telemetry/javascript-contrib-triagers](https://github.com/orgs/open-telemetry/teams/javascript-contrib-triagers) may add the
242242
`type:semconv-update` or `bug` label to mark them as exempt from being auto-closed within two weeks.
243243

244244
A component which is unmaintained may be deprecated if there is a problem that is not fixed in a timely manner.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@
2020
"test:ci:changed": "nx affected -t test --base=origin/main --head=HEAD",
2121
"test-all-versions": "nx run-many -t test-all-versions",
2222
"changelog": "lerna-changelog",
23-
"lint": "nx run-many -t lint && npm run lint:readme && npm run lint:markdown",
23+
"lint": "nx run-many -t lint && npm run lint:readme && npm run lint:markdown && npm run lint:semconv-deps",
2424
"lint:fix": "nx run-many -t lint:fix && npm run lint:markdown:fix",
2525
"lint:deps": "npx --yes [email protected] --dependencies --production --tags=-knipignore",
2626
"lint:examples": "eslint ./examples/**/*.js",
2727
"lint:examples:fix": "eslint ./examples/**/*.js --fix",
2828
"lint:markdown": "markdownlint-cli2 $(git ls-files '*.md')",
2929
"lint:markdown:fix": "markdownlint-cli2 --fix $(git ls-files '*.md')",
30-
"lint:readme": "nx run-many -t lint:readme"
30+
"lint:readme": "nx run-many -t lint:readme",
31+
"lint:semconv-deps": "./scripts/lint-semconv-deps.mjs"
3132
},
3233
"keywords": [
3334
"opentelemetry",

plugins/node/instrumentation-cucumber/test/cucumber.test.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,24 +84,23 @@ describe('CucumberInstrumentation', () => {
8484
providedConfiguration?: Partial<IConfiguration>
8585
) => {
8686
// clean-up require cache to re-register cucumber hooks for a new run
87-
['features/support/world', 'features/step_definitions/steps'].forEach(
88-
search => {
89-
const key = Object.keys(require.cache).find(key =>
90-
key.includes(search)
91-
);
92-
if (key == null) return;
93-
delete require.cache[key];
94-
}
95-
);
87+
[
88+
path.join('features', 'support', 'world'),
89+
path.join('features', 'step_definitions', 'steps'),
90+
].forEach(search => {
91+
const key = Object.keys(require.cache).find(key => key.includes(search));
92+
if (key == null) return;
93+
delete require.cache[key];
94+
});
9695
const featurePath = path.join(__dirname, 'current.feature');
9796
await fs.promises.writeFile(featurePath, feature, 'utf-8');
9897
const { runConfiguration } = await loadConfiguration({
9998
provided: {
10099
...providedConfiguration,
101100
paths: [featurePath],
102101
require: [
103-
path.join(__dirname, 'features/support/world.ts'),
104-
path.join(__dirname, 'features/step_definitions/steps.ts'),
102+
path.join(__dirname, 'features', 'support', 'world.ts'),
103+
path.join(__dirname, 'features', 'step_definitions', 'steps.ts'),
105104
],
106105
},
107106
});
@@ -170,7 +169,7 @@ describe('CucumberInstrumentation', () => {
170169
assert(parent, 'Expected a parent span');
171170

172171
assert.deepEqual(parent.attributes, {
173-
[SEMATTRS_CODE_FILEPATH]: 'test/current.feature',
172+
[SEMATTRS_CODE_FILEPATH]: path.join('test', 'current.feature'),
174173
[SEMATTRS_CODE_LINENO]: 7,
175174
[SEMATTRS_CODE_FUNCTION]: 'Button pushing',
176175
[SEMATTRS_CODE_NAMESPACE]: 'Basic',

plugins/node/opentelemetry-instrumentation-mongodb/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Mongodb instrumentation has few options available to choose from. You can set th
5454
| [`enhancedDatabaseReporting`](./src/types.ts#L32) | `string` | If true, additional information about query parameters and results will be attached (as `attributes`) to spans representing database operations |
5555
| `responseHook` | `MongoDBInstrumentationExecutionResponseHook` (function) | Function for adding custom attributes from db response |
5656
| `dbStatementSerializer` | `DbStatementSerializer` (function) | Custom serializer function for the db.statement tag |
57+
| `requireParentSpan` | `boolean` | Require a parent span in order to create mongodb spans, default when unset is `true` |
5758

5859
## Semantic Conventions
5960

plugins/node/opentelemetry-instrumentation-mongodb/package.json

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77
"repository": "open-telemetry/opentelemetry-js-contrib",
88
"scripts": {
99
"docker:start": "docker run -e MONGODB_DB=opentelemetry-tests -e MONGODB_PORT=27017 -e MONGODB_HOST=127.0.0.1 -p 27017:27017 --rm mongo",
10-
"test": "npm run test-v5-v6",
11-
"test-v3": "nyc mocha --require '@opentelemetry/contrib-test-utils' 'test/**/mongodb-v3.test.ts'",
12-
"test-v4": "nyc mocha --require '@opentelemetry/contrib-test-utils' 'test/mongodb-v4-v5-v6.metrics.test.ts' 'test/**/mongodb-v4.test.ts'",
13-
"test-v5-v6": "nyc mocha --require '@opentelemetry/contrib-test-utils' 'test/mongodb-v4-v5-v6.metrics.test.ts' 'test/**/mongodb-v5-v6.test.ts'",
10+
"test": "npm run test-v3 && npm run test-v4 && npm run test-v5-v6 && nyc merge .nyc_output ./coverage/coverage-final.json",
11+
"test-v3": "tav mongodb 3.7.4 npm run test-v3-run",
12+
"test-v4": "tav mongodb 4.17.0 npm run test-v4-run",
13+
"test-v5-v6": "npm run test-v5-v6-run",
14+
"test-v3-run": "nyc --no-clean mocha --require '@opentelemetry/contrib-test-utils' 'test/**/mongodb-v3.test.ts'",
15+
"test-v4-run": "nyc --no-clean mocha --require '@opentelemetry/contrib-test-utils' 'test/mongodb-v4-v5-v6.metrics.test.ts' 'test/**/mongodb-v4.test.ts'",
16+
"test-v5-v6-run": "nyc --no-clean mocha --require '@opentelemetry/contrib-test-utils' 'test/mongodb-v4-v5-v6.metrics.test.ts' 'test/**/mongodb-v5-v6.test.ts'",
1417
"test-all-versions": "tav",
15-
"tdd": "npm run test -- --watch-extensions ts --watch",
18+
"tdd": "npm run test-v5-v6-run -- --watch-extensions ts --watch",
1619
"clean": "rimraf build/*",
1720
"lint": "eslint . --ext .ts",
1821
"lint:fix": "eslint . --ext .ts --fix",

plugins/node/opentelemetry-instrumentation-mongodb/src/instrumentation.ts

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,21 @@ import { V4Connect, V4Session } from './internal-types';
5555
import { PACKAGE_NAME, PACKAGE_VERSION } from './version';
5656
import { UpDownCounter } from '@opentelemetry/api';
5757

58+
const DEFAULT_CONFIG: MongoDBInstrumentationConfig = {
59+
requireParentSpan: true,
60+
};
61+
5862
/** mongodb instrumentation plugin for OpenTelemetry */
5963
export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumentationConfig> {
6064
private _connectionsUsage!: UpDownCounter;
6165
private _poolName!: string;
6266

6367
constructor(config: MongoDBInstrumentationConfig = {}) {
64-
super(PACKAGE_NAME, PACKAGE_VERSION, config);
68+
super(PACKAGE_NAME, PACKAGE_VERSION, { ...DEFAULT_CONFIG, ...config });
69+
}
70+
71+
override setConfig(config: MongoDBInstrumentationConfig = {}) {
72+
super.setConfig({ ...DEFAULT_CONFIG, ...config });
6573
}
6674

6775
override _updateMetricInstruments() {
@@ -438,10 +446,13 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
438446
callback?: Function
439447
) {
440448
const currentSpan = trace.getSpan(context.active());
449+
const skipInstrumentation =
450+
instrumentation._checkSkipInstrumentation(currentSpan);
451+
441452
const resultHandler =
442453
typeof options === 'function' ? options : callback;
443454
if (
444-
!currentSpan ||
455+
skipInstrumentation ||
445456
typeof resultHandler !== 'function' ||
446457
typeof ops !== 'object'
447458
) {
@@ -451,6 +462,7 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
451462
return original.call(this, server, ns, ops, options, callback);
452463
}
453464
}
465+
454466
const span = instrumentation.tracer.startSpan(
455467
`mongodb.${operationName}`,
456468
{
@@ -490,10 +502,14 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
490502
callback?: Function
491503
) {
492504
const currentSpan = trace.getSpan(context.active());
505+
const skipInstrumentation =
506+
instrumentation._checkSkipInstrumentation(currentSpan);
507+
493508
const resultHandler =
494509
typeof options === 'function' ? options : callback;
510+
495511
if (
496-
!currentSpan ||
512+
skipInstrumentation ||
497513
typeof resultHandler !== 'function' ||
498514
typeof cmd !== 'object'
499515
) {
@@ -503,6 +519,7 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
503519
return original.call(this, server, ns, cmd, options, callback);
504520
}
505521
}
522+
506523
const commandType = MongoDBInstrumentation._getCommandType(cmd);
507524
const type =
508525
commandType === MongodbCommandType.UNKNOWN ? 'command' : commandType;
@@ -535,20 +552,17 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
535552
callback: any
536553
) {
537554
const currentSpan = trace.getSpan(context.active());
555+
const skipInstrumentation =
556+
instrumentation._checkSkipInstrumentation(currentSpan);
538557
const resultHandler = callback;
539558
const commandType = Object.keys(cmd)[0];
540559

541-
if (
542-
typeof resultHandler !== 'function' ||
543-
typeof cmd !== 'object' ||
544-
cmd.ismaster ||
545-
cmd.hello
546-
) {
560+
if (typeof cmd !== 'object' || cmd.ismaster || cmd.hello) {
547561
return original.call(this, ns, cmd, options, callback);
548562
}
549563

550564
let span = undefined;
551-
if (currentSpan) {
565+
if (!skipInstrumentation) {
552566
span = instrumentation.tracer.startSpan(`mongodb.${commandType}`, {
553567
kind: SpanKind.CLIENT,
554568
});
@@ -581,6 +595,9 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
581595
) {
582596
const [ns, cmd] = args;
583597
const currentSpan = trace.getSpan(context.active());
598+
const skipInstrumentation =
599+
instrumentation._checkSkipInstrumentation(currentSpan);
600+
584601
const commandType = Object.keys(cmd)[0];
585602
const resultHandler = () => undefined;
586603

@@ -589,7 +606,7 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
589606
}
590607

591608
let span = undefined;
592-
if (currentSpan) {
609+
if (!skipInstrumentation) {
593610
span = instrumentation.tracer.startSpan(`mongodb.${commandType}`, {
594611
kind: SpanKind.CLIENT,
595612
});
@@ -634,10 +651,13 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
634651
callback?: Function
635652
) {
636653
const currentSpan = trace.getSpan(context.active());
654+
const skipInstrumentation =
655+
instrumentation._checkSkipInstrumentation(currentSpan);
637656
const resultHandler =
638657
typeof options === 'function' ? options : callback;
658+
639659
if (
640-
!currentSpan ||
660+
skipInstrumentation ||
641661
typeof resultHandler !== 'function' ||
642662
typeof cmd !== 'object'
643663
) {
@@ -655,6 +675,7 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
655675
);
656676
}
657677
}
678+
658679
const span = instrumentation.tracer.startSpan('mongodb.find', {
659680
kind: SpanKind.CLIENT,
660681
});
@@ -699,9 +720,13 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
699720
callback?: Function
700721
) {
701722
const currentSpan = trace.getSpan(context.active());
723+
const skipInstrumentation =
724+
instrumentation._checkSkipInstrumentation(currentSpan);
725+
702726
const resultHandler =
703727
typeof options === 'function' ? options : callback;
704-
if (!currentSpan || typeof resultHandler !== 'function') {
728+
729+
if (skipInstrumentation || typeof resultHandler !== 'function') {
705730
if (typeof options === 'function') {
706731
return original.call(
707732
this,
@@ -723,6 +748,7 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
723748
);
724749
}
725750
}
751+
726752
const span = instrumentation.tracer.startSpan('mongodb.getMore', {
727753
kind: SpanKind.CLIENT,
728754
});
@@ -1021,4 +1047,10 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
10211047
const poolName = `mongodb://${host}:${port}/${database}`;
10221048
this._poolName = poolName;
10231049
}
1050+
1051+
private _checkSkipInstrumentation(currentSpan: Span | undefined) {
1052+
const requireParentSpan = this.getConfig().requireParentSpan;
1053+
const hasNoParentSpan = currentSpan === undefined;
1054+
return requireParentSpan === true && hasNoParentSpan;
1055+
}
10241056
}

plugins/node/opentelemetry-instrumentation-mongodb/src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ export interface MongoDBInstrumentationConfig extends InstrumentationConfig {
4949
* Custom serializer function for the db.statement tag
5050
*/
5151
dbStatementSerializer?: DbStatementSerializer;
52+
53+
/**
54+
* Require parent to create mongodb span, default when unset is true
55+
*/
56+
requireParentSpan?: boolean;
5257
}
5358

5459
export interface MongoResponseHookInformation {

plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v3.test.ts

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ import {
3939
SEMATTRS_NET_PEER_PORT,
4040
} from '@opentelemetry/semantic-conventions';
4141

42+
// We can't use @ts-expect-error because it will fail depending on the used mongodb version on tests
43+
/* eslint-disable @typescript-eslint/ban-ts-comment */
44+
4245
describe('MongoDBInstrumentation-Tracing-v3', () => {
4346
function create(config: MongoDBInstrumentationConfig = {}) {
4447
instrumentation.setConfig(config);
@@ -85,7 +88,7 @@ describe('MongoDBInstrumentation-Tracing-v3', () => {
8588
}
8689
// Non traced insertion of basic data to perform tests
8790
const insertData = [{ a: 1 }, { a: 2 }, { a: 3 }];
88-
// @ts-expect-error -- v5 removed callback support
91+
// @ts-ignore -- v5 removed callback support
8992
collection.insertMany(insertData, (err: any, result: any) => {
9093
resetMemoryExporter();
9194
done();
@@ -94,7 +97,7 @@ describe('MongoDBInstrumentation-Tracing-v3', () => {
9497

9598
afterEach(done => {
9699
if (shouldTest) {
97-
// @ts-expect-error -- v5 removed callback support
100+
// @ts-ignore -- v5 removed callback support
98101
collection.deleteMany({}, done);
99102
} else {
100103
done();
@@ -619,7 +622,6 @@ describe('MongoDBInstrumentation-Tracing-v3', () => {
619622
let collection: Collection;
620623
before(done => {
621624
accessCollection(URL, DB_NAME, COLLECTION_NAME, {
622-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
623625
// @ts-ignore
624626
useUnifiedTopology: true,
625627
})
@@ -642,7 +644,7 @@ describe('MongoDBInstrumentation-Tracing-v3', () => {
642644
it('should generate correct span attributes', done => {
643645
const span = trace.getTracer('default').startSpan('findRootSpan');
644646
context.with(trace.setSpan(context.active(), span), () => {
645-
// @ts-expect-error -- v5 removed callback support
647+
// @ts-ignore -- v5 removed callback support
646648
collection.find({ a: 1 }).toArray((err, results) => {
647649
span.end();
648650
const [mongoSpan] = getTestSpans();
@@ -669,6 +671,49 @@ describe('MongoDBInstrumentation-Tracing-v3', () => {
669671
});
670672
});
671673

674+
describe('requireParentSpan', () => {
675+
// Resetting the behavior to default to avoid flakes in other tests
676+
beforeEach(() => {
677+
instrumentation.setConfig();
678+
});
679+
680+
afterEach(() => {
681+
instrumentation.setConfig();
682+
});
683+
684+
it('should not create spans without parent span when requireParentSpan is explicitly set to true', done => {
685+
context.with(trace.deleteSpan(context.active()), () => {
686+
collection
687+
.insertOne({ a: 1 })
688+
.then(() => {
689+
assert.strictEqual(getTestSpans().length, 0);
690+
done();
691+
})
692+
.catch(err => {
693+
done(err);
694+
});
695+
});
696+
});
697+
698+
it('should create spans without parent span when requireParentSpan is false', done => {
699+
instrumentation.setConfig({
700+
requireParentSpan: false,
701+
});
702+
703+
context.with(trace.deleteSpan(context.active()), () => {
704+
collection
705+
.insertOne({ a: 1 })
706+
.then(() => {
707+
assert.strictEqual(getTestSpans().length, 1);
708+
done();
709+
})
710+
.catch(err => {
711+
done(err);
712+
});
713+
});
714+
});
715+
});
716+
672717
/** Should intercept command */
673718
describe('Removing Instrumentation', () => {
674719
it('should unpatch plugin', () => {
@@ -723,3 +768,5 @@ describe('MongoDBInstrumentation-Tracing-v3', () => {
723768
});
724769
});
725770
});
771+
772+
/* eslint-enable @typescript-eslint/ban-ts-comment */

0 commit comments

Comments
 (0)