# 小程序 SDK 配置参考

本文档介绍用户体验监控小程序 SDK 的全部配置项与 API。通过 `ArmsRum.init(config)` 传入 `IMiniappConfig` 对象完成 SDK 初始化。

下面按用途分组说明各配置项。

---

## SDK 基础配置

| 参数 | 类型 | 描述 | 是否必填 | 默认值 |
|------|------|------|----------|--------|
| `pid` | `string` | 应用 ID | 是 | — |
| `endpoint` | `string` | 数据上报地址 | 是 | — |
| `enable` | `boolean` | 是否启用 SDK，关闭后所有采集器与上报均不工作 | 否 | `true` |
| `env` | `'prod' \| 'gray' \| 'pre' \| 'daily' \| 'local'` | 应用环境标识 | 否 | `'prod'` |
| `version` | `string` | 应用版本号 | 否 | — |

> **说明** `endpoint` 为完整上报地址 URL，可在阿里云云监控控制台「用户体验监控 > 应用列表」创建应用后获取。

```typescript
import ArmsRum from '@arms/rum-miniapp';

ArmsRum.init({
  pid: '<your-pid>',
  endpoint: '<your-endpoint>',
  enable: true,
  env: 'prod',
  version: '1.0.0',
});
```

---

## user 配置

用户信息，便于在控制台按用户维度排查问题。

| 参数 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| `user.id` | `string` | 用户 ID（由 SDK 默认生成，不建议覆盖） | 自动生成 |
| `user.name` | `string` | 用户名称 | — |
| `user.tags` | `string` | 用户标签（逗号分隔） | — |

```typescript
ArmsRum.init({
  pid: '<your-pid>',
  endpoint: '<your-endpoint>',
  user: { name: '张三', tags: 'vip,enterprise' },
});
```

> **说明** 如需关联业务自有账号体系，建议使用 `user.name` 或 `user.tags`，强制覆盖 `user.id` 会影响 UV 计算。

---

## sessionConfig 配置

会话（Session）的采样与生命周期策略。

| 参数 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| `sampling` | `number` | 会话采样率（0~100，百分比） | `100` |
| `sampleRate` | `number` | **已废弃**：旧的会话采样率字段（0~1）；保留兼容，运行时自动转换。新接入请用 `sampling` | — |
| `maxDuration` | `number` | 会话最大持续时间（ms） | `86400000`（24h） |
| `overtime` | `number` | 会话无活动超时时间（ms） | `1800000`（30min） |
| `storage` | `'auto' \| 'localStorage' \| 'memory'` | 会话存储介质 | `'auto'` |

```typescript
ArmsRum.init({
  pid: '<your-pid>',
  endpoint: '<your-endpoint>',
  sessionConfig: {
    sampling: 50,                       // 50% 采样
    maxDuration: 86400000,             // 最长 24 小时
    overtime: 1800000,                 // 30 分钟无活动超时
  },
});
```

> 小程序本地缓存中存储了 `_arms_uid`（用户 ID）和 `_arms_session`（Session 信息：sessionId、sampled、startTime、lastTime）。

---

## reportConfig 配置

上报节奏配置。

| 参数 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| `flushTime` | `number` | 上报时间间隔（ms），取值范围 [0, 10000] | `3000` |
| `maxEventCount` | `number` | 单次上报最大事件数，取值范围 [1, 100] | `20` |

```typescript
ArmsRum.init({
  pid: '<your-pid>',
  endpoint: '<your-endpoint>',
  reportConfig: {
    flushTime: 0,            // 立即上报
    maxEventCount: 50,       // 一次最多上报 50 条
  },
});
```

---

## remoteConfig 配置

远程配置动态管控。也可直接传 `remoteConfig: true` 开启默认远程配置。

| 参数 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| `enable` | `boolean` | 是否启用远程配置 | `false` |
| `url` | `string` | 配置服务器 URL；未指定时 SDK 从 `endpoint` / `pid` 自动推导 | — |
| `mode` | `'launch-first' \| 'remote-first'` | `launch-first` 先用本地配置启动，异步拉取远端；`remote-first` 阻塞等待云端配置 | `'launch-first'` |
| `cacheTimeout` | `number` | 本地配置缓存有效期（ms） | `3600000`（1h） |
| `region` | `string` | 远程配置拉取地域 | `'cn-hangzhou'` |

```typescript
ArmsRum.init({
  pid: '<your-pid>',
  endpoint: '<your-endpoint>',
  remoteConfig: {
    enable: true,
    mode: 'launch-first',
    region: 'cn-hangzhou',
  },
});
```

