(Container: any, operation: string)
| 86 | } |
| 87 | |
| 88 | interceptOperation(Container: any, operation: string): void { |
| 89 | const _original = Container[operation]; |
| 90 | |
| 91 | if (!_original) return; |
| 92 | |
| 93 | Container[operation] = function () { |
| 94 | let span = ContextManager.currentSpan; |
| 95 | |
| 96 | if ((span as any)?.mongooseInCall) |
| 97 | // mongoose has called into itself internally |
| 98 | return _original.apply(this, arguments); |
| 99 | |
| 100 | const host = `${this.db.host}:${this.db.port}`; |
| 101 | span = ContextManager.current.newExitSpan('Mongoose/' + operation, Component.MONGOOSE, Component.MONGODB); |
| 102 | |
| 103 | span.start(); |
| 104 | |
| 105 | try { |
| 106 | span.component = Component.MONGOOSE; |
| 107 | span.layer = SpanLayer.DATABASE; // mongodb may not actually be called so we set these here in case |
| 108 | span.peer = host; |
| 109 | |
| 110 | span.tag(Tag.dbType('MongoDB')); |
| 111 | span.tag(Tag.dbInstance(this.db.name)); |
| 112 | |
| 113 | const hasCB = typeof arguments[arguments.length - 1] === 'function'; |
| 114 | |
| 115 | if (hasCB) { |
| 116 | const wrappedCallback = wrapCallback(span, arguments[arguments.length - 1], 0); |
| 117 | |
| 118 | arguments[arguments.length - 1] = function () { |
| 119 | // in case of immediate synchronous callback from mongoose |
| 120 | (span as any).mongooseInCall = false; |
| 121 | wrappedCallback.apply(this, arguments as any); |
| 122 | }; |
| 123 | } |
| 124 | |
| 125 | (span as any).mongooseInCall = true; // if mongoose calls into itself while executing this operation then ignore it |
| 126 | let ret = _original.apply(this, arguments); |
| 127 | (span as any).mongooseInCall = false; |
| 128 | |
| 129 | if (!hasCB) { |
| 130 | if (ret && typeof ret.then === 'function') { |
| 131 | // generic Promise check |
| 132 | |
| 133 | if (ret.constructor.name != 'Query') { |
| 134 | ret = wrapPromise(span, ret); |
| 135 | } else { |
| 136 | // Mongoose Query object |
| 137 | const chainMethods = ['select', 'sort', 'skip', 'limit', 'populate']; |
| 138 | |
| 139 | // Mongoose Query object |
| 140 | const originalThen = ret.then; |
| 141 | const originalExec = ret.exec; |
| 142 | const originalLean = ret.lean; |
| 143 | |
| 144 | // Preserve the query chain methods using arrow functions to maintain context |
| 145 | ret.then = (...args: any[]) => wrapPromise(span, originalThen.apply(ret, args)); |
no test coverage detected