function wrapAsJson({ shim, tools }) {
  const { agent } = shim
  const { config, metrics } = agent

  shim.wrap(tools, 'asJson', function wrapJson(shim, asJson) {
    /**
     * Wraps function in pino that is used to construct/serialize a log
     * line to json
     *
     * @param {object} obj data from mixins
     * @param {string} msg message of log line
     * @param {number} num log level as number
     * @param {string} time formatted snippet of json with time(`,"time":<unix time>`)
     * @param {...any} args
     * @returns {string} serialized log line
     */
    return function wrappedAsJson(...args) {
      const level = this?.levels?.labels?.[args[2]]
      // Pino log methods accept a singular object (a merging object) that can
      // have a `msg` property for the log message. In such cases, we need to
      // update that log property instead of the second parameter.
      const useMergeObj = args[1] === undefined && Object.hasOwn(args[0], 'msg')

      if (isMetricsEnabled(config)) {
        incrementLoggingLinesMetrics(level, metrics)
      }

      if (isLocalDecoratingEnabled(config)) {
        if (useMergeObj === true) {
          args[0].msg += agent.getNRLinkingMetadata()
        } else {
          args[1] += agent.getNRLinkingMetadata()
        }
      }

      /**
       * must call original asJson to allow pino
       * to construct the entire log line before we
       * add to the log aggregator
       */
      const logLine = asJson.apply(this, args)

      if (isLogForwardingEnabled(config, agent)) {
        const formatLogLine = reformatLogLine({
          msg: useMergeObj === true ? args[0].msg : args[1],
          logLine,
          agent,
          level,
          logger: shim.logger
        })

        agent.logs.add(formatLogLine)
      }

      return logLine
    }
  })
}
Wraps `asJson` to properly decorate and forward logs

@param {object} params to function
@param {Shim} params.shim instance of shim
@param {object} params.tools exported `pino/lib/tools`