> SDK 获取远程配置后会缓存到本地存储，下次启动时优先使用本地缓存配置。需 SDK 版本 >= 0.0.37。

---

## collectors 配置（采集器）

各采集器的启用/禁用开关。每个采集器支持 `boolean` 或对象细化配置。

| 采集器 | 类型 | 描述 | 默认值 |
|--------|------|------|--------|
| `api` | `boolean \| IApiCollectorConfig` | API 请求监控（含 SSE） | `true` |
| `jsError` | `boolean \| ICollectorConfig` | 未捕获异常 + 未处理 Promise 拒绝 | `true` |
| `consoleError` | `boolean \| ICollectorConfig` | `console.error` 拦截上报 | `true` |
| `action` | `boolean \| ICollectorConfig` | 用户行为（tap 事件） | `true` |
| `longTask` | `boolean \| ICollectorConfig` | 页面卡顿（setData 渲染阻塞） | `true` |
| `perf` | `boolean \| ICollectorConfig` | 页面性能指标 | `true` |

```typescript
ArmsRum.init({
  pid: '<your-pid>',
  endpoint: '<your-endpoint>',
  collectors: {
    action: false,          // 关闭用户行为采集
    longTask: false,        // 关闭卡顿监控
    consoleError: false,    // 关闭 console.error 拦截
    api: {
      enable: true,
      filters: [/\.internal\.example\.com/],
      sse: { timeout: 30000 },
    },
  },
});
```

### api 采集器细化配置

`api` 采集器统一管理小程序 `request` / `httpRequest` 的所有网络请求。除通用字段外，还支持 SSE 子配置：

| 字段 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| `enable` | `boolean` | 是否启用 API 采集 | `true` |
| `filters` | `MatchOption[]` | 过滤规则；URL 命中即跳过采集 | — |
| `sse` | `ISseCollectorConfig` | SSE 流式接口配置（仅微信小程序支持） | — |
| `sse.enabled` | `boolean` | 是否启用 SSE 监控 | `true` |
| `sse.timeout` | `number` | SSE 流活动超时时间（ms），每次收到数据重置 | `60000` |

> **SSE 平台支持**：仅微信小程序（基础库 >= 2.20.2）通过 `enableChunked` 原生支持 SSE 流式监控。其他平台自动静默降级为普通 API 监控。

---

## longTaskConfig 配置（卡顿监控）

卡顿监控的上报限制与判定阈值。

| 参数 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| `maxEventCount` | `number` | 单次 PV 内最大上报卡顿次数，取值范围 [1, 5] | `5` |
| `renderThreshold` | `number` | setData 卡顿判定阈值（ms），最小值 50 | `50` |

```typescript
ArmsRum.init({
  pid: '<your-pid>',
  endpoint: '<your-endpoint>',
  longTaskConfig: {
    maxEventCount: 4,
    renderThreshold: 100,    // setData 耗时超过 100ms 视作卡顿
  },
});
```

> 卡顿监控依赖 `setUpdatePerformanceListener` API，部分低版本基础库不支持时 SDK 自动跳过。

---

## tracing 配置

分布式链路追踪。支持 `boolean` 快速开关或 `ITracingOption` 对象。SDK 在 outbound 请求上自动注入追踪头。

| 参数 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| `enable` | `boolean` | 是否启用链路追踪 | `false` |
| `sample` | `number` | 采样率（0~100，百分比） | `100` |
| `propagatorTypes` | `Array<'tracecontext' \| 'b3' \| 'b3multi' \| 'jaeger' \| 'sw8'>` | 传播协议 | `['tracecontext']` |
| `allowedUrls` | `Array<MatchOption \| TraceOption>` | 允许注入追踪头的 URL/path 规则；未配置时不会注入 | `[]` |
| `tracestate` | `boolean` | 是否携带 W3C tracestate | `true` |
| `baggage` | `boolean` | 是否携带 W3C baggage | `false` |

`TraceOption`：`{ match: MatchOption; sampling?: number; propagatorTypes?: PropagatorType[]; tracestate?: boolean; baggage?: boolean }`，可对单条 URL 覆盖全局策略。

```typescript
ArmsRum.init({
  pid: '<your-pid>',
  endpoint: '<your-endpoint>',
  tracing: {
    enable: true,
    sample: 50,
    propagatorTypes: ['tracecontext', 'b3'],
    allowedUrls: [
      'https://api.example.com',
      /\/api\/v\d+\//,
      { match: 'https://payment.example.com', sampling: 100 },
    ],
    tracestate: true,
  },
});
```

