更新记录

0.1.0(2026-07-22)

  • 按 HBuilderX 4.71+ 规范将微信兼容性声明迁移到 mp.weixin,补齐暗黑模式、 多语言和宽屏适配声明,并增加发布包内容门禁。
  • 市场数据声明补充用户主动分享边界,明确插件不会自动上传到作者或第三方服务器。
  • 首发配置普通授权版 49 元、源码授权版 199 元,并明确付费加密 UTS 在传统 uni-app Web、微信小程序上的编译限制。
  • 首版支持 Android 5.0+、Web/H5 与微信小程序,兼容 uni-app Vue 3 和 uni-app x。
  • 微信小程序提供生命周期、实际路由、页面不存在、网络、JS error、unhandled rejection、Performance、内存告警和五个 uni 路由 API 监控。
  • 新增 shareDiagnosticBundle:Android 系统分享面板、Web Share/下载和微信 shareFileMessage,只在宿主用户操作时触发。
  • 提供 logbreadcrumbrecordError 三类宿主手动事件。
  • 提供多 listener onDiagnosticEvent 持续回调和按 ID/callback 注销,事件明确标识 custom、native、uni-api、web-api 或 plugin 来源。
  • 自动监控默认全部关闭,初始化通过稳定 namespaced monitor ID 按需启用;支持未来 平台 ID,由当前平台 Adapter 报告实际能力。
  • callback 与 storage 支持独立脱敏、等级过滤和持久化策略,默认均脱敏。
  • 手动事件默认落盘,自动事件默认不落盘;分别通过 persistCustompersistMonitored 控制。
  • Android、Web、微信均要等待异步 init.success;无效配置在任何存储变更前拒绝。
  • 监控注册和 strict 校验先于新存储配置提交;失败重新初始化恢复旧监控配置, Web IndexedDB 只加载一次以避免覆盖运行期事件。
  • 补齐 URL credential 脱敏、动态错误及 listener 参数校验、listener 重入保护和宿主 callback 异常隔离,非法公共参数统一返回 9010101
  • 非活跃或启动失败的 registration 不提交同步回放事件;非空结构化 error 固定包含 nullable 的 codestacktracecausefatal 键。
  • Android 提供生命周期、内存压力、Android 11+ 历史退出原因和网络监控;路由 监控支持 uni-app x,uni-app Vue 3 明确报告 requires_uni_app_x
  • Web 提供 error、unhandled rejection、visibility、navigation performance、CSP、 网络和路由监控。
  • Web error 使用捕获阶段监听,并用 phase: script/resource 区分脚本异常与资源 加载失败。
  • 提供 flush 写入屏障;异步存储失败返回稳定错误并产生关联原事件 ID 的 plugin.storage-health 事件。
  • 路由事件提供 operationIdoutcomedurationMs、安全的回调结果和结构化错误。
  • Android 使用 no-backup 私有 JSONL;Web 按 storageSubdirectory 使用独立 IndexedDB;微信使用 USER_DATA_PATH JSONL。
  • 回调、快照和诊断包统一为最终 schema 1 JSON;Android 返回私有文件路径,Web 返回临时 Blob URL,微信返回用户目录文件路径。
  • callback 与快照事件使用 canonical JSON 字符串作为跨平台边界,并与落盘、 导出共用显式 serializer,确保 Android 桥接后仍保留三个必填 nullable 字段。
  • 持久化事件读取和导出执行严格 schema v1 门禁;内部 listener 副本不复用该 不可信输入门禁,并兼容 Vue 3 Web 运行时。
  • Android 历史退出原因只在事件被运行时接受后推进游标;JSON 导出只允许原子 renameTo 发布,失败不保留非原子正式文件。
  • Android listener 仅抑制主线程宿主 callback 自身重入,不丢弃 IO 线程批量事件。
  • 公共运行时使用 Environment、Monitor、Storage、Archive、Delivery、JsonCodec 六个 Port;三端在各自目录实现 Adapter,common 不包含平台条件编译和全平台目录。
  • monitor listener 使用 registration ID 精确回滚和注销,避免新平台或重新初始化 影响不属于本批配置的监听器。
  • platform、monitor、origin 和 bundle delivery 改为开放标识;持久化门禁仍严格校验 schema v1,并保留未来新增的 optional 字段。
  • iOS 与 HarmonyOS 只保留公共契约和接入文档,不提供假实现。

