前言:
在项目开发中涉及了一些日志的处理,包括在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的重写,便可以保证日志的输出在上报之前做一层筛选,并且无侵入性的引入此类功能,未来如果要在其它平台使用,也不用去修改平台的代码便可非常容易的使用日志功能。