更新记录
1.0.0(2026-07-22)
新增
- 首次发布请求日志插件
- 基于
useComplete 完成拦截器实现,记录所有请求(含网络超时、无网络等异常情况)
- 自动适配
mh-request 全局配置:
apiFieldMap:自动识别 code / msg 字段名
successCode:判断业务是否成功
httpSuccessCodes:判断 HTTP 状态是否成功
- 智能日志分级:
info:请求成功(HTTP 成功且业务成功)
warn:业务错误(HTTP 成功但业务 code 不匹配)
error:HTTP 错误(含超时、无网络、5xx 等)
- 支持配置项:
logLevel:控制日志输出级别(debug / info / warn / error)
customLogger:自定义日志输出函数,支持上报到服务器
excludeUrls:按 URL 排除日志(支持字符串或正则)
maxLogSize:限制内存日志存储条数,防止内存泄漏
- 提供
getLoggerHistory() 方法,方便调试时查看最近日志
- 请求拦截器记录请求开始时间,便于计算耗时
- 响应日志包含状态码、耗时、业务数据、业务状态等完整信息
平台兼容性
uni-app(3.8.0)
| Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
| √ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
小红书小程序 |
快应用-华为 |
快应用-联盟 |
| √ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
uni-app x(3.8.0)
| Chrome |
Safari |
Android |
iOS |
鸿蒙 |
微信小程序 |
| √ |
√ |
√ |
√ |
√ |
√ |
mh-request-logger
基于 mh-request 的请求日志插件,记录所有请求(含网络异常)的完整信息,支持自定义日志输出和上报。
本插件是 mh-request 的配套插件,需配合使用。
特性
- 📝 全量记录:基于
useComplete 拦截器,无论请求成功或失败(含超时、无网络等)都能记录
- 🔧 自动适配:自动读取全局
apiFieldMap、successCode、httpSuccessCodes,与核心库行为一致
- 🎯 智能分级:自动区分 HTTP 错误、业务错误、成功响应,使用不同日志级别
- 🚫 灵活过滤:支持按 URL 排除日志(字符串包含或正则匹配)
- 🎨 可定制输出:支持自定义日志函数,便于接入监控平台或上报服务器
- 💾 内存管理:支持限制日志存储条数,防止内存泄漏
- 🐛 调试友好:提供
getLoggerHistory() 方法,随时查看最近日志
快速开始
import { Request } from '@/uni_modules/mh-request'
import { loggerPlugin } from '@/uni_modules/mh-request-logger'
const request = new Request({
baseURL: 'https://api.example.com',
plugins: [
{ plugin: loggerPlugin }
]
})
export default request
自定义日志输出
const request = new Request({
baseURL: 'https://api.example.com',
plugins: [
{
plugin: loggerPlugin,
config: {
logLevel: 'warn',
customLogger: (level, message, data) => {
// 接入自定义日志系统或上报到服务器
myLogSystem.report({ level, message, data })
}
}
}
]
})
排除特定接口
const request = new Request({
baseURL: 'https://api.example.com',
plugins: [
{
plugin: loggerPlugin,
config: {
excludeUrls: [
'/health', // 字符串包含匹配
/^\/api\/ping/, // 正则匹配
]
}
}
]
})
配置项
LoggerConfig
| 属性 |
类型 |
默认值 |
说明 |
logLevel |
'debug' \| 'info' \| 'warn' \| 'error' |
'info' |
日志输出级别,低于该级别的日志将被过滤 |
customLogger |
(level, message, data) => void |
console.log |
自定义日志输出函数,可用于上报或集成第三方日志系统 |
excludeUrls |
(string \| RegExp)[] |
[] |
排除的 URL 列表,匹配的请求不记录任何日志 |
maxLogSize |
number |
1000 |
内存中保留的最大日志条数,超出后移除最早记录 |
日志级别说明
| 级别 |
优先级 |
输出场景 |
debug |
0 |
所有请求(含请求体等详细信息) |
info |
1 |
成功请求(HTTP 成功且业务成功) |
warn |
2 |
业务错误(HTTP 成功但业务 code ≠ successCode) |
error |
3 |
HTTP 错误(含超时、无网络、5xx 等) |
工作原理
日志记录流程
请求发起 → 请求拦截器记录开始时间 → 发送请求
↓
请求完成(成功或失败)→ 完成拦截器触发
↓
判断 HTTP 状态(使用 httpSuccessCodes)
↓
成功 → 解析业务数据 → 判断业务 code(使用 apiFieldMap)
↓
业务成功 → info 级别日志
业务失败 → warn 级别日志
HTTP 失败 → error 级别日志(含 errMsg)
↓
输出日志(customLogger 或 console)
↓
存入内存历史(受 maxLogSize 限制)
高级用法
上报到监控平台(注意脱敏)
⚠️ 重要提醒:上报日志到服务器时,务必对请求/响应中的敏感字段进行脱敏处理,避免泄露用户密码、Token、身份证号、手机号等隐私信息。
const request = new Request({
baseURL: 'https://api.example.com',
plugins: [
{
plugin: loggerPlugin,
config: {
logLevel: 'error', // 仅上报错误日志
customLogger: (level, message, data) => {
// 脱敏处理:移除或隐藏敏感字段
const sanitized = sanitizeData(data)
// 上报到 Sentry / 阿里云 ARMS 等监控平台
Sentry.captureMessage(message, { level, extra: sanitized })
}
}
}
]
})
/**
* 数据脱敏函数 - 递归移除敏感字段(示例函数,不一定适合直接使用)
*/
function sanitizeData(data: any): any {
if (!data || typeof data !== 'object') return data
const sensitiveKeys = ['password', 'token', 'authorization', 'phone', 'idCard', 'secret']
const result = Array.isArray(data) ? [] : {}
for (const [key, value] of Object.entries(data)) {
// 敏感字段直接替换为掩码
if (sensitiveKeys.some(k => k.toLowerCase() === key.toLowerCase())) {
result[key] = '***'
continue
}
// 递归处理嵌套对象
if (value && typeof value === 'object') {
result[key] = sanitizeData(value)
} else {
result[key] = value
}
}
return result
}
查看历史日志(调试用)
// 在控制台查看最近日志
const history = request.getLoggerHistory()
console.table(history)
生产环境动态调整日志级别
const isDev = process.env.NODE_ENV === 'development'
const request = new Request({
baseURL: 'https://api.example.com',
plugins: [
{
plugin: loggerPlugin,
config: {
logLevel: isDev ? 'debug' : 'error',
maxLogSize: isDev ? 500 : 50
}
}
]
})
接入第三方日志库(如 log4js)
import log4js from 'log4js'
const logger = log4js.getLogger('http')
const request = new Request({
plugins: [
{
plugin: loggerPlugin,
config: {
customLogger: (level, message, data) => {
logger[level](message, data)
}
}
}
]
})
日志输出示例
成功请求
[logger] INFO [完成] GET /user/info -> 成功 (156ms) {
statusCode: 200,
duration: '156ms',
data: { code: 1, msg: '成功', data: { id: 1, name: '张三' } },
business: { code: 1, msg: '成功', success: true }
}
业务错误
[logger] WARN [完成] POST /order/create -> 业务错误(1001) (203ms) {
statusCode: 200,
duration: '203ms',
data: { code: 1001, msg: '库存不足', data: null },
business: { code: 1001, msg: '库存不足', success: false }
}
网络超时
[logger] ERROR [完成] GET /user/info -> HTTP - request:fail timeout (30002ms) {
statusCode: 0,
duration: '30002ms',
errMsg: 'request:fail timeout'
}