当前为技术预览,不包含自动上传、云后台、request wrapper、符号化或 iOS/HarmonyOS 运行实现。


平台兼容性

uni-app(4.0)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× × × ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × × ×

uni-app x(4.44)

Chrome Safari Android iOS 鸿蒙 微信小程序
× ×

其他

多语言 暗黑模式 宽屏模式
×

UTS App Diagnostic Kit 隐私安全诊断包

作者 ID:xhx

面向 uni-app Vue 3 与 uni-app x 的离线诊断插件。首版支持 Android 5.0+、 Web/H5 和微信小程序,不依赖第三方诊断后台。插件不会上传或联网发送诊断数据; 只有宿主在用户点击回调内调用分享 API 时,才使用当前平台的系统交付能力。

安装与导入

将插件放入 uni_modules/xhx-diagnostic-kit

import {
  init,
  onDiagnosticEvent,
  offDiagnosticEvent,
  log,
  breadcrumb,
  recordError,
  getCapabilities,
  getDiagnostics,
  buildDiagnosticBundle,
  shareDiagnosticBundle,
  clear,
  flush,
} from '@/uni_modules/xhx-diagnostic-kit'

最低要求为 HBuilderX 5.15;uni-app x 最低 4.44。支持 uni-app Vue 3 和 uni-app x 的 Android、Chrome、Safari、微信小程序;微信基础库要求大于 3.7.1。Vue 2、nvue、iOS、HarmonyOS 尚不支持。

Android 分享使用插件内置 FileProvider、资源和 AndroidX Core 依赖。首次接入或 插件升级后,需要重新制作自定义基座或重新云打包;标准基座和仅热更新不会包含这些 原生配置。

购买与授权

  • 普通授权版:49 元,使用 DCloud 付费插件加密交付;
  • 源码授权版:199 元,提供完整源码,可在授权项目内审查和修改;
  • 两种授权都以插件市场订单绑定的 appid、包名和购买协议为准,均允许随授权宿主 App 打包发布,但不得转售、公开或作为插件再次分发。

付费加密 UTS 在不同技术栈存在官方编译边界:uni-app x 可使用普通授权版运行本页 声明的 Android、Web 和微信小程序能力;传统 uni-app Vue 3 的普通授权版适用于 Android App,Web 和微信小程序需要源码授权版。试用版只能用于自定义基座调试, 不能用于正式发行。购买前请按目标技术栈和平台完成试用或示例验证。

最小使用

init() 默认不启动任何自动监控。初始化是异步的;手动事件应在 success 之后记录。手动事件默认脱敏并写入本地存储;自动监控仍默认关闭:

const listenerId = onDiagnosticEvent((eventJson) => {
  // eventJson 是完整 canonical schema v1 JSON 文本。
  const event = JSON.parse(eventJson)
  handleDiagnosticEvent(event)
})

init({
  success() {
    log('info', 'checkout opened', { orderNo: 'A-1001' })
    breadcrumb('checkout.submit', { source: 'cart' })
    recordError({ message: 'payment rejected' }, { memberNo: 'M-1' })
  },
})

页面或应用不再接收事件时调用 offDiagnosticEvent(listenerId)。可以注册多个 listener;无参数调用 offDiagnosticEvent() 会注销全部 listener。 三个平台都要等待 init.success;提前调用记录、读取、导出、清理或 flush 会返回 9010106

