console.log封装 无感切入接入console日志

前言:

在项目开发中涉及了一些日志的处理,包括在electronjs中添加log、上报到后台服务的日志,团队中之前已经有小伙伴封装好了上报的逻辑,需要在代码里批量替换开发中写好的console.log,将console.log替换成window.log,通过window.log的方式便可以上报到服务端了

 window.log.error('<<<<<<<<<<<< axios.interceptors.response >>>>>>>>>>>>')
    window.log.info('日志')

这种方式有什么问题:

1、侵入性太强。

软件开发原则里有提到一个小点:子类可以扩展父类的功能,但不能改变父类原有的功能。相对应的到我们实际的项目中也是类似,一个扩展软件 不应该直接改变原先主应用就已经有的书写方式,大家已经习惯用于console.log,不应该强制修改其习惯的方式,这么做只会起到适得其反的效果。

2、封装好的log无法定位到原先代码的输出位置

所有使用了封装好的window.log.info方式打印的地方 后面的代码都是定位到函数内,当你想debugger的时候 将会非常困难。

解决方式:要想达到无感侵入,并且有断点可循,就只能重写console.log

export function initConsole(log) {
  const errorInfoArr = ['error', 'Error', 'fail'] // 定义错误的字符状态
  const logFunc = console.log // 保留原console.log
  
  console.log = function () {
    // 开发环境不上报日志
    const isLogStack = process.env.NODE_ENV === 'development'
    try {
      let arr = []
      arr.push(...arguments)
      let isError = false // 是否是错误输出
      let isRecord = false // 是否需要动态上报输出
      for (let i = 0; i < arr.length; i++) {
        const item = arr[i]
        if (Object.prototype.toString.call(item) === '[object String]') {
          isError = !!errorInfoArr.find((error) => item.indexOf(error) > -1)
          isRecord = item.indexOf('record:') > -1
        }
        if (Object.prototype.toString.call(item) === '[object Error]') {
          isError = true
        }
        if (isError) {
          break
        }
      }

      const stack = new Error().stack // 获取调用栈
      const stackArr = stack.split('\n')
      // 如果是错误输出
      if (isError) {
        if (isLogStack) {
          console.info(arr)
          window.log.error(...arr)
          logFunc(...arr, stackArr[2])
        } else {
          if (log) {
            log.error(...arguments)
          } else {
            window.log.error(...arguments)
          }
        }
        return
      }
      // 如果不是开发环境
      if (!isLogStack) {
        if (log) {
          if (isRecord) {
            log.info(...arguments)
          } else {
            logFunc(...arr)
          }
        } else {
          if (isRecord) {
            window.log.info(...arguments)
          } else {
            logFunc(...arr)
          }
        }
      } else {
        if (log) {
          logFunc(...arr)
        } else {
          logFunc(...arr, stackArr[2])
        }
      }
      // logFunc(stackArr)
      // isLogStack ? console.trace() : null // 是否打印堆栈
    } catch (e) {
      console.log(`a log error: ${e}`)
    }
  }
}

在这段函数里有一个入参log是针对客户端的应用的日志输出,如果是嵌入到web端 这个参数可以不传递。

总结:基于对console.log的重写,便可以保证日志的输出在上报之前做一层筛选,并且无侵入性的引入此类功能,未来如果要在其它平台使用,也不用去修改平台的代码便可非常容易的使用日志功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自动化处理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值