Cls.prototype[operation] = function()

in src/plugins/MongoDBPlugin.ts [299:363]


    Cls.prototype[operation] = function (...args: any[]) {
      let span = ContextManager.currentSpan;

      // XXX: mongodb calls back into itself at this level in several places, for this reason we just do a normal call
      // if this is detected instead of opening a new span. This should not affect secondary db calls being recorded
      // from a cursor since this span is kept async until the cursor is closed, at which point it is stoppped.

      if ((span as any)?.mongodbInCall)
        // mongodb has called into itself internally
        return _original.apply(this, args);

      let host = '???';

      try {
        const db = this instanceof plugin.Collection ? this.s.db : this;
        host = db.serverConfig.s.options.servers.map((s: any) => `${s.host}:${s.port}`).join(','); // will this work for non-NativeTopology?
      } catch {
        /* nop */
      }

      span = ContextManager.current.newExitSpan('MongoDB/' + operation, Component.MONGODB);

      span.start();

      try {
        if (span.component === Component.UNKNOWN)
          // in case mongoose sitting on top
          span.component = Component.MONGODB;

        span.layer = SpanLayer.DATABASE;
        span.peer = host;

        span.tag(Tag.dbType('MongoDB'));
        span.tag(Tag.dbInstance(`${this.s.namespace.db}`));

        const hasCB = operationFunc.call(this, operation, span, args);

        (span as any).mongodbInCall = true;
        let ret = _original.apply(this, args);
        (span as any).mongodbInCall = false;

        if (!hasCB) {
          if (plugin.hookCursorMaybe(span, ret)) {
            // NOOP
          } else if (ret && typeof ret.then === 'function') {
            // generic Promise check
            ret = wrapPromise(span, ret);
          } else {
            // no callback passed in and no Promise or Cursor returned, play it safe
            span.stop();

            return ret;
          }
        }

        span.async();

        return ret;
      } catch (e) {
        span.error(e);
        span.stop();

        throw e;
      }
    };