每个回调事件都包含:

  • 身份与时间:schemaVersioneventIdsessionIdoperationIdsequenceoccurredAtobservedAtplatform
  • 来源与语义:originmonitorIdapiNamephaseoutcomecoveragetypelevelmessagedurationMs
  • 数据与处理状态:context、结构化 errorredactionpersistence

operationIddurationMserror 不适用时为 null,三个平台 不会省略这三个字段。 callback 与 snapshot.recentEvents 对外都使用 DiagnosticEventJson 字符串,避免 Android 原生桥接省略 null 属性。Vue 3/JavaScript 使用 JSON.parse(eventJson), uni-app x/UTS 使用 JSON.parseObject(eventJson);解析后再访问 monitorId 等字段。 单个 listener 执行期间再调用 log/breadcrumb/recordError 时,为避免异步 递归,新事件不会再回调该 listener,但仍可交付给其他 listener 并按 配置落盘。宿主 callback 抛错不会改写插件操作结果;诊断事件 callback 抛错会累计到 snapshot.plugin.callbackFailureCount

按需自动监控

初始化只启用明确列出的 ID,不提供 monitorAll

onDiagnosticEvent((eventJson) => {
  handleDiagnosticEvent(JSON.parse(eventJson))
})

init({
  monitors: [
    'uni.network-status',
    'uni.route.navigateTo',
    'web.error',
    'mp-weixin.error',
  ],
  persistMonitored: false,
  redaction: {
    callback: true,
    storage: true,
  },
  success(result) {
    // 每个请求项都有 status、reason、coverage 和 active。
    console.log(result.monitorResults)
  },
})

monitor ID 是开放的 namespaced string,具体支持列表由当前平台的 getCapabilities().monitors 返回。符合格式但当前平台未知的 ID 在非严格模式下 逐项返回 unsupported / platform_not_supported;设置 strictMonitors: true 时, 任一不可用项都会以 9010105 回滚整次初始化。格式非法的 ID 返回 9010101

手动事件默认落盘,自动事件默认不落盘。callbackScopecallbackMinLevelpersistCustompersistMonitoredminLevel 可分别控制 两个通道。可用 persistCustom: false 关闭手动事件落盘;自动事件需要落盘时 显式设置 persistMonitored: true。关闭脱敏不会自动采集更多字段。首版 capture 只支持 urlModeurlQuerypageQueryerrorStack;Header、body、文件路径和 WebSocket payload 不采集。 如果已指定 monitors,但既未启用 persistMonitored,也没有可接收 监控事件的 listener(包括 callbackScope: 'custom'),对应监控不会注册, monitorResultswarnings 返回 no_delivery_sink,避免静默丢日志。

重新初始化时先验证并注册监控,再提交新的容量和保留期配置;strict 监控失败会 恢复上一次有效配置,不会先按新配置裁剪旧事件。Web 按 storageSubdirectory 使用独立 IndexedDB namespace,重新初始化相同 namespace 不会覆盖运行期间刚写入的事件。

JSON 导出

首版只导出 JSON。需要明确确认队列写入结果时先调用 flush

flush({
  success(result) {
    console.log(result.flushed, result.flushedAt)
  },
})

buildDiagnosticBundle({
  lastHours: 24,
  maxEvents: 1000,
  success(result) {
    if (result.delivery === 'private-file') {
      // Android App 私有 cacheDir 文件路径。
      console.log(result.location)
    } else if (result.delivery === 'object-url') {
      // Web 临时 Blob URL;clear 或再次导出后会失效。
      window.open(result.location)
    } else if (result.delivery === 'wechat-private-file') {
      // 微信小程序用户目录文件,仅供后续显式分享。
      console.log(result.location)
    }
    console.log(result.sha256)
  },
})

