@evertro/monitor-core
v1.1.1
Published
Evertro Monitor 核心引擎
Downloads
738
Readme
@evertro/monitor-core
Evertro Monitor 核心引擎 — 插件管理、事件管道、数据处理
概述
本包是 SDK 的中枢引擎,负责:
- 插件生命周期管理 — 注册、初始化、热插拔、销毁
- 事件上报管道 — 采样 → 去重 → 事件枚举填充 → 脱敏 → beforeSend → ignoreErrors → 上报
- 操作链路管理 — RingBuffer 环形缓冲,自动淘汰最早的记录
- 上下文管理 — 用户信息、设备信息的统一管理
- 事件映射 — 内部事件类型到旧 APM SDK 枚举的转换
本包是平台无关的,不包含任何 wx、document、window 等平台特定 API 调用。
安装
pnpm add @evertro/monitor-core模块说明
engine.ts — CollectorEngine 核心引擎
引擎是所有插件和上报管道的中心节点。
import { CollectorEngine } from '@evertro/monitor-core';
const engine = new CollectorEngine(config);
// 注册插件
engine.use(errorPlugin);
engine.use(performancePlugin);
// 设置上报回调(连接到 ReportQueue)
engine.setReportCallback((event) => reportQueue.enqueue(event));
// 初始化(启动所有插件)
engine.init();
// 销毁(停止所有插件,清理资源)
engine.destroy();上报管道处理流程
event
│
├─ 1. 采样检查(P0 事件跳过,始终 100% 上报)
│ └─ Sampler.shouldSample()
│
├─ 2. 去重检查(相同 message + stack 前 3 帧,5 分钟内只报 1 次)
│ └─ Deduplicator.check()
│
├─ 3. 事件枚举填充(自动计算 eventId / eventName / eventCode)
│ └─ enrichEventFields()
│
├─ 4. 数据脱敏(替换 token/password/phone 等)
│ └─ sanitize()
│
├─ 5. beforeSend 钩子(用户自定义过滤)
│ └─ config.beforeSend() → 返回 null 则丢弃
│
├─ 6. ignoreErrors 规则匹配
│ └─ 字符串包含匹配 / 正则匹配
│
└─ 7. 交给上报回调 → ReportQueue关键方法
| 方法 | 描述 |
|------|------|
| use(plugin) | 注册插件。引擎已初始化时新插件会立即启动(热插拔) |
| init() | 初始化所有已注册插件。只能调用一次 |
| destroy() | 销毁引擎和所有插件,清理 EventHub、breadcrumbs、去重器 |
| setReportCallback(fn) | 设置上报回调,由 Monitor 主入口调用 |
| report(event) | 核心上报方法(箭头函数,this 安全),触发完整管道 |
| addBreadcrumb(crumb) | 添加操作链路节点(箭头函数,this 安全) |
eventMapping.ts — 事件映射工具
将内部的 MonitorEvent 类型映射到旧 APM SDK 的 EventId / EventName / EventCode 格式。
import {
resolveEventId,
resolveEventCode,
enrichEventFields,
toReportEvent,
} from '@evertro/monitor-core';resolveEventId(event)
根据 event.type 推断对应的 EventId:
// type → EventId 映射规则
'js_error' → EventId.ERROR // E100000015
'promise_rejection' → EventId.PROMISE_REJECTION // E100000023
'network_error' → EventId.NETWORK_ERROR // E100000022
'resource_error' → EventId.RESOURCE_ERROR // E100000024
'react_error' → EventId.REACT_ERROR // E100000025
'white_screen' → EventId.WHITE_SCREEN // E100000020
'page_load' → EventId.PAGE_VIEW // E100000010
'api_call' / 'fcp' / 'lcp' / 'fp' 等 → EventId.PERFORMANCE // E100000021resolveEventCode(event)
生成 "TYPE-pagePath" 格式的事件编码:
resolveEventCode({ type: 'js_error', pageUrl: '/pages/index' })
// → 'ERROR-/pages/index'
resolveEventCode({ type: 'white_screen', pageUrl: '/pages/home' })
// → 'WHITE_SCREEN-/pages/home'enrichEventFields(event)
在引擎管道中调用,一次性填充 eventId、eventName、eventCode 三个字段:
enrichEventFields(event);
// event.eventId = 'E100000015'
// event.eventName = '错误事件'
// event.eventCode = 'ERROR-/pages/index'toReportEvent(event)
将内部 MonitorEvent 转换为旧 SDK 格式的 ReportEvent(用于 createPayload() 出口):
const reportEvent = toReportEvent(errorEvent);
// {
// eventId: 'E100000015',
// eventName: '错误事件',
// eventCode: 'ERROR-/pages/index',
// eventTime: 1713200000000,
// attr: {
// pagePath: '/pages/index',
// errorMessage: 'xxx is not defined',
// errorStack: 'ReferenceError: xxx is not defined\n at ...',
// errorType: 'js_error',
// }
// }eventHub.ts — 事件总线
跨插件通信的发布/订阅机制。
import { EventHub } from '@evertro/monitor-core';
const hub = new EventHub();
// 订阅事件
hub.on('network:complete', (data) => { /* ... */ });
// 发布事件
hub.emit('network:complete', { url: '/api/user', duration: 1200 });
// 取消订阅
hub.off('network:complete', handler);
// 清除所有监听
hub.clear();使用场景: NetworkPlugin 通过 EventHub 广播请求完成事件,PerformancePlugin 监听并检测慢接口(> 3s)。
ringBuffer.ts — 环形缓冲区
固定大小的环形数据结构,用于存储操作链路(breadcrumbs)。满了之后自动淘汰最早的记录。
import { RingBuffer } from '@evertro/monitor-core';
const buffer = new RingBuffer<Breadcrumb>(30); // 最多 30 条
buffer.push(breadcrumb); // 添加
const items = buffer.getAll(); // 获取所有(按时间顺序)
buffer.clear(); // 清空
buffer.size; // 当前数量contextManager.ts — 上下文管理器
管理用户信息和设备信息的统一组件。
import { ContextManager } from '@evertro/monitor-core';
const ctx = new ContextManager();
// 设置用户信息
ctx.setUser({ userId: '100', isLogin: true, sessionId: 'xxx' });
// 更新设备信息
ctx.setDevice({ platform: 'weapp', screenWidth: 375, ... });
// 获取完整上下文
const context = ctx.getContext();
// { user: {...}, device: {...} }sampler.ts — 采样器
基于配置的采样率决定事件是否上报。
import { Sampler } from '@evertro/monitor-core';
const sampler = new Sampler(0.1); // 10% 采样率
sampler.shouldSample(event); // true / false
// 注意:P0 (IMMEDIATE) 事件跳过采样,始终 100% 上报deduplicate.ts — 去重器
使用 message + stack 前 3 帧 生成指纹,5 分钟窗口期内重复错误只上报 1 次。
import { Deduplicator, generateFingerprint } from '@evertro/monitor-core';
const dedup = new Deduplicator();
// 返回 0 表示首次出现,> 0 表示重复次数
const count = dedup.check('TypeError: xxx', 'at foo\nat bar');
// count === 0 → 应该上报
// count > 0 → 应该丢弃
dedup.clear(); // 清除所有指纹记录sanitize.ts — 数据脱敏
递归遍历对象,将包含敏感词的字段值替换为 ***。
import { sanitize, sanitizeUrl } from '@evertro/monitor-core';
// 对象脱敏
sanitize({ token: 'abc123', name: '张三' }, ['token', 'password']);
// { token: '***', name: '张三' }
// URL 参数脱敏
sanitizeUrl('https://api.com?token=abc&name=test', ['token']);
// 'https://api.com?token=***&name=test'generateId.ts — ID 生成器
import { generateId, generateShortId } from '@evertro/monitor-core';
generateId(); // 'a1b2c3d4-e5f6-7890-abcd-ef1234567890' (UUID v4)
generateShortId(); // 'a1b2c3d4' (8 位短 ID)依赖关系
@evertro/monitor-types → @evertro/monitor-core
↓
@evertro/monitor-transport
@evertro/monitor-miniapp
@evertro/monitor-web
@evertro/monitor-taro导出一览
export { EventHub } from './eventHub';
export { RingBuffer } from './ringBuffer';
export { ContextManager } from './contextManager';
export { Sampler } from './sampler';
export { sanitize, sanitizeUrl } from './sanitize';
export { generateId, generateShortId } from './generateId';
export { Deduplicator, generateFingerprint } from './deduplicate';
export { CollectorEngine } from './engine';
export { resolveEventId, resolveEventCode, enrichEventFields, toReportEvent } from './eventMapping';