Skip to content

Commit 18e815f

Browse files
committed
feat(instrumentation-mongodb): Add requireParentSpan config option.
1 parent e57f3e4 commit 18e815f

File tree

4 files changed

+75
-5
lines changed

4 files changed

+75
-5
lines changed

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/src/instrumentation.ts

Lines changed: 33 additions & 5 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,15 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
438446
callback?: Function
439447
) {
440448
const currentSpan = trace.getSpan(context.active());
449+
450+
const hasNoParentSpan = currentSpan === undefined;
451+
const requireParentSpan = instrumentation.getConfig().requireParentSpan;
452+
const skipInstrumentation = requireParentSpan === true && hasNoParentSpan;
453+
441454
const resultHandler =
442455
typeof options === 'function' ? options : callback;
443456
if (
444-
!currentSpan ||
457+
skipInstrumentation ||
445458
typeof resultHandler !== 'function' ||
446459
typeof ops !== 'object'
447460
) {
@@ -490,10 +503,15 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
490503
callback?: Function
491504
) {
492505
const currentSpan = trace.getSpan(context.active());
506+
507+
const hasNoParentSpan = currentSpan === undefined;
508+
const requireParentSpan = instrumentation.getConfig().requireParentSpan;
509+
const skipInstrumentation = requireParentSpan === true && hasNoParentSpan;
510+
493511
const resultHandler =
494512
typeof options === 'function' ? options : callback;
495513
if (
496-
!currentSpan ||
514+
skipInstrumentation ||
497515
typeof resultHandler !== 'function' ||
498516
typeof cmd !== 'object'
499517
) {
@@ -634,10 +652,15 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
634652
callback?: Function
635653
) {
636654
const currentSpan = trace.getSpan(context.active());
655+
656+
const hasNoParentSpan = currentSpan === undefined;
657+
const requireParentSpan = instrumentation.getConfig().requireParentSpan;
658+
const skipInstrumentation = requireParentSpan === true && hasNoParentSpan;
659+
637660
const resultHandler =
638661
typeof options === 'function' ? options : callback;
639662
if (
640-
!currentSpan ||
663+
skipInstrumentation ||
641664
typeof resultHandler !== 'function' ||
642665
typeof cmd !== 'object'
643666
) {
@@ -699,9 +722,14 @@ export class MongoDBInstrumentation extends InstrumentationBase<MongoDBInstrumen
699722
callback?: Function
700723
) {
701724
const currentSpan = trace.getSpan(context.active());
725+
726+
const hasNoParentSpan = currentSpan === undefined;
727+
const requireParentSpan = instrumentation.getConfig().requireParentSpan;
728+
const skipInstrumentation = requireParentSpan === true && hasNoParentSpan;
729+
702730
const resultHandler =
703731
typeof options === 'function' ? options : callback;
704-
if (!currentSpan || typeof resultHandler !== 'function') {
732+
if (skipInstrumentation || typeof resultHandler !== 'function') {
705733
if (typeof options === 'function') {
706734
return original.call(
707735
this,

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-v5-v6.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,42 @@ describe('MongoDBInstrumentation-Tracing-v5', () => {
652652
});
653653
});
654654

655+
describe('requireParentSpan', () => {
656+
it('should create spans without parent span when requireParentSpan is false', done => {
657+
create({
658+
requireParentSpan: false,
659+
});
660+
661+
collection
662+
.insertOne({ a: 1 })
663+
.then(() => {
664+
assert.strictEqual(getTestSpans().length, 1);
665+
done();
666+
})
667+
.catch(err => {
668+
done(err);
669+
});
670+
});
671+
672+
it('should not create spans without parent span when requireParentSpan is set to false by setConfig', done => {
673+
create();
674+
675+
instrumentation.setConfig({
676+
requireParentSpan: false,
677+
});
678+
679+
collection
680+
.insertOne({ a: 1 })
681+
.then(() => {
682+
assert.strictEqual(getTestSpans().length, 1);
683+
done();
684+
})
685+
.catch(err => {
686+
done(err);
687+
});
688+
});
689+
})
690+
655691
/** Should intercept command */
656692
describe('Removing Instrumentation', () => {
657693
it('should unpatch plugin', () => {

0 commit comments

Comments
 (0)