// 必须直接从用户点击回调内调用。
shareDiagnosticBundle({
  lastHours: 24,
  maxEvents: 1000,
  success(result) {
    // Android: share sheet;Web: Web Share 或下载;微信: shareFileMessage。
    console.log(result.delivery, result.status, result.fileName)
  },
})

getDiagnostics({
  recentEventLimit: 20,
  success(snapshot) {
    const recentEvents = snapshot.recentEvents.map((eventJson) =>
      JSON.parse(eventJson)
    )
    console.log(snapshot.storage, recentEvents)
  },
})

clear({ scope: 'all' })

导出顶层固定为 schemaVersion: 1manifestdiagnosticsevents,逻辑有效期 24 小时。Android 使用私有 JSON 文件;Web 使用 IndexedDB 持久化和 JSON Blob object-url;微信使用用户目录 JSON 文件。读取、导出、分享和清理会先等待存储队列;高可靠业务也可在关键流程结束 时主动调用 flush()

默认值

  • monitors: []strictMonitors: false
  • callbackScope: 'all'callbackMinLevel: 'debug'
  • persistCustom: truepersistMonitored: falseminLevel: 'info'
  • redaction.callback: trueredaction.storage: true
  • capture.urlMode: 'origin-and-path'urlQuery: falsepageQuery: falseerrorStack: false
  • 容量 5 MiB,保留 7 天,目录 diagnostics-v1
  • URL 只保留 origin 与 path,不采集 page query、Header、body 或文件路径。

因此手动日志默认可回调并落盘;如不需要持久化,设置 persistCustom: falsedebug 需要将 minLevel 设为 'debug' 才会落盘。 recordErrortypecodestacktracecausefatal 是规范字段,同时接受 name 作为 type 别名、stack 作为 stacktrace 别名;动态调用传入非法类型统一返回 9010101

完整参数和返回类型以 utssdk/interface.uts 为准。

参数约束

API/参数 默认值 有效范围与语义
init.maxStorageBytes 5 MiB 256 KiB~50 MiB 的整数
init.retentionDays 7 1~30 的整数
init.storageSubdirectory diagnostics-v1 1~40 位小写字母、数字、点、下划线或连字符
init.extraRedactKeys [] 最多 64 项;去空白、去重后每项 1~64 字符
getDiagnostics.recentEventLimit 20 0~200 的整数;0 表示不返回近期事件
buildDiagnosticBundle.lastHours 24 1~168 的整数
buildDiagnosticBundle.maxEvents 1000 1~5000 的整数
buildDiagnosticBundle.includeExitReasons true 是否包含 type: 'exit' 的事件和摘要
shareDiagnosticBundle.* 同构建参数 生成后调用平台分享或下载;必须由用户操作触发
clear.scope all eventsexportsall

所有配置 boolean 必须传 boolean,枚举必须是公开类型中的值;NaNInfinity、 小数计数、数组代替 context、空 message/name 以及非法动态 error 字段都会返回 9010101message 和 error 文本投影最多保留 4096 字符;context 最深 8 层, 每个数组最多 100 项、每个对象最多 200 个字段,超出部分会裁剪并通过 redaction.truncated 标记。successfailcomplete 中的宿主异常会被隔离, 不会改变本次 API 的成功或失败结果;complete 始终在对应 success/fail 之后调用。

隐私与安全边界

  • 默认递归遮蔽 Token、密码、JWT、手机号、邮箱和身份证号;
  • callback 与 storage 生成独立不可变投影,两个脱敏开关互不影响;
  • 不采集设备唯一标识、联系人、定位、相册、剪贴板、SSID、BSSID 或 IP;
  • Android 只声明 android.permission.ACCESS_NETWORK_STATE 普通权限;
  • Android 数据写入 no-backup 私有目录;Web 数据写入独立 IndexedDB namespace; 微信数据写入 USER_DATA_PATH,不使用 localStorage;
  • 插件没有上传客户端,分享仅由宿主显式用户操作触发。

宿主仍应避免主动传入支付数据、请求正文和其他不必要的敏感信息。

