@evertro/monitor-transport
v1.1.1
Published
Evertro Monitor 数据上报传输层
Downloads
698
Readme
@evertro/monitor-transport
Evertro Monitor 数据上报传输层 — 队列管理、批处理、重试、离线缓存
概述
本包负责将引擎产出的 MonitorEvent 通过网络发送到后端,是 SDK 的出口层。核心能力:
- 上报队列 — 按优先级分级处理(P0 即时、P1 批量、P2 定时)
- Payload 格式转换 — 将内部事件结构转换为旧 APM SDK 的扁平格式
- 批处理器 — 将事件切分为固定大小的批次上报
- 重试策略 — 指数退避重试,失败后自动存入离线缓存
- 离线缓存 — 上报失败时持久化到 localStorage/wx.setStorageSync
- 传输适配器 — 提供
WeappTransport(wx.request)和H5Transport(fetch/XHR)两种实现
安装
pnpm add @evertro/monitor-transport模块说明
reportQueue.ts — 上报队列(核心)
管理事件的入队、分级处理和上报调度。
import { ReportQueue } from '@evertro/monitor-transport';
const queue = new ReportQueue(
transport, // 传输适配器(WeappTransport 或 H5Transport)
config, // MonitorConfig
getContext, // () => MonitorContext
getSessionId, // () => string
offlineStorage // 可选,离线缓存实例
);
queue.start(); // 启动定时上报(按 reportInterval)
queue.enqueue(event); // 添加事件(P0 立即发,P1/P2 入队)
queue.flush(); // 手动触发 flush(如 app.onHide 时)
queue.stop(); // 停止定时上报
queue.length; // 当前队列长度事件分级处理策略
| 优先级 | 处理方式 | 典型事件 |
|--------|---------|---------|
| P0 IMMEDIATE | 立即单条上报(不入队) | 白屏、崩溃 |
| P1 BATCH | 入队,满 batchSize 条后自动 flush | JS 错误、Promise 拒绝 |
| P2 SCHEDULED | 入队,等定时器触发 flush | 性能数据、操作链路 |
createPayload() — 载荷构建
将 MonitorEvent[] 转换为旧 APM SDK 的扁平结构:
MonitorEvent[] (内部格式)
│
├── context.device → 打平到外层 (screenHeight, os, networkType...)
├── context.user → 打平到外层 (userId, visitorId...)
└── events → toReportEvent() 转换为 ReportEvent[] 格式
(eventId + eventName + eventCode + eventTime + attr)并发安全
使用 flushing 锁防止并发 flush 导致事件重复上报或丢失:
flush() 被调用
└─ if (flushing) return; // 其他 flush 正在执行,跳过
└─ flushing = true;
└─ try { ... } finally { flushing = false; }batchProcessor.ts — 批处理器
将事件数组按固定大小切分为多个批次。
import { BatchProcessor } from '@evertro/monitor-transport';
const processor = new BatchProcessor(10); // 每批最多 10 条
const batches = processor.process(events);
// events = [e1, e2, ..., e15]
// batches = [[e1..e10], [e11..e15]]retryStrategy.ts — 重试策略
指数退避重试机制。
import { RetryStrategy } from '@evertro/monitor-transport';
const retry = new RetryStrategy(3); // 最多重试 3 次
const success = await retry.execute(() => transport.send(payload));
// 第 1 次失败 → 等 1s → 第 2 次失败 → 等 2s → 第 3 次失败 → 返回 false重试间隔公式:delay = 1000 * 2^(attempt - 1) ms
| 次数 | 延迟 | |------|------| | 第 1 次重试 | 1s | | 第 2 次重试 | 2s | | 第 3 次重试 | 4s |
offlineStorage.ts — 离线缓存
上报失败的事件持久化到本地存储,下次初始化时自动重传。
import { OfflineStorage } from '@evertro/monitor-transport';
const storage = new OfflineStorage({
maxCacheSize: 100, // 最多缓存 100 条
maxBytes: 512000, // 最多 500KB
storageKey: '_evertro_offline_events',
});
storage.save(events); // 持久化事件
const cached = storage.load(); // 读取缓存的事件
storage.clear(); // 清空缓存存储引擎自动适配:
- 小程序环境 →
wx.setStorageSync/wx.getStorageSync - H5/PC 环境 →
localStorage
interface.ts — 传输接口
所有传输适配器必须实现的接口:
interface TransportInterface {
send(payload: ReportPayload): Promise<boolean>;
}weappTransport.ts — 微信小程序传输
基于 wx.request 的传输实现。
import { WeappTransport } from '@evertro/monitor-transport';
const transport = new WeappTransport(dsn);
// 内部使用 wx.request POST 发送数据
// 请求标记 _evertro_skip = true 防止被 NetworkPlugin 自监控防自我监控: 发送的请求会在 requestTask 上设置 _evertro_skip 标记,NetworkPlugin 会跳过带有此标记的请求。
h5Transport.ts — H5/PC 传输
基于 fetch(优先)或 XMLHttpRequest(降级)的传输实现。
import { H5Transport } from '@evertro/monitor-transport';
const transport = new H5Transport(dsn);
// 优先使用 fetch API
// 不支持 fetch 时降级为 XMLHttpRequest
// XHR 请求设置 _evertro_skip 防止自监控配置参数
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| reportBatchSize | number | 10 | 批量上报条数阈值 |
| reportInterval | number | 10000 | 定时上报间隔(ms) |
| maxRetries | number | 3 | 上报重试次数 |
| maxCacheSize | number | 100 | 离线缓存上限条数 |
| offlineMaxBytes | number | 512000 | 离线缓存字节上限(500KB) |
依赖关系
@evertro/monitor-types → @evertro/monitor-core → @evertro/monitor-transport导出一览
export { ReportQueue } from './reportQueue';
export { BatchProcessor } from './batchProcessor';
export { RetryStrategy } from './retryStrategy';
export { OfflineStorage } from './offlineStorage';
export { WeappTransport } from './weappTransport';
export { H5Transport } from './h5Transport';
export type { TransportInterface } from './interface';