API监控
简介
Web SDK 通过重写浏览器原生 fetch 与 XMLHttpRequest 对象,实现对 Web 页面网络请求的透明监控。无论业务代码直接使用 fetch、XMLHttpRequest,还是使用 axios 等基于 XHR/fetch 的请求库,通常都可以被 SDK 拦截并上报性能与错误数据。
API 监控仅在浏览器环境中生效。SSR/SSG 框架中的服务端请求不会被 Web SDK 捕获,服务端链路需要接入对应的服务端监控方案。
开启方式
import Aegis from 'bugly-web-sdk';
// 仅用于 API 监控 ignoreUrls 排除 SDK 自身上报请求,不需要作为 hostUrl.url 传入。
const BUGLY_PRO_REPORT_URL = 'https://pro.bugly.qq.com/collect/aegisV2Web';
const aegis = new Aegis({
id: '<bugly-app-id>',
appKey: '<bugly-app-key>',
buglyType: 'pro',
plugin: {
api: {
apiDetail: false,
reportWhenError: true,
ignoreUrls: [BUGLY_PRO_REPORT_URL],
},
},
});
建议把 SDK 自身上报地址加入 ignoreUrls,避免 SDK 上报请求被业务 API 监控重复记录。专业版主流程只需配置 buglyType: 'pro',SDK 会使用内置上报/白名单地址,一般用户不需要配置 hostUrl。
监控原理
1. 重写 fetch
SDK 初始化后会包装全局 fetch:
- 请求发起前记录请求开始时间、URL、method、请求参数和指定请求头;
- 请求完成后计算耗时,读取状态码、响应头、响应内容等信息;
- 根据配置判断是否采集详情、是否命中忽略规则、是否为异常请求;
- 网络错误、跨域、超时、手动 abort 等异常会进入错误上报逻辑。
2. 重写 XMLHttpRequest
对于 XHR 请求,SDK 会监听 readystatechange、loadend、error、timeout、abort 等事件,并在请求结束时统一计算耗时、读取状态码、提取返回内容和判断是否异常。
3. 上报内容
常见上报字段包括:
| 字段 | 说明 |
|---|---|
url | 请求地址,可通过 urlHandler 自定义格式 |
status | HTTP 状态码 |
method | 请求方法 |
duration | 请求耗时,单位 ms |
ret | 业务返回码,通常来自 retcode、code、ret、errcode 等字段或自定义处理结果 |
isErr | 是否为异常请求 |
param | 请求参数,仅在采集详情时上报 |
data | 响应内容,仅在采集详情时上报 |
reqHeaders / resHeaders | 指定采集的请求头/响应头 |
trace / span | 链路追踪相关标识,取决于 trace 配置 |
配置示例
new Aegis({
id: '<bugly-app-id>',
appKey: '<bugly-app-key>',
plugin: {
api: {
apiDetail: false,
reportWhenError: true,
reportAbort: false,
reqHeaders: ['x-request-id'],
resHeaders: ['content-type'],
retCodeHandler: (data, url) => {
try {
if (typeof data === 'string') data = JSON.parse(data);
} catch (e) {
return { isErr: true, code: 'parse_error' };
}
return {
isErr: data.code !== 0,
code: String(data.code),
};
},
urlHandler: (url) => url.split('?')[0],
ignoreUrls: ['https://pro.bugly.qq.com/collect/aegisV2Web'],
},
},
});
retCodeHandler
不同业务接口的返回结构不同,建议通过 retCodeHandler 明确业务错误判断逻辑。该函数需要返回:
{
isErr: boolean;
code: string;
}
示例:
new Aegis({
id: '<bugly-app-id>',
appKey: '<bugly-app-key>',
plugin: {
api: {
retCodeHandler(data, url) {
try {
if (typeof data === 'string') data = JSON.parse(data);
} catch (e) {
return { isErr: true, code: 'parse_error' };
}
const code = data?.body?.retCode ?? data?.code ?? data?.ret ?? data?.errcode;
return {
isErr: String(code) !== '0',
code: String(code ?? ''),
};
},
},
},
});
接口请求是否异常通常根据 isErr 判断,因此 retCodeHandler 的返回值非常重要。code 建议统一转为字符串,避免不同类型导致后台聚合口径不一致。
请求/响应详情与脱敏
apiDetail: true 会采集请求参数、响应内容等详情,有助于定位问题,但也可能包含敏感字段。开启前请确认采集范围,并使用 handler 做脱敏或裁剪。
使用 reqParamHandler / resBodyHandler 脱敏
new Aegis({
id: '<bugly-app-id>',
appKey: '<bugly-app-key>',
plugin: {
api: {
apiDetail: true,
reqParamHandler: (body, url) => {
const text = typeof body === 'string' ? body : JSON.stringify(body);
return text
.replace(/"password":"[^"]+"/g, '"password":"***"')
.replace(/"token":"[^"]+"/g, '"token":"***"');
},
resBodyHandler: (body, url, ctx) => {
try {
const data = JSON.parse(body);
delete data.token;
delete data.secret;
delete data.phone;
return JSON.stringify(data);
} catch (e) {
return body;
}
},
},
},
});
控制详情采集范围
如果只希望对特定接口采集详情,可以使用 apiDetailReportUrls;如果需要排除登录、鉴权、用户隐私相关接口,可以使用 apiDetailIgnoreUrls。
new Aegis({
id: '<bugly-app-id>',
appKey: '<bugly-app-key>',
plugin: {
api: {
apiDetail: true,
apiDetailReportUrls: [/\/api\/order\//],
apiDetailIgnoreUrls: [/\/api\/login/, /\/api\/user\/profile/],
},
},
});
trace header
如果业务链路需要前后端串联,可以配置 SDK 注入 trace header。支持的 header 类型以 SDK 类型定义为准,包括 traceparent、sw8、b3、sentry-trace。
new Aegis({
id: '<bugly-app-id>',
appKey: '<bugly-app-key>',
plugin: {
api: {
injectTraceHeader: 'traceparent',
injectTraceUrls: [/^https:\/\/api\.example\.com\//],
injectTraceIgnoreUrls: [/\/api\/public\//],
},
},
});
注意事项
- API 监控只覆盖浏览器内的
fetch与XMLHttpRequest请求,不覆盖 SSR 服务端请求、Node.js 后端请求或原生客户端请求。 - 如需采集响应头,后端需要通过
Access-Control-Expose-Headers暴露非 simple header。 - 建议使用
ignoreUrls排除 SDK 上报地址和其他不需要统计的内部请求。 - 开启
apiDetail前必须评估数据敏感性,并通过reqParamHandler、resBodyHandler或详情 URL 白/黑名单做脱敏与范围控制。 - 对于 SSE 等长连接场景,可结合
isSSE、isFirstSSEChunk等配置识别请求类型和首包信息。