> **`sw8` 排他性** `propagatorTypes` 包含 `'sw8'` 时只使用 sw8 单一协议（SkyWalking 标准要求）。

---

## filters 配置（事件级过滤）

事件级过滤规则，命中后该事件不上报。与 `collectors.api.filters`（采集器级，命中即不采）互补。

| 参数 | 类型 | 描述 |
|------|------|------|
| `resource` | `MatchOption \| MatchOption[]` | 资源事件（API / 静态资源），按 URL 匹配 |
| `exception` | `MatchOption \| MatchOption[]` | 异常事件，按 error.name / message / stack 匹配 |

`MatchOption` 支持三种形式：
- `string`：URL/path 前缀匹配
- `RegExp`：正则匹配
- `(value: string) => boolean`：自定义函数

```typescript
ArmsRum.init({
  pid: '<your-pid>',
  endpoint: '<your-endpoint>',
  filters: {
    exception: [
      'Test error',
      /^Script error\.?$/,
      (msg) => msg.includes('example-error'),
    ],
    resource: [
      'https://example.com/',
      /localhost/i,
    ],
  },
});
```

---

## 小程序专属配置

| 参数 | 类型 | 描述 | 默认值 |
|------|------|------|--------|
| `parseViewName` | `(url: string) => string` | 自定义页面 name 解析（入参为当前页面路由） | — |
| `parseResourceName` | `(url: string) => string` | 自定义资源 name 解析（入参为请求 URL） | — |
| `evaluateApi` | `(options, response, error?) => Promise<IApiBaseAttr>` | 自定义 API 事件解析回调 | — |
| `beforeReport` | `(bundle) => any` | 上报前回调，可修改或阻止数据上报 | — |
| `properties` | `Record<string, number \| string>` | 全局自定义属性，附加到所有上报事件 | — |

### evaluateApi：自定义 payload 写入 snapshots

`evaluateApi` 用于把请求/响应内容写入事件。**SDK 不自动采集 payload**——业务侧按需提取并通过返回的 `snapshots` 字段上报，SDK 自动裁剪至 5KB。

回调入参：

| 参数 | 类型 | 描述 |
|------|------|------|
| `options` | `Object` | 请求参数（url、headers、data 等） |
| `response` | `Object` | 请求响应体 |
| `error` | `Error \| undefined` | 仅请求失败时传入 |

返回值结构（`IApiBaseAttr`）：

| 字段 | 类型 | 说明 |
|------|------|------|
| `name` | `string` | API 名称（优先级高于 `parseResourceName`），最大 1000 字符 |
| `message` | `string` | API 信息描述，最大 1000 字符 |
| `success` | `0 \| 1` | 业务成功/失败标记 |
| `duration` | `number` | 覆盖 SDK 推导的耗时（ms） |
| `status_code` | `number \| string` | 覆盖 SDK 推导的状态码 |
| `snapshots` | `string` | 写入 `event.snapshots`；自动经 5KB 裁剪 |
| `properties` | `Record<string, number \| string>` | 写入 `event.properties`；保留给用户业务标签 |

```typescript
ArmsRum.init({
  pid: '<your-pid>',
  endpoint: '<your-endpoint>',
  evaluateApi: async (options, response, error) => {
    const respText = JSON.stringify(response);
    return {
      success: error ? 0 : 1,
      snapshots: JSON.stringify({
        params: options.data,
        response: respText.substring(0, 2000),
      }),
    };
  },
});
```

> **超时与错误处理** 回调抛错时 SDK 静默捕获，回退到原始事件（不会阻塞上报）。

---

## 其他配置

RUM SDK 支持配置基于设备和网络等的公共属性，主动配置优先级高于自动解析。

| 参数 | 类型 | 描述 |
|------|------|------|
| `device` | `Object` | 设备信息 |
| `os` | `Object` | 系统、容器信息 |
| `geo` | `Object` | 行政地理信息 |
| `isp` | `Object` | 运营商信息 |
| `net` | `Object` | 网络信息（SDK 自动监听网络类型变化） |

```typescript
ArmsRum.init({
  pid: '<your-pid>',
  endpoint: '<your-endpoint>',
  geo: {
    country: 'China',
    city: 'Hangzhou',
  },
});
```

---

## properties 配置

全局自定义属性，对所有上报事件生效。

| 参数 | 类型 | 描述 |
|------|------|------|
| `[key: string]` | `string \| number` | key 最大 50 字符；value 为 string 时最大 2000 字符。不符合要求的键值对会被移除 |

