消息与日志系统
完整的观测体系,让每一次治理行为都可追踪、可分析、可上报。
消息提示系统(notify)
notify 是统一的消息出口,所有能力的用户提示都走这里:
const requestManager = setupRequestGuard(axios, {
notify: (payload) => {
// payload.message — 提示文案
// payload.capability — 触发能力名:'duplicate' / 'circuitBreaker'
// payload.strategy — duplicate 策略:'ignore' / 'block' / 'reuse'(仅 duplicate 时存在)
Toast.show(payload.message);
},
defaults: {
duplicate: {
showToast: true, // 控制是否触发 notify
message: '请勿重复提交' // 默认提示文案
}
}
});触发时机
| 触发时机 | capability | 说明 |
|---|---|---|
| duplicate 命中(ignore) | duplicate | showToast: true 且 ignore 策略命中重复,请求静默挂起 |
| duplicate 命中(block) | duplicate | showToast: true 且 block 策略命中重复,请求被拒绝 |
| duplicate 命中(reuse-waiting) | duplicate | showToast: true 且 reuse 策略命中在途请求,进入复用等待 |
| 熔断拦截 | circuitBreaker | 熔断打开,请求被拒绝(未发出) |
| 熔断状态变更 | circuitBreaker | 状态在 NORMAL / CIRCUIT_BREAKER / HALF_OPEN 间切换,让业务感知保护状态 |
| retry | — | 默认不触发 notify,仅走 logger;重试耗尽后返回原始错误给业务 |
notify payload 字段
各触发时机的完整 payload 字段见 事件与 payload 参考。常见字段包括:
- duplicate:
message/strategy/capability/requestKey/repeatCount/pendingCount/method/url - circuitBreaker 拦截:
message/capability/circuitKey/state/failCount/openedAt - circuitBreaker 状态变更:
message/capability/circuitKey/fromState/toState/failCount/openedAt
日志系统
Logger 事件目录
所有治理行为先归一化为标准 LogEvent,再由 logger 决定去向:
| 事件名 | 等级 | 触发能力 | 说明 |
|---|---|---|---|
duplicate.triggered | warn | duplicate | 命中重复请求(ignore / block / reuse)时触发 |
retry.scheduled | info | retry | 一次失败被判定为可重试,下一次 attempt 已安排等待时触发 |
retry.exhausted | warn | retry | retry 生命周期停止时触发(不只是次数用尽,data.reason 区分停止原因) |
circuitBreaker.blocked | warn | circuitBreaker | 请求被熔断拦截(熔断打开状态)时触发 |
circuitBreaker.stateChange | warn | circuitBreaker | 熔断状态在 NORMAL / CIRCUIT_BREAKER / HALF_OPEN 间切换时触发 |
circuitBreaker.halfOpenProbe | info | circuitBreaker | 半开状态放行试探请求时触发 |
circuitBreaker.recovered | info | circuitBreaker | 半开试探成功、熔断单元恢复到 NORMAL 时触发 |
requestGuard.internalError | error | 守护层自身 | 守护层内部异常被隔离时触发;生产环境静默,仅走 logger |
各事件的完整 data 字段(含 retry.exhausted 的 reason 枚举)见 事件与 payload 参考。
使用内置控制台 Logger
import { ConsoleRequestGuardLogger, setupRequestGuard } from '@hydd/request-guard';
const requestManager = setupRequestGuard(axios, {
logger: new ConsoleRequestGuardLogger({
devOnly: true, // 仅开发环境输出(production 自动静默)
level: 'debug' // 最低输出等级:debug / info / warn / error
})
});ConsoleRequestGuardLogger 是面向浏览器 DevTools 的默认实现:浏览器环境渲染彩色诊断面板(含标识生成依据、策略、对比信息和调用栈),其他环境输出纯文本。
自定义 Logger(可选)
如果你需要把日志发往自己的监控平台或埋点系统,可继承 RequestGuardLogger 基类,重写 write(event) 方法:
import { RequestGuardLogger, setupRequestGuard } from '@hydd/request-guard';
class RemoteLogger extends RequestGuardLogger {
write(event) {
// event: { level, event, message, namespace, timestamp, data }
// 发往你的监控平台
monitor.report(event.event, event.data);
}
}
setupRequestGuard(axios, {
logger: new RemoteLogger({ devOnly: false, level: 'warn' })
});默认行为
不传 logger → 自动用内置 ConsoleRequestGuardLogger,只需传 dev: true。传 logger: null → 关闭日志。传自定义 logger → 用你的。大多数项目用内置日志就够了,不需要自定义。
Logger 配置项
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| devOnly | boolean | true | 仅开发环境输出 |
| enabled | boolean | undefined | 显式开关(优先级高于 devOnly) |
| dev | boolean | undefined | 当前是否开发环境;跨端(RN / 小程序)时请显式传入,不要依赖自动探测 |
| level | string | 'debug' | 最低输出等级(debug / info / warn / error) |
RequestGuardLogger 基类还提供以下方法,自定义 logger 可复用:
| 方法 | 说明 |
|---|---|
setDev(dev) | 更新 dev 标识,使 devOnly 模式下的输出开关与运行态保持一致 |
createEvent(level, messageOrEvent, data?) | 把字符串或事件片段整理成标准 LogEvent,供自定义 logger 复用 |
shouldLog(event) | 输出前的过滤判断,统一处理 enabled / devOnly / level |
log(event) | 日志主入口,标准化和过滤后进入 write |
debug / info / warn / error | 各等级便捷入口 |
TIP
如果把日志发往远端监控,建议对调用栈做脱敏处理,避免敏感信息外泄。
环境探测与 dev 选项
dev 可在两处配置:setupRequestGuard({ dev }) 全局选项,或 new ConsoleRequestGuardLogger({ dev })。显式声明优先于自动探测。跨端场景(React Native、微信小程序等)与 Web 的 process.env.NODE_ENV 语义不一致,务必显式传入 dev,避免生产环境误输出或开发环境静默。后续可通过 configure({ dev }) 或 logger.setDev() 更新。
// 跨端显式声明 dev
const requestManager = setupRequestGuard(axios, {
dev: process.env.NODE_ENV !== 'production',
logger: new ConsoleRequestGuardLogger({ dev: process.env.NODE_ENV !== 'production' })
});
