function recordWrapper({ shim, fn, name, recordNamer }) {
  return function wrapper(...args) {
    // Create the segment that will be recorded.
    const spec = recordNamer.call(this, shim, fn, name, args)
    if (!spec) {
      shim.logger.trace('No segment descriptor for "%s", not recording.', name)
      return fnApply.call(fn, this, args)
    }

    // middleware recorders pass in parent segment
    // we need to destructure this as it is not needed past this function
    // and will overwhelm trace level loggers with logging the entire spec
    const { parent: specParent, ...segDesc } = spec

    const context = shim.tracer.getContext()
    const transaction = context.transaction
    const parent = transaction?.isActive() && specParent ? specParent : context.segment

    if (!transaction?.isActive() || !parent) {
      shim.logger.debug('Not recording function %s, not in a transaction.', name)
      return fnApply.call(fn, this, args)
    }

    if (segDesc.callbackRequired && !_hasValidCallbackArg(shim, args, segDesc.callback)) {
      return fnApply.call(fn, this, args)
    }

    // Only create a segment if:
    //  - We are _not_ making an internal segment.
    //  - OR the parent segment is either not internal or not from this shim.
    const shouldCreateSegment = !(
      parent.opaque ||
      (segDesc.internal && parent.internal && shim.id === parent.shimId)
    )

    const segment = shouldCreateSegment
      ? _rawCreateSegment({ shim, spec: segDesc, parent, transaction })
      : parent

    const newContext = context.enterSegment({ segment })
    maybeAddCLMAttributes(fn, segment)

    return _doRecord.call(this, {
      context: newContext,
      args,
      segDesc,
      shouldCreateSegment,
      shim,
      fn,
      name
    })
  }
}
Wrapped function for Shim.prototype.record
This creates a segment for the method being recorded

@private
@param {object} params to function
@param {Shim} params.shim instance of shim
@param {Function} params.fn function being wrapped/recorded
@param {string} params.name name of function
@param {RecorderFunction} params.recordNamer
 A function which returns a record descriptor that gives the name and type of
 record we'll make.
 @returns {Function} wrapped function