- 全局 `properties` 与事件级 `properties` 存储时会合并，事件级优先
- 合并后键值对数量不可超过 20 对

```typescript
ArmsRum.init({
  pid: '<your-pid>',
  endpoint: '<your-endpoint>',
  properties: {
    department: 'engineering',
    region: 'cn-hangzhou',
  },
});
```

---

## SDK API

### `ArmsRum.init(config)`

初始化 SDK。返回 `Promise`，可链式处理初始化完成事件。

```typescript
import ArmsRum from '@arms/rum-miniapp';

ArmsRum.init({
  pid: '<your-pid>',
  endpoint: '<your-endpoint>',
  env: 'prod',
  version: '1.0.0',
});
```

---

### `ArmsRum.getConfig()`

获取当前 SDK 配置（合并远程配置后的最终态）。

```typescript
const config = ArmsRum.getConfig();
console.log(config?.endpoint, config?.env);
```

---

### `ArmsRum.setConfig()`

动态修改 SDK 配置，支持两种调用方式。

```typescript
// 指定 key 设置
ArmsRum.setConfig('env', 'pre');

// 覆盖设置
const config = ArmsRum.getConfig();
ArmsRum.setConfig({
  ...config,
  version: '2.0.0',
  env: 'pre',
});
```

> 修改后采集器立即按新配置工作；已上报的事件不受影响。

---

### `ArmsRum.getCollector(name)`

获取某个内置采集器实例，用于扩展或调试。

可选 `name` 值：

| 采集器名 | 说明 |
|----------|------|
| `'pv-collector'` | 页面 PV / 路由切换 |
| `'perf-collector'` | 页面性能 |
| `'exception-collector'` | JS 异常 |
| `'api-collector'` | API 请求（含 SSE） |
| `'action-collector'` | 用户行为 |
| `'render-block-collector'` | 卡顿监控 |

---

### `ArmsRum.sendCustom(event)`

上报自定义数据，必须包含 `type` 和 `name` 两个属性。

| 参数 | 类型 | 描述 | 是否必填 |
|------|------|------|----------|
| `type` | `string` | 类型 | 是 |
| `name` | `string` | 名称 | 是 |
| `group` | `string` | 分组 | 否 |
| `value` | `number` | 值 | 否 |
| `properties` | `object` | 自定义属性 | 否 |

```typescript
ArmsRum.sendCustom({
  type: 'CustomEventType',
  name: 'order-submit',
  group: 'business',
  value: 99.9,
  properties: { orderId: '12345' },
});
```

---

### `ArmsRum.sendException(event)`

上报自定义异常数据，必须包含 `name` 和 `message` 两个属性。

| 参数 | 类型 | 描述 | 是否必填 |
|------|------|------|----------|
| `name` | `string` | 异常名称 | 是 |
| `message` | `string` | 异常信息 | 是 |
| `file` | `string` | 异常发生文件 | 否 |
| `stack` | `string` | 异常堆栈信息 | 否 |
| `line` | `number` | 异常发生行数 | 否 |
| `column` | `number` | 异常发生列数 | 否 |
| `properties` | `object` | 自定义属性 | 否 |

```typescript
ArmsRum.sendException({
  name: 'BusinessError',
  message: 'Payment failed',
  stack: 'Error: Payment failed\n    at ...',
  properties: { userId: 'u_123' },
});
```

---

### `ArmsRum.sendResource(event)`

上报自定义资源，必须包含 `name`、`type` 和 `duration` 三个属性。

| 参数 | 类型 | 描述 | 是否必填 |
|------|------|------|----------|
| `name` | `string` | 资源名 | 是 |
| `type` | `string` | 资源类型（如 `api`、`script`、`image`） | 是 |
| `duration` | `number` | 请求耗时（ms） | 是 |
| `success` | `number` | 请求状态：1 成功 / 0 失败 / -1 未知 | 否 |
| `method` | `string` | 请求方法 | 否 |
| `status_code` | `number \| string` | 请求状态码 | 否 |
| `message` | `string` | 请求消息 | 否 |
| `url` | `string` | 请求地址 | 否 |
| `trace_id` | `string` | 链路追踪 ID | 否 |
| `properties` | `object` | 自定义属性 | 否 |

```typescript
ArmsRum.sendResource({
  name: 'getListByPage',
  type: 'api',
  duration: 800,
  url: 'https://api.example.com/list',
  success: 1,
  properties: { page: '1' },
});
```