平台限制

  • Android 5.0~10 不支持 native.android-exit-reason;Android 11+ 在下次 启动读取最近历史退出原因,覆盖度为 post-mortem
  • Android 内存压力回调不能保证在 OOM 前触发;
  • Android uni-app Vue 3 的原生 UTS 编译目标不支持 uni.addInterceptor,五个路由 monitor 返回 unsupportedreason: requires_uni_app_x
  • Android uni-app x 和 Web 的路由监控为 degraded,只覆盖对应 uni.* API, 不覆盖组件导航、原生 tabbar 或浏览器历史按钮;并发调用只能按 FIFO 尽力关联,事件会标记 context.correlationMode: 'fifo'
  • Web errorphase: script/resource 区分脚本异常和资源加载失败;脚本错误 仍受同源策略限制,资源事件只记录安全化后的标签名和 URL;
  • Web visibility:hidden 不代表正常退出;
  • Web 存储耐久性为 best-effort,无痕模式或 quota 错误会让初始化失败;
  • 微信提供实际 App 路由、页面不存在、JS error、unhandled rejection、性能和 内存告警;uni.route.* 只表示 API 调用,mp-weixin.route 才表示实际路由;
  • 微信 onHide 和内存告警不是崩溃、OOM 或历史退出证据;微信端不提供原生 Crash、ANR、OOM stack 或历史退出原因;
  • 微信 Performance resource timing 只表示性能条目,不等价于 request 监控;
  • plugin.storage-health 会产生 ready,并在 flush() 观察到异步写失败时产生 outcome: failed 事件;能力为 degraded / flush_required
  • plugin.bundle-healthplugin.monitor-health 首版只产生 ready,能力为 degraded / ready_signal_only
  • request、upload、download、WebSocket、原生 crash handler 和 ANR watchdog 不在首版范围内。

完整状态见 docs/architecture/monitoring-capability-matrix.md

iOS 与 HarmonyOS 扩展口

iOS 当前不支持,目录只保留 MetricKit 接入约束。HarmonyOS 当前不支持,目录 只保留 Ability 生命周期、沙箱存储和网络能力的接入约束。两端完成自动化测试和 真机验证前不会提供返回假数据的 index.uts

公共运行时通过 DiagnosticEnvironmentPortDiagnosticMonitorPortDiagnosticStoragePortDiagnosticArchivePortDiagnosticDeliveryPortDiagnosticJsonCodecPort 依赖平台能力。平台 index.uts 在构建期注入本平台 Adapter;common 不包含平台 switch、平台原生 API 或全平台 monitor catalog。完成基础重构后,新增平台只新增 对应平台目录和 Adapter,另行更新发布清单、文档和测试。

开发验证

npm run test:static
npm run test:kotlin
npm run test:web
npm run check:uts:android
npm run check:uts:web
npm run check:uts:mp-weixin
npm run sync:plugins
npm run test:web:x
npm run test:web:uni
npm run test:android:x
npm run test:android:uni

HBuilderX Web 脚本默认依次测试 web-chromeweb-safari,可通过 HBUILDERX_WEB_PLATFORMS 覆盖。Android 自动化需要已启动的真机或模拟器。

当前版本为技术预览 0.1.0。Android 11+ 异常退出恢复、不同浏览器无痕模式, 以及微信 Android/iOS 真机的分享、生命周期、内存和网络变化仍需在上架前验证。

隐私、权限声明

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

android.permission.ACCESS_NETWORK_STATE,用于记录网络类型;不申请运行时权限和公共存储权限

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

在 Android 私有目录、Web IndexedDB 和微信小程序用户目录保存宿主主动提交的诊断事件、运行信息与平台可用的退出信息;插件不会自动上传到作者或第三方服务器,只有宿主在用户主动操作中调用分享 API 时才通过系统或微信能力交付诊断包

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

暂无用户评论。