bugfix
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
import { LogLevel, LOG_LEVEL, LOG_TO_REALTIME } from './config'
|
||||
|
||||
/**
|
||||
* 全项目统一日志出口。
|
||||
*
|
||||
* 用法:logger.debug('模块名', '消息', 任意参数)
|
||||
* 级别:DEBUG < INFO < WARN < ERROR < SILENT,低于当前生效级别的调用直接返回,
|
||||
* 且级别判断前置,不做任何字符串拼接,热路径(如每次请求)零开销。
|
||||
*
|
||||
* 输出:
|
||||
* 1. console —— 按级别选用 log / warn / error,开发者工具与真机调试可见
|
||||
* 2. 微信实时日志 —— 仅 WARN 及以上写入,可在小程序后台「实时日志」查询线上问题
|
||||
*/
|
||||
|
||||
// 手动覆盖的级别(LOG_LEVEL 为 null 时按环境自动推导)
|
||||
let manualLevel: LogLevel | null = LOG_LEVEL
|
||||
|
||||
// 解析后的生效级别缓存,避免每次调用都读环境信息
|
||||
let resolvedLevel: LogLevel | null = null
|
||||
|
||||
const LEVEL_NAMES: Record<number, string> = {
|
||||
[LogLevel.DEBUG]: 'DEBUG',
|
||||
[LogLevel.INFO]: 'INFO',
|
||||
[LogLevel.WARN]: 'WARN',
|
||||
[LogLevel.ERROR]: 'ERROR',
|
||||
}
|
||||
|
||||
// 按运行环境推导默认级别:开发版最详细,正式版只看异常
|
||||
function resolveByEnv(): LogLevel {
|
||||
try {
|
||||
const info = wx.getAccountInfoSync()
|
||||
const env = info.miniProgram && info.miniProgram.envVersion
|
||||
if (env === 'develop') return LogLevel.DEBUG
|
||||
if (env === 'trial') return LogLevel.INFO
|
||||
return LogLevel.WARN
|
||||
} catch (e) {
|
||||
// 取不到环境信息时(低版本基础库等)退化为 DEBUG,保证开发期可见
|
||||
return LogLevel.DEBUG
|
||||
}
|
||||
}
|
||||
|
||||
// 当前生效级别
|
||||
export function getLevel(): LogLevel {
|
||||
if (resolvedLevel === null) {
|
||||
resolvedLevel = manualLevel === null ? resolveByEnv() : manualLevel
|
||||
}
|
||||
return resolvedLevel
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行时调整日志级别(调级后对全局生效)。
|
||||
* 传 null 恢复为「按环境自动」。
|
||||
*/
|
||||
export function setLevel(level: LogLevel | null): void {
|
||||
manualLevel = level
|
||||
resolvedLevel = null
|
||||
}
|
||||
|
||||
// 实时日志单例(惰性初始化,取不到时降级为仅 console,绝不因日志抛错影响业务)
|
||||
let realtimeManager: any = null
|
||||
let realtimeInited = false
|
||||
|
||||
function getRealtimeManager(): any {
|
||||
if (realtimeInited) return realtimeManager
|
||||
realtimeInited = true
|
||||
try {
|
||||
if (typeof wx.getRealtimeLogManager === 'function') {
|
||||
realtimeManager = wx.getRealtimeLogManager()
|
||||
}
|
||||
} catch (e) {
|
||||
realtimeManager = null
|
||||
}
|
||||
return realtimeManager
|
||||
}
|
||||
|
||||
// 序列化日志参数:实时日志有单条长度限制,做截断保护
|
||||
function stringify(args: any[]): string {
|
||||
try {
|
||||
return args
|
||||
.map((a) => {
|
||||
if (typeof a === 'string') return a
|
||||
try {
|
||||
return JSON.stringify(a)
|
||||
} catch (e) {
|
||||
return String(a)
|
||||
}
|
||||
})
|
||||
.join(' ')
|
||||
.slice(0, 1000)
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function emit(level: LogLevel, module: string, args: any[]): void {
|
||||
if (level < getLevel()) return
|
||||
|
||||
const prefix = `[${LEVEL_NAMES[level]}][${module}]`
|
||||
|
||||
// console 通道
|
||||
if (level === LogLevel.ERROR) {
|
||||
console.error(prefix, ...args)
|
||||
} else if (level === LogLevel.WARN) {
|
||||
console.warn(prefix, ...args)
|
||||
} else {
|
||||
console.log(prefix, ...args)
|
||||
}
|
||||
|
||||
// 实时日志通道:仅 WARN 及以上,避免击穿配额
|
||||
if (!LOG_TO_REALTIME || level < LogLevel.WARN) return
|
||||
const manager = getRealtimeManager()
|
||||
if (!manager) return
|
||||
const text = `${prefix} ${stringify(args)}`
|
||||
try {
|
||||
if (level === LogLevel.ERROR && typeof manager.error === 'function') manager.error(text)
|
||||
else if (typeof manager.warn === 'function') manager.warn(text)
|
||||
} catch (e) {
|
||||
// 日志写入失败不影响业务
|
||||
}
|
||||
}
|
||||
|
||||
export const logger = {
|
||||
/** 开发期流程细节:页面入参、请求发起/成功、数据条数 */
|
||||
debug(module: string, ...args: any[]): void {
|
||||
emit(LogLevel.DEBUG, module, args)
|
||||
},
|
||||
/** 关键流程节点:登录成功、刷新成功、下单/上传/分享成功 */
|
||||
info(module: string, ...args: any[]): void {
|
||||
emit(LogLevel.INFO, module, args)
|
||||
},
|
||||
/** 可恢复异常与静默降级:静默 catch、跳转失败、非关键请求失败 */
|
||||
warn(module: string, ...args: any[]): void {
|
||||
emit(LogLevel.WARN, module, args)
|
||||
},
|
||||
/** 真正的错误:网络异常、业务错误码、账号禁用、登录态失效 */
|
||||
error(module: string, ...args: any[]): void {
|
||||
emit(LogLevel.ERROR, module, args)
|
||||
},
|
||||
}
|
||||
|
||||
export default logger
|
||||
Reference in New Issue
Block a user