为什么需要自定义 Logger ?
也许会好奇,console.log
不是挺好用的吗,为什么要花精力去自定义 Logger 呢?其实思想跟统一路由是一个道理的,通过自定义Logger,我们可以更好地管理应用中的所有打印,比如统一打印内容的格式,统一打印信息的级别等,甚至如果后期需要做类似后端的 logger 记录也是可以轻松做到的。
那应该怎么实现自定义 Logger 呢?
其实就很简单的方法,通过对 console.log
包装一层函数,然后让外界使用包装过的函数间接调用 console.log
就可以了,这里我列出了我常用的方案给大家参考:
src/hooks/useAppLoggerHook.ts
import { appDebugLogger, appErrorLogger, appInfoLogger, appWarnLogger } from '@/utils/logger'
import { useRef } from 'react'
/** 应用自定义 logger hook */
export const useAppLoggerHook = (module: string) => {
const moduleNameRef = useRef(module)
const debugLogger = (msg: Parameters<typeof appInfoLogger>[1], msgObj?: Parameters<typeof appInfoLogger>[2]) => {
appDebugLogger(moduleNameRef.current, msg, msgObj)
}
const infoLogger = (msg: Parameters<typeof appInfoLogger>[1], msgObj?: Parameters<typeof appInfoLogger>[2]) => {
appInfoLogger(moduleNameRef.current, msg, msgObj)
}
const warnLogger = (msg: Parameters<typeof appInfoLogger>[1], msgObj?: Parameters<typeof appInfoLogger>[2]) => {
appWarnLogger(moduleNameRef.current, msg, msgObj)
}
const errorLogger = (msg: Parameters<typeof appInfoLogger>[1], msgObj?: Parameters<typeof appInfoLogger>[2]) => {
appErrorLogger(moduleNameRef.current, msg, msgObj)
}
return {
debugLogger,
infoLogger,
warnLogger,
errorLogger,
}
}
src/utils/logger/index.ts
const isProd = process.env.APP_ENV === 'PROD'
const colorHash = {
error: '#E0282E',
warn: '#F2BD27',
ready: '#00B96B',
info: '#1677FF',
debug: '#626262',
}
function handleLogWithStyle(_module: string, type: keyof typeof colorHash, msg: string, msgObj: any) {
if (isProd) {
return
}
// console.log('colorHash[type]', colorHash[type])
if (msg && msgObj) {
console.log(
`%c${_module} ${type}::%c${msg}`,
`padding: 2px 5px; border-radius: 3px 0 0 3px; color: #fff; background: ${colorHash[type]}; font-weight: bold;`,
`padding: 2px 5px; border-radius: 0 3px 3px 0; color: ${colorHash[type]}; background: #fff; font-weight: bold;`,
msgObj
)
} else if (msg) {
console.log(
`%c${_module} ${type}::%c${msg}`,
`padding: 2px 5px; border-radius: 3px 0 0 3px; color: #fff; background: ${colorHash[type]}; font-weight: bold;`,
`padding: 2px 5px; border-radius: 0 3px 3px 0; color: ${colorHash[type]}; background: #fff; font-weight: bold;`
)
} else if (msgObj) {
console.log(
`%c${_module} ${type}::%c${msg}`,
`padding: 2px 5px; border-radius: 3px; color: #fff; background: ${colorHash[type]}; font-weight: bold;`,
`padding: 2px 5px; border-radius: 0 3px 3px 0; color: ${colorHash[type]}; background: #fff; font-weight: bold;`,
msgObj
)
}
}
export const appDebugLogger = (_module: string, msg?: string, msgObj?: any) => {
handleLogWithStyle(_module, 'debug', msg || '', msgObj || undefined)
}
export const appInfoLogger = (_module: string, msg?: string, msgObj?: any) => {
handleLogWithStyle(_module, 'info', msg || '', msgObj || undefined)
}
export const appWarnLogger = (_module: string, msg?: string, msgObj?: any) => {
handleLogWithStyle(_module, 'warn', msg || '', msgObj || undefined)
}
export const appErrorLogger = (_module: string, msg?: string, msgObj?: any) => {
handleLogWithStyle(_module, 'error', msg || '', msgObj || undefined)
}
使用方法:src/pages/index/index.tsx
const {
infoLogger,
} = useAppLoggerHook('Home Page')
infoLogger('This is example info logger')
warnLogger('This is example warn logger')
errorLogger('This is example error logger')
最终打印的效果:
在 utils 下的 logger.ts 文件中有 appDebugLogger、appInfoLogger、appWarnLogger、appErrorLogger 这四个代理 console.log
函数,其实也是简单地对平时使用 console.log 的场景做了分类,如果后续有需要对应用中的打印信息上传后日志服务器(比如说微信小程序的日志),方便后续查询,也是可以在这几个代理函数里实现逻辑的。此外因为这几个函数又是统一调用了 handleLogWithStyle
函数,所以也可以在 handleLogWithStyle
函数中实现打印(日志上传)开关功能的。
希望对大家有帮助~