MCPcopy Index your code
hub / github.com/apache/skywalking-nodejs / interceptOperation

Method interceptOperation

src/plugins/MongoDBPlugin.ts:293–364  ·  view source on GitHub ↗
(Cls: any, operation: string, operationFunc: any)

Source from the content-addressed store, hash-verified

291 }
292
293 interceptOperation(Cls: any, operation: string, operationFunc: any): void {
294 const plugin = this;
295 const _original = Cls.prototype[operation];
296
297 if (!_original) return;
298
299 Cls.prototype[operation] = function (...args: any[]) {
300 let span = ContextManager.currentSpan;
301
302 // XXX: mongodb calls back into itself at this level in several places, for this reason we just do a normal call
303 // if this is detected instead of opening a new span. This should not affect secondary db calls being recorded
304 // from a cursor since this span is kept async until the cursor is closed, at which point it is stoppped.
305
306 if ((span as any)?.mongodbInCall)
307 // mongodb has called into itself internally
308 return _original.apply(this, args);
309
310 let host = '???';
311
312 try {
313 const db = this instanceof plugin.Collection ? this.s.db : this;
314 host = db.serverConfig.s.options.servers.map((s: any) => `${s.host}:${s.port}`).join(','); // will this work for non-NativeTopology?
315 } catch {
316 /* nop */
317 }
318
319 span = ContextManager.current.newExitSpan('MongoDB/' + operation, Component.MONGODB);
320
321 span.start();
322
323 try {
324 if (span.component === Component.UNKNOWN)
325 // in case mongoose sitting on top
326 span.component = Component.MONGODB;
327
328 span.layer = SpanLayer.DATABASE;
329 span.peer = host;
330
331 span.tag(Tag.dbType('MongoDB'));
332 span.tag(Tag.dbInstance(`${this.s.namespace.db}`));
333
334 const hasCB = operationFunc.call(this, operation, span, args);
335
336 (span as any).mongodbInCall = true;
337 let ret = _original.apply(this, args);
338 (span as any).mongodbInCall = false;
339
340 if (!hasCB) {
341 if (plugin.hookCursorMaybe(span, ret)) {
342 // NOOP
343 } else if (ret && typeof ret.then === 'function') {
344 // generic Promise check
345 ret = wrapPromise(span, ret);
346 } else {
347 // no callback passed in and no Promise or Cursor returned, play it safe
348 span.stop();
349
350 return ret;

Callers 1

installMethod · 0.95

Calls 7

wrapPromiseFunction · 0.90
hookCursorMaybeMethod · 0.80
errorMethod · 0.80
newExitSpanMethod · 0.65
startMethod · 0.65
stopMethod · 0.65
asyncMethod · 0.65

Tested by

no test coverage detected