更新记录

1.0.0(2026-11-10)

首个版本。

  • 提供 report / query / detail / stats / clean 五个 action
  • traceId 自动生成与透传,异常自动记 error 后原样抛出
  • 字段名与值级双层脱敏
  • 自带日志查询页

平台兼容性

云端兼容性

支付宝云 腾讯云 阿里云
× √ √

云函数日志追踪(traceId)

一个零第三方依赖的 uniCloud 日志云函数。业务云函数只要包一层,就自动获得链路 ID 透传、结构化落库、异常自动捕获、敏感字段脱敏、按链路查询与统计、过期清理,并附一个开箱即用的查询页。

适合:云函数排障靠 console.log 翻日志、多函数串调用串不起链路、线上报错要靠用户描述复现、需要按 traceId 一次性拉出全链路记录的项目。

特性

  • traceId 全链路透传:客户端 / 上游传入则复用,没有就自动生成;下游调用自动带 __traceId,下游用 wrap() 包一层就能复用同一个 ID
  • 结构化落库:固定字段(时间、级别、服务、动作、耗时、错误码、内容、扩展字段、用户、IP),便于检索统计
  • 异常自动捕获:wrap() 包住业务 handler,抛错自动记为 error 并记堆栈,然后原样抛出,不改变业务语义
  • 双层脱敏:SDK 本地先脱敏,云函数服务端再脱敏一次(不信任客户端);字段名匹配之外还有一层值级兜底(手机号、身份证号、JWT)
  • 采样与容量控制:日志级别、采样率、单批上限、字符串 / 数组 / 递归深度上限,全部可配
  • 日志失败不影响业务:上报是独立云函数调用,所有异常静默吞掉,并有超时保护(默认 1 秒),不会把业务接口拖住
  • 零依赖:只用 uniCloud.database()、callFunction()、getClientInfos(),不引任何 npm 包或扩展库
  • 自带查询页:按 traceId / 级别 / 时间查询、详情查看、分页、分级别统计

目录结构

uni_modules/aliang-trace-log/
├── package.json                      插件配置(含价格与加密文件清单)
├── pages_init.json                   自动注册查询页
├── readme.md / changelog.md / license.md
├── uniCloud/
│   ├── cloudfunctions/aliang-trace-log/
│   │   ├── index.js                  加密云函数(单文件,含配置/脱敏/存储/查询/入口 5 个分区)
│   │   └── package.json
│   └── database/trace_logs.schema.json   日志集合 Schema
├── js_sdk/trace-client.js            轻量接入 SDK(客户端与云函数两端通用)
└── pages/trace-log/list.vue          查询页

插件内的 uniCloud 目录不带 -aliyun / -tcb 后缀,导入工程后 HBuilderX 会虚拟合并到项目根目录的 uniCloud 中。

云函数刻意做成单文件:普通授权版的加密清单是按文件配置的,多文件结构一旦漏配某个 lib 文件,那个文件就会明文留在你的项目里,而且不会有任何报错。单文件可以让加密清单只有一项,不可能漏。

五分钟接入

  1. 从插件市场导入本插件到 uni-app 项目。
  2. 上传 uniCloud/database/trace_logs.schema.json 到你的服务空间(生成 trace_logs 集合)。
  3. 右键 uniCloud/cloudfunctions/aliang-trace-log → 上传部署。
  4. 在业务侧接 SDK(见下),或直接在查询页点几下验证。
  5. pages_init.json 会自动提示把「日志追踪」页注册进 pages.json,确认即可。

建议第 0 步就把 TRACE_QUERY_TOKEN 配上(服务空间 → 环境变量)。没配的话,clean 会直接拒绝执行,query / stats 则对任何知道云函数名的人开放。

接入方式 A:包装业务云函数(推荐)

把 js_sdk/trace-client.js 复制到你自己的云函数目录,然后:

const TraceLog = require('./trace-client.js')

async function business(event, context) {
  // 原来的业务代码,一行都不用改
  return { errCode: 0, errMsg: 'ok', data: { id: 1 } }
}

exports.main = TraceLog.wrap(business, { service: 'order-service' })

wrap() 自动完成:生成/复用 traceId、计时、捕获异常并记 error、业务返回 errCode != 0 记 warn、采集真实客户端 IP、上报日志。上报失败静默忽略,且最多等 1 秒(timeout 可调)。

串起下游链路(下游同样用 wrap 就会自动复用同一个 traceId):

const res = await TraceLog.callFunction('inventory-deduct', { sku: 'A01', qty: 1 })

接入方式 B:客户端 SDK

import TraceLog from '@/uni_modules/aliang-trace-log/js_sdk/trace-client.js'

TraceLog.configure({ service: 'app-client', sampleRate: 1 })

// 包装调用,自动带 traceId 并记录耗时 / 错误
const res = await TraceLog.callFunction('order-create', { goodsId: 9 })

// 任意自定义日志
TraceLog.report({ level: 'info', action: 'page-view', message: '进入详情页' })

