更新记录

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 拦截器,无论请求成功或失败(含超时、无网络等)都能记录
  • 🔧 自动适配:自动读取全局 apiFieldMapsuccessCodehttpSuccessCodes,与核心库行为一致
  • 🎯 智能分级:自动区分 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'
}

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。