手动上报(不装 SDK 也能用)

await uniCloud.callFunction({
  name: 'aliang-trace-log',
  data: {
    action: 'report',
    records: [{
      traceId: 'm8x2k1-a3b4c5d6',
      level: 'error',
      service: 'pay-service',
      action: 'charge',
      duration: 128,
      code: 'PAY_TIMEOUT',
      message: '支付网关超时',
      extra: { orderNo: 'NO20261110001', retry: 2 },
      userId: 'u_10086'
    }]
  }
})

单条也可以平铺(不用 records):{ action:'report', level:'error', message:'...' },其中 __traceId 也会被当作链路 ID 使用。

API 参考

统一返回 { errCode: 0 | 字符串, errMsg, data }。失败时错误码以 aliang-trace-log- 开头:

errCode 含义
aliang-trace-log-unauthorized 令牌不对
aliang-trace-log-token-required clean 没配 TRACE_QUERY_TOKEN
aliang-trace-log-invalid-param 时间参数无法解析
aliang-trace-log-invalid-action action 不认识
aliang-trace-log-collection-missing 集合不存在(没上传 schema)
aliang-trace-log-internal 其他异常
action 说明 主要参数 需要 token
report 上报日志 records(数组,单批默认上限 50,超出部分截断并在 truncated 回报)或平铺单条 否
query 分页查询 traceId level service code userId startTime endTime page pageSize 是(若配置)
detail 按 _id 查详情 id 是(若配置)
stats 分级别计数 traceId service code userId startTime endTime 是(若配置)
clean 清理过期日志 days(默认取 TRACE_RETENTION_DAYS,30 天) 必须

report 单条记录字段:traceId / spanId / level / service / action / duration / code / message / extra / userId / clientIp。

report 的返回:{ accepted, dropped, truncated, insert }。insert.degraded 为 true 表示批量写入失败后改成了逐条写,insert.skipped 是没能写进去的条数。

时间参数必须是毫秒时间戳(Date.now()),也接受能 Date.parse 的字符串(如 '2026-11-01')。传了别的东西会直接返回 invalid-param,不会静默忽略条件。

查询示例:

const res = await uniCloud.callFunction({
  name: 'aliang-trace-log',
  data: {
    action: 'query',
    traceId: 'm8x2k1-a3b4c5d6',
    level: 'error',
    startTime: Date.now() - 86400000,
    page: 1, pageSize: 20,
    token: '你的查询令牌'
  }
})
console.log(res.result.data.list)

配置项

在 uniCloud 服务空间的环境变量里配置。collection 与 queryToken 只能用环境变量设置,data.config 无法覆盖;其余可按次覆盖。

环境变量 默认 说明
TRACE_COLLECTION trace_logs 日志集合名。不接受请求侧覆盖,否则调用方能把 clean/query 指向任意业务集合
TRACE_LEVEL info 最低记录级别:debug / info / warn / error
TRACE_SAMPLE_RATE 1 采样率 0~1;error 始终全量记录
TRACE_QUERY_TOKEN 空 查询/清理令牌。只能通过环境变量设置;clean 没它直接拒绝
TRACE_RETENTION_DAYS 30 clean 默认保留天数
TRACE_MAX_BATCH 50 单批最多写入条数
TRACE_MAX_STRING 2000 单字符串截断长度
TRACE_MAX_EXTRA 8000 extra 序列化上限,超出时按 key 逐个保留并标记 _truncated
TRACE_MAX_ARRAY 20 数组保留元素数
TRACE_MAX_DEPTH 4 对象递归深度
TRACE_REDACT_VALUES 1 值级脱敏开关(手机号 / 身份证号 / JWT),设 0 关闭

安全设计:TRACE_QUERY_TOKEN 与 TRACE_COLLECTION 都刻意不接受 data.config 覆盖。前者防止调用方自己指定 token 绕过鉴权,后者防止调用方把破坏性的 clean 指向业务集合。

data.config 可覆盖其余参数,也可追加 sensitiveKeys(数组)扩充脱敏字段名。

安全与隐私

  • 字段名脱敏(子串匹配,大小写不敏感,支持中文键名):password / passwd / pwd / secret / token / authorization / cookie / session / apikey / privatekey / credential / idcard / identity / phone / mobile / email / bankcard / cardno / cvv / signature / 手机号 / 身份证 / 姓名 / 住址 / 地址 / 病历号 / 住院号。命中值替换为 [REDACTED]。
  • 值级兜底脱敏:message 正文和 extra 的字符串值里出现的 11 位手机号、18 位身份证号、JWT 会被替换为 [PHONE] / [IDCARD] / [JWT]。字段名匹配管不到正文,所以需要这一层。
  • 服务端再次脱敏,客户端 SDK 处理与否都不影响结果。
  • 集合 permission 全部为 false,前端无法直连,只能通过云函数访问。
  • 数据全部写在你自己的服务空间,不向任何第三方服务器发送。
  • 请自行避免上报患者身份信息、身份证号等敏感个人信息;本插件的脱敏是兜底,不是合规豁免。
  • clean 默认 fail-closed:没配 TRACE_QUERY_TOKEN 时一律拒绝,避免"装完就默认允许删库"。
  • 建议给 query / detail / stats 也配上 token,并把查询页入口放在管理后台。

容量估算(重要)

默认 sampleRate: 1,也就是每个被 wrap() 包住的请求都会写一条日志。按 10 万请求/天算就是 10 万条/天、约 300 万条/月,会实实在在吃掉你服务空间的存储和数据库读写额度。

三个建议:

  1. 生产环境把 TRACE_SAMPLE_RATE 调到 0.1(错误日志不受影响,始终全量);
  2. 给 trace_logs 配定时清理(见下);
  3. 只把需要排障的关键云函数用 wrap() 包起来,不要全站无脑包。

索引建议

Schema 未强制声明索引(避免不同云厂商差异)。日志量上来后,建议在 uniCloud 控制台为 trace_logs 建:

索引字段 用途
trace_id 按链路拉全量
create_time(降序) 列表分页与时间范围
level + create_time 错误筛选
code 错误码聚合

提醒:这份 Schema 的作用是创建集合 + 在控制台声明字段。uniCloud 的 DB Schema 只在 JQL 下生效,云函数走的是原生数据库接口,所以 required、bsonType 这些不对云函数写入做校验,字段规范由云函数自己保证。另外 create_time 存的是毫秒时间戳数字,不是日期类型。

定时清理

clean 需要 token,定时触发可以在触发器参数里带上:

{ "action": "clean", "days": 30, "token": "与环境变量 TRACE_QUERY_TOKEN 相同的值" }

这样既能自动清理,又不会出现"任何人都能调 clean 删日志"的口子。

常见问题

Q:报 collection-missing。 A:日志集合不存在。上传插件自带的 uniCloud/database/trace_logs.schema.json 到服务空间后重试。

Q:调用正常但查不到日志。 A:依次检查:云函数是否上传部署、集合是否创建、TRACE_LEVEL 是否高于上报级别、TRACE_SAMPLE_RATE 是否小于 1、业务侧是否 await 了包装后的 handler。

Q:报 token-required。 A:在调 clean,但服务空间没配 TRACE_QUERY_TOKEN。这是刻意的:清理是破坏性操作,不允许在"未配置即开放"的默认状态下被执行。

Q:报 invalid-param。 A:startTime / endTime 传了无法解析的值。请传毫秒时间戳。

Q:云函数里日志偶尔丢。 A:SDK 默认等待上报完成(推荐),且有 1 秒超时保护。若手动设了 fireAndForget: true,serverless 实例在请求返回后可能冻结,异步请求发不出去,云函数环境请保持默认。

Q:报 unauthorized。 A:服务空间配了 TRACE_QUERY_TOKEN,但请求没带 token,或值不一致。查询页在筛选区下方会出现令牌输入框(输入后会记住)。

Q:云函数报模块找不到。 A:云函数是单文件,理论上不会有子模块缺失。请确认上传的是整个 aliang-trace-log 云函数目录,且 index.js 没有被截断。

Q:支持 uni-app x / 鸿蒙 / 小程序吗? A:云函数与 js_sdk/trace-client.js 均为纯 JS,各端可用;自带查询页是 vue 页面,仅用于 uni-app 项目(uni-app x 项目可只接 SDK,用 callFunction 自行取数)。

授权方式(购买前请先读)

  • 付费普通授权版按服务空间 spaceId 绑定。开发空间和生产空间是两个 spaceId,需要各自授权。
  • 提供 7 天试用,试用期内可以把加密云函数部署到指定服务空间体验;试用到期后,加密云函数会被平台自动删除。
  • 加密云函数无法上传到你未授权的其他服务空间。

版本要求

  • HBuilderX 4.71+(平台兼容性使用新规范),uniCloud 阿里云 / 腾讯云服务空间
  • JavaScript 普通云函数(CommonJS),不需要任何扩展库

授权

购买后按 DCloud 插件市场的标准授权条款使用,可用于自己的任意商业项目,项目数量不限。普通授权版不含源码,请勿反编译或二次分发。

隐私、权限声明

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

无

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

本插件把业务方主动上报的结构化日志写入使用者自己的 uniCloud 服务空间数据库(默认集合 trace_logs),字段包含 traceId、时间、级别、服务名、动作、耗时、错误码、日志内容、业务扩展字段、用户标识与客户端 IP。不向任何第三方服务器发送数据,不内置任何统计或上报 SDK。内置敏感字段脱敏(password、token、idcard、phone、email 等)与值级兜底脱敏(手机号、身份证号、JWT),服务端会二次脱敏;业务方仍应自行避免上报患者身份信息、身份证号等敏感个人信息。

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

无

暂无用户评论。