关于 sentry-react-native-sdk
扫描 React Native 和 Expo 项目并指导配置 Sentry SDK 的技能,涵盖监控、追踪、回放、性能分析和日志,并按项目类型提供配置路径。
主要功能
- 01识别 React Native 和 Expo 配置
- 02推荐 Sentry 可观测性功能
- 03指导使用向导安装
- 04提供 Expo 与裸 React Native 配置步骤
- 05配置错误监控与追踪
- 06验证 SDK 配置
适用场景
- 01为 Expo 应用添加 Sentry
- 02在裸 React Native 项目中配置 Sentry
- 03启用移动端崩溃与性能监控
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ getsentry/ sentry-for-ai --skill sentry-react-native-sdk安装后在 Claude Code 中输入/sentry-react-native-sdk确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/error-monitoring.mdexpo-config-plugin.mdlogging.mdprofiling.mdsession-replay.mdtracing.mduser-feedback.md详细介绍
Sentry React Native SDK
一款主见鲜明的向导,可扫描你的 React Native 或 Expo 项目,并指导你完成完整的 Sentry 设置——错误监控、追踪、性能分析、会话回放、日志记录等。
在以下情况下调用此技能
- 用户要求“将 Sentry 添加到 React Native”或在 RN 或 Expo 应用中“设置 Sentry”
- 用户希望在 React Native 中进行错误监控、追踪、性能分析、会话回放或日志记录
- 用户提到
@sentry/react-native、移动端错误跟踪或 Expo 的 Sentry - 用户希望监控 iOS/Android 上的原生崩溃、ANR 或应用卡顿
注意: 以下 SDK 版本和 API 反映了撰写本文时 Sentry 文档中的最新信息(
@sentry/react-native≥6.0.0,建议的最低版本为 ≥8.0.0)。 实施前,请务必对照 docs.sentry.io/platforms/react-native/ 进行核实。
阶段 1:检测
在提出任何建议前,运行以下命令以了解项目:
# Detect project type and existing Sentry
cat package.json | grep -E '"(react-native|expo|@expo|@sentry/react-native|sentry-expo)"'
# Distinguish Expo managed vs bare vs vanilla RN
ls app.json app.config.js app.config.ts 2>/dev/null
cat app.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print('Expo managed' if 'expo' in d else 'Bare/Vanilla')" 2>/dev/null
# Check Expo SDK version (important: Expo SDK 50+ required for @sentry/react-native)
cat package.json | grep '"expo"'
# Detect navigation library
grep -E '"(@react-navigation/native|react-native-navigation)"' package.json
# Detect state management (Redux → breadcrumb integration available)
grep -E '"(redux|@reduxjs/toolkit|zustand|mobx)"' package.json
# Check for existing Sentry initialization
grep -r "Sentry.init" src/ app/ App.tsx App.js _layout.tsx 2>/dev/null | head -5
# Detect Hermes (affects source map handling)
cat android/app/build.gradle 2>/dev/null | grep -i hermes
cat ios/Podfile 2>/dev/null | grep -i hermes
# Detect Expo Router
ls app/_layout.tsx app/_layout.js 2>/dev/null
# Detect backend for cross-link
ls backend/ server/ api/ 2>/dev/null
find . -maxdepth 3 \( -name "go.mod" -o -name "requirements.txt" -o -name "Gemfile" -o -name "package.json" \) 2>/dev/null | grep -v node_modules | head -10
需要确认的事项:
| 问题 | 影响 |
|---|---|
package.json 中是否有 expo? | Expo 路径(配置插件 + getSentryExpoConfig)还是裸项目/纯 RN 路径 |
| Expo SDK 是否 ≥50? | 直接使用 @sentry/react-native;更旧版本使用 sentry-expo(旧版,不要使用) |
app.json 是否有 "expo" 键? | Expo 托管项目——向导是最简单的方式;配置插件会处理所有原生配置 |
是否存在 app/_layout.tsx? | Expo Router 项目——在 _layout.tsx 中进行初始化 |
package.json 中是否已有 @sentry/react-native? | 跳过安装,直接进入功能配置 |
是否存在 @react-navigation/native? | 建议使用 reactNavigationIntegration 跟踪屏幕 |
是否存在 react-native-navigation? | 建议使用 reactNativeNavigationIntegration(Wix) |
| 是否检测到后端目录? | 触发跨链接阶段 4 |
阶段 2:推荐
根据发现的情况,提出具体建议。不要提出开放式问题——直接给出方案:
推荐(核心覆盖——始终设置以下功能):
- ✅ 错误监控 — 捕获 JS 异常、原生崩溃(iOS + Android)、ANR 和应用卡顿
- ✅ 追踪 — 移动端性能至关重要;自动检测导航、应用启动和网络请求
- ✅ 会话回放 — 移动端回放会捕获屏幕截图和触控事件,帮助调试用户问题
可选(增强可观测性):
- ⚡ 性能分析 — 在 iOS 上进行 CPU 性能分析(JS 性能分析支持跨平台);在生产环境中开销低
- ⚡ 日志记录 — 通过
Sentry.logger.*记录结构化日志;关联追踪以提供完整上下文 - ⚡ 用户反馈 — 直接从应用收集用户提交的错误报告
推荐逻辑:
| 功能 | 推荐时机…… |
|---|---|
| 错误监控 | 始终——任何移动应用都不可或缺的基础功能 |
| 追踪 | 移动端始终推荐——应用启动、导航和网络延迟都很重要 |
| 会话回放 | 面向用户的生产应用;通过可视化方式调试用户反馈的问题 |
| 性能分析 | 对性能敏感的屏幕、关注启动时间,或调查生产环境性能问题 |
| 日志记录 | 应用使用结构化日志,或希望在 Sentry 中关联日志与追踪 |
| 用户反馈 | 希望用户提交错误报告的 Beta 版或面向客户的应用 |
建议:“对于你的 [Expo 托管 / 裸 RN] 应用,我建议设置错误监控 + 追踪 + 会话回放。还需要我添加性能分析和日志记录吗?”
阶段 3:引导
确定你的设置路径
| 项目类型 | 推荐设置方式 | 复杂度 |
|---|---|---|
| Expo 托管模式(SDK 50+) | 使用向导 CLI,或手动配置并使用配置插件 | 低 — 向导会完成所有操作 |
| Expo 裸机模式(SDK 50+) | 推荐使用向导 CLI | 中 — 处理 iOS/Android 配置 |
| 原生 React Native(0.69+) | 推荐使用向导 CLI | 中 — 处理 Xcode + Gradle |
| Expo SDK <50 | 使用 sentry-expo(旧版) | 请参阅旧版文档 |
路径 A:向导 CLI(推荐用于所有项目类型)
你需要自行运行此命令 — 向导会打开浏览器以供登录,并要求进行 Agent 无法处理的交互式输入。请复制并粘贴到终端:
npx @sentry/wizard@latest -i reactNative它会处理登录、组织/项目选择、SDK 安装、原生配置、源映射上传和
Sentry.init()。以下是它会创建或修改的内容:
文件 操作 用途 package.json安装 @sentry/react-native核心 SDK metro.config.js添加 @sentry/react-native/metro序列化器生成源映射 app.json添加 @sentry/react-native/expo插件(仅限 Expo)原生构建的配置插件 App.tsx/_layout.tsx添加 Sentry.init()和Sentry.wrap()SDK 初始化 ios/sentry.properties存储组织/项目/令牌 iOS 源映射和 dSYM 上传 android/sentry.properties存储组织/项目/令牌 Android 源映射上传 android/app/build.gradle添加 Sentry Gradle 插件 Android 源映射和 proguard ios/[AppName].xcodeproj包装 “Bundle RN” 构建阶段并添加 dSYM 上传 iOS 符号上传 .env.localSENTRY_AUTH_TOKEN身份验证令牌(添加到 .gitignore)完成后,返回此处并跳转到验证。
如果用户跳过向导,请根据其项目类型,继续执行下面的路径 B 或 C(手动设置)。
路径 B:手动配置 — Expo Managed(SDK 50+)
第 1 步 — 安装
npx expo install @sentry/react-native
第 2 步 — metro.config.js
const { getSentryExpoConfig } = require("@sentry/react-native/metro");
const config = getSentryExpoConfig(__dirname, {
// Auto-wrap Expo Router ErrorBoundary exports at build time (SDK ≥8.17.0)
autoWrapExpoRouterErrorBoundary: true,
});
module.exports = config;
如果尚不存在 metro.config.js:
npx expo customize metro.config.js
# Then replace contents with the above
Metro 配置选项:
| 选项 | 类型 | 默认值 | 用途 |
|---|---|---|---|
autoWrapExpoRouterErrorBoundary | boolean | false | 在构建时自动用 Sentry 包装 export { ErrorBoundary } from 'expo-router'(SDK ≥8.17.0)。捕获进入各路由 ErrorBoundary 的错误,无需手动包装 |
annotateReactComponents | boolean | false | 注入组件名称,以提供更丰富的错误上下文 |
includeWebReplay | boolean | true | 包含 Web 回放包(仅限原生应用时设为 false) |
includeWebFeedback | boolean | true | 包含 Web 反馈包(仅限原生应用时设为 false) |
enableSourceContextInDevelopment | boolean | true | 在开发构建中启用源码上下文 |
第 3 步 — app.json — 添加 Expo 配置插件
{
"expo": {
"plugins": [
[
"@sentry/react-native/expo",
{
"url": "https://sentry.io/",
"project": "YOUR_PROJECT_SLUG",
"organization": "YOUR_ORG_SLUG",
"disableAutoUpload": false
}
]
]
}
}
注意: 将
SENTRY_AUTH_TOKEN设置为原生构建的环境变量,切勿将其提交到版本控制中。
插件选项:
| 选项 | 类型 | 默认值 | 用途 |
|---|---|---|---|
url | string | "https://sentry.io/" | Sentry 实例 URL |
project | string | — | 项目 slug |
organization | string | — | 组织 slug |
disableAutoUpload | boolean | false | 本地构建时跳过 source map 和 dSYM 上传(SDK ≥8.13.0) |
第 4 步 — 初始化 Sentry
对于 Expo Router(app/_layout.tsx):
import { Stack } from "expo-router";
import { isRunningInExpoGo } from "expo";
import * as Sentry from "@sentry/react-native";
Sentry.init({
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN ?? "YOUR_SENTRY_DSN",
sendDefaultPii: true,
// Tracing
tracesSampleRate: 1.0, // lower to 0.1–0.2 in production
// Profiling
profilesSampleRate: 1.0,
// Session Replay
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
// Logging (SDK ≥7.0.0)
enableLogs: true,
// Session Replay
integrations: [
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: !isRunningInExpoGo(), // slow/frozen frames
environment: __DEV__ ? "development" : "production",
});
function RootLayout() {
return <Stack />;
}
export default Sentry.wrap(RootLayout);
注意: Expo Router 会自动处理导航跟踪。Expo Router 项目无需使用
Sentry.NavigationContainer包装器,导航 span 会自动捕获。
Expo Router ErrorBoundary 设置(SDK ≥8.16.0)
默认情况下,Expo Router 的各路由 ErrorBoundary 会吞掉渲染错误,除非显式捕获,否则 Sentry 无法检测到这些错误。可选以下两种方式:
-
自动包装(推荐,SDK ≥8.17.0) — 在
metro.config.js中启用autoWrapExpoRouterErrorBoundary: true(如上所示)。Babel 插件会自动重写所有路由文件中的export { ErrorBoundary } from 'expo-router'。 -
手动包装 — 在每个路由文件中自行包装边界:
// app/_layout.tsx (or any route file) import { ErrorBoundary as ExpoErrorBoundary } from 'expo-router'; import * as Sentry from '@sentry/react-native'; export const ErrorBoundary = Sentry.wrapExpoRouterErrorBoundary(ExpoErrorBoundary);
这两种方式都会捕获进入边界的错误,并附带路由上下文(route.name、route.path、route.params),将当前导航 span 标记为错误,并生成一条面包屑。具体路径和参数会遵循 sendDefaultPii 的设置。
对于 标准 Expo(App.tsx):
import { isRunningInExpoGo } from "expo";
import * as Sentry from "@sentry/react-native";
Sentry.init({
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN ?? "YOUR_SENTRY_DSN",
sendDefaultPii: true,
tracesSampleRate: 1.0,
profilesSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
enableLogs: true,
integrations: [
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: !isRunningInExpoGo(),
environment: __DEV__ ? "development" : "production",
});
function App() {
return (
<Sentry.NavigationContainer>
{/* your navigation here */}
</Sentry.NavigationContainer>
);
}
export default Sentry.wrap(App);
路径 C:手动配置 — Bare React Native(0.69+)
第 1 步 — 安装
npm install @sentry/react-native --save
cd ios && pod install
第 2 步 — metro.config.js
const { getDefaultConfig } = require("@react-native/metro-config");
const { withSentryConfig } = require("@sentry/react-native/metro");
const config = getDefaultConfig(__dirname);
module.exports = withSentryConfig(config, {
// Set to false to exclude @sentry-internal/replay from the native bundle (web only).
// includeWebReplay: true,
// Set to false to exclude @sentry-internal/feedback from the native bundle (web only).
// includeWebFeedback: true,
// Auto-wrap Expo Router ErrorBoundary exports at build time (SDK ≥8.17.0, Expo Router only)
// autoWrapExpoRouterErrorBoundary: true,
});
第 3 步 — iOS:修改 Xcode 构建阶段
在 Xcode 中打开 ios/[AppName].xcodeproj。找到 “Bundle React Native code and images” 构建阶段,并将脚本内容替换为:
# RN 0.81.1+
set -e
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
SENTRY_XCODE="../node_modules/@sentry/react-native/scripts/sentry-xcode.sh"
/bin/sh -c "$WITH_ENVIRONMENT $SENTRY_XCODE"
第 4 步 — iOS:添加 “Upload Debug Symbols to Sentry” 构建阶段
在 Xcode 中添加新的 Run Script 构建阶段(位于 bundle 阶段之后):
/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh
第 5 步 — iOS:ios/sentry.properties
defaults.url=https://sentry.io/
defaults.org=YOUR_ORG_SLUG
defaults.project=YOUR_PROJECT_SLUG
auth.token=YOUR_ORG_AUTH_TOKEN
第 6 步 — Android:android/app/build.gradle
在 android {} 块之前添加:
apply from: "../../node_modules/@sentry/react-native/sentry.gradle.kts"
注意: SDK ≥8.13.0 使用
sentry.gradle.kts(Kotlin DSL)。较旧的 SDK 使用sentry.gradle(Groovy)。两者均向后兼容。
第 7 步 — Android:android/sentry.properties
defaults.url=https://sentry.io/
defaults.org=YOUR_ORG_SLUG
defaults.project=YOUR_PROJECT_SLUG
auth.token=YOUR_ORG_AUTH_TOKEN
第 8 步 — 初始化 Sentry(App.tsx 或入口文件)
import * as Sentry from "@sentry/react-native";
Sentry.init({
dsn: "YOUR_SENTRY_DSN",
sendDefaultPii: true,
tracesSampleRate: 1.0,
profilesSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
enableLogs: true,
integrations: [
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: true,
environment: __DEV__ ? "development" : "production",
});
function App() {
return (
<Sentry.NavigationContainer>
{/* your navigation here */}
</Sentry.NavigationContainer>
);
}
export default Sentry.wrap(App);
快速参考:功能完整的 Sentry.init()
以下是推荐的起始配置,启用了所有功能:
import * as Sentry from "@sentry/react-native";
Sentry.init({
dsn: "YOUR_SENTRY_DSN",
sendDefaultPii: true,
// Tracing — lower to 0.1–0.2 in high-traffic production
tracesSampleRate: 1.0,
// Profiling — runs on a subset of traced transactions
profilesSampleRate: 1.0,
// Session Replay — always capture on error, sample 10% of all sessions
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
// Logging — enable Sentry.logger.* API
enableLogs: true,
// Integrations — mobile replay is opt-in
integrations: [
Sentry.mobileReplayIntegration({
maskAllText: true, // masks text by default for privacy
maskAllImages: true,
}),
],
// Native frames tracking (disable in Expo Go)
enableNativeFramesTracking: true,
// Environment
environment: __DEV__ ? "development" : "production",
// Release — set from CI or build system
// release: "[email protected]+1",
// dist: "1",
});
// REQUIRED: Wrap root component to capture React render errors
export default Sentry.wrap(App);
应用启动准确性 — Sentry.appLoaded()(SDK ≥8.x)
如果应用在根组件挂载后还要执行大量异步操作(例如获取配置、等待身份验证),请在这些操作完成后调用 Sentry.appLoaded()。这会向 Sentry 表明应用启动确实已结束,从而更准确地测量应用启动时长。
// Call after async initialization is complete, e.g., in a useEffect or after a loading screen:
useEffect(() => {
fetchConfig().then(() => {
Sentry.appLoaded(); // marks the end of the app startup phase
});
}, []);
如果不调用 Sentry.appLoaded(),SDK 会自动估算应用启动结束时间。
导航设置 — React Navigation(v5+)
推荐:使用 Sentry.NavigationContainer 包装器(SDK ≥8.13.0)
可直接替换 NavigationContainer,自动接入导航跟踪:
import * as Sentry from "@sentry/react-native";
// Replace NavigationContainer with Sentry.NavigationContainer
<Sentry.NavigationContainer>
<Stack.Navigator>
{/* your screens */}
</Stack.Navigator>
</Sentry.NavigationContainer>
就是这么简单!该包装器会自动:
- 创建
reactNavigationIntegration - 注册导航容器引用
- 捕获导航事件的面包屑(SDK ≥8.13.0)
- 跟踪每个屏幕的初始显示时间(TTID)
替代方案:手动设置(适用于 SDK <8.13.0 或自定义配置)
import { reactNavigationIntegration } from "@sentry/react-native";
import { NavigationContainer, createNavigationContainerRef } from "@react-navigation/native";
const navigationIntegration = reactNavigationIntegration({
enableTimeToInitialDisplay: true, // track TTID per screen
routeChangeTimeoutMs: 1_000, // max wait for route change to settle
ignoreEmptyBackNavigationTransactions: true,
});
// Add to Sentry.init integrations array
Sentry.init({
integrations: [navigationIntegration],
// ...
});
// In your component:
const navigationRef = createNavigationContainerRef();
<NavigationContainer
ref={navigationRef}
onReady={() => {
navigationIntegration.registerNavigationContainer(navigationRef);
}}
>
导航设置 — Wix React Native Navigation
import * as Sentry from "@sentry/react-native";
import { Navigation } from "react-native-navigation";
Sentry.init({
integrations: [Sentry.reactNativeNavigationIntegration({ navigation: Navigation })],
// ...
});
包装根组件
务必包装根组件,以启用 React 错误边界,并确保捕获组件树级别的崩溃:
export default Sentry.wrap(App);
针对每项商定的功能
逐项处理功能。为每项功能加载参考文件,按其中的步骤操作,然后在继续之前验证结果:
| 功能 | 参考文件 | 在以下情况下加载…… |
|---|---|---|
| 错误监控 | ${SKILL_ROOT}/references/error-monitoring.md | 始终加载(基线配置) |
| 跟踪与性能 | ${SKILL_ROOT}/references/tracing.md | 移动应用始终加载(应用启动、导航、网络) |
| 性能分析 | ${SKILL_ROOT}/references/profiling.md | 对性能敏感的生产应用 |
| 会话回放 | ${SKILL_ROOT}/references/session-replay.md | 面向用户的应用 |
| 日志记录 | ${SKILL_ROOT}/references/logging.md | 需要结构化日志或日志与跟踪关联时 |
| 用户反馈 | ${SKILL_ROOT}/references/user-feedback.md | 收集用户提交的报告时 |
| Expo 配置插件 | ${SKILL_ROOT}/references/expo-config-plugin.md | 配置 @sentry/react-native/expo 插件时 |
针对每项功能:Read ${SKILL_ROOT}/references/<feature>.md,严格按照步骤操作,并验证其是否有效。
配置参考
核心 Sentry.init() 选项
| 选项 | 类型 | 默认值 | 用途 |
|---|---|---|---|
dsn | string | — | 必填。 项目 DSN;为空时 SDK 将被禁用。环境变量:SENTRY_DSN |
environment | string | — | 例如 "production"、"staging"。环境变量:SENTRY_ENVIRONMENT |
release | string | — | 应用版本,例如 "[email protected]+42"。环境变量:SENTRY_RELEASE |
dist | string | — | 构建编号 / 变体标识符(最多 64 个字符)。环境变量:SENTRY_DIST |
sendDefaultPii | boolean | false | 包含个人身份信息(PII):IP 地址、Cookie、用户数据 |
sampleRate | number | 1.0 | 错误事件采样率(0.0–1.0) |
maxBreadcrumbs | number | 100 | 每个事件的面包屑上限 |
attachStacktrace | boolean | true | 自动将堆栈跟踪附加到消息中 |
attachScreenshot | boolean | false | 出错时截取屏幕截图(SDK ≥4.11.0) |
screenshot | object | — | 精细控制屏幕截图遮罩;仅当 attachScreenshot: true 时生效。请参阅下方的 屏幕截图遮罩选项 |
attachViewHierarchy | boolean | false | 将 JSON 视图层级作为附件附加 |
debug | boolean | false | 输出详细的 SDK 日志。切勿在生产环境中使用 |
enabled | boolean | true | 完全禁用 SDK(例如用于测试) |
ignoreErrors | string[] | RegExp[] | — | 丢弃与这些模式匹配的错误 |
ignoreTransactions | string[] | RegExp[] | — | 丢弃与这些模式匹配的事务 |
maxCacheItems | number | 30 | 离线缓存信封的数量上限 |
defaultIntegrations | boolean | true | 设置为 false 可禁用所有默认集成 |
integrations | array | function | — | 添加或筛选集成 |
屏幕截图遮罩选项
当 attachScreenshot: true 时,将这些选项作为 screenshot 键传入 Sentry.init():
Sentry.init({
attachScreenshot: true,
screenshot: {
maskAllText: true, // default: true — mask all text nodes
maskAllImages: true, // default: true — mask all images
maskedViewClasses: ['com.mapbox.maps.MapView'], // always mask these native view classes
unmaskedViewClasses: ['com.example.SafeView'], // always show these native view classes
},
});
| 子选项 | 类型 | 默认值 | 用途 |
|---|---|---|---|
maskAllText | boolean | true | 遮罩屏幕截图中的所有文本节点 |
maskAllImages | boolean | true | 遮罩屏幕截图中的所有图像 |
maskedViewClasses | string[] | [] | 始终遮罩的原生视图类名(Android/iOS) |
unmaskedViewClasses | string[] | [] | 始终显示的原生视图类名(Android/iOS) |
跟踪选项
| 选项 | 类型 | 默认值 | 用途 |
|---|---|---|---|
tracesSampleRate | number | 0 | 事务采样率(0–1)。开发环境中使用 1.0 |
tracesSampler | function | — | 按事务进行采样;优先于 tracesSampleRate |
tracePropagationTargets | (string | RegExp)[] | [/.*/] | 哪些 API URL 会接收分布式跟踪标头 |
profilesSampleRate | number | 0 | 性能分析采样率(应用于已跟踪的事务) |
原生 / 移动端选项
| 选项 | 类型 | 默认值 | 用途 |
|---|---|---|---|
enableNative | boolean | true | 设置为 false 以仅使用 JS(不使用原生 SDK) |
enableNativeCrashHandling | boolean | true | 捕获原生硬崩溃(iOS/Android) |
enableNativeFramesTracking | boolean | — | 跟踪缓慢 / 冻结帧。在 Expo Go 中禁用 |
enableWatchdogTerminationTracking | boolean | true | 检测 OOM 终止(iOS) |
enableAppHangTracking | boolean | true | 检测应用卡顿(iOS、tvOS、macOS) |
appHangTimeoutInterval | number | 2 | 将应用归类为卡顿前的秒数(iOS) |
enableAutoPerformanceTracing | boolean | true | 自动进行性能检测 |
enableNdkScopeSync | boolean | true | Java→NDK 作用域同步(Android) |
attachThreads | boolean | false | 崩溃时自动附加所有线程(Android) |
attachAllThreads | boolean | false | 将所有线程的完整堆栈跟踪附加到每个捕获的事件中(仅限 iOS,要求 Cocoa SDK ≥9.9.0) |
autoInitializeNativeSdk | boolean | true | 设置为 false 以手动初始化原生 SDK |
onReady | function | — | 原生 SDK 初始化后的回调 |
enableTurboModuleTracking | boolean | false | 实验性。 安装原生 TurboModule 性能日志记录器,用于崩溃归因和按模块划分的跨度。仅适用于 RN 0.75+ 新架构;在旧架构中无操作(SDK ≥8.17.0) |
会话与版本健康度选项
| 选项 | 类型 | 默认值 | 用途 |
|---|---|---|---|
autoSessionTracking | boolean | true | 会话跟踪(无崩溃用户数 / 会话数) |
sessionTrackingIntervalMillis | number | 30000 | 会话结束前在后台运行的毫秒数 |
回放选项
| 选项 | 类型 | 默认值 | 用途 |
|---|---|---|---|
replaysSessionSampleRate | number | 0 | 记录的所有会话所占比例 |
replaysOnErrorSampleRate | number | 0 | 记录的错误会话所占比例 |
日志选项(SDK ≥7.0.0)
| 选项 | 类型 | 用途 |
|---|---|---|
enableLogs | boolean | 启用 Sentry.logger.* API |
enableAutoConsoleLogs | boolean | 当 enableLogs: true 时自动捕获 console.* 调用。设置为 false 以仅使用手动调用的 Sentry.logger.*(SDK ≥8.14.0,默认值:true) |
beforeSendLog | function | 发送前筛选 / 修改日志 |
logsOrigin | 'native' | 'js' | 'all' | 筛选日志来源(SDK ≥7.7.0) |
Hook 选项
| 选项 | 类型 | 用途 |
|---|---|---|
beforeSend | (event, hint) => event | null | 修改 / 丢弃 JS 错误事件。⚠️ 不适用于原生崩溃 |
beforeSendTransaction | (event) => event | null | 修改 / 丢弃事务事件 |
beforeBreadcrumb | (breadcrumb, hint) => breadcrumb | null | 存储前处理面包屑 |
onNativeLog | (log: { level, component, message }) => void | 拦截原生 SDK 日志消息并转发到 JS 控制台。仅在 debug: true 时触发 |
环境变量
| 变量 | 用途 | 备注 |
|---|---|---|
SENTRY_DSN | 数据源名称 | 回退使用 dsn 选项 |
SENTRY_AUTH_TOKEN | 上传 source map 和 dSYM | 切勿提交——请使用 CI 密钥 |
SENTRY_ORG | 组织标识 | 供向导和构建插件使用 |
SENTRY_PROJECT | 项目标识 | 供向导和构建插件使用 |
SENTRY_RELEASE | 发布标识符 | 回退使用 release 选项 |
SENTRY_DIST | 分发标识符 | 回退使用 dist 选项 |
SENTRY_ENVIRONMENT | 环境名称 | 回退使用 environment 选项 |
SENTRY_DISABLE_AUTO_UPLOAD | 跳过 source map 上传 | 本地构建时设为 true |
EXPO_PUBLIC_SENTRY_DSN | 用于 DSN 的 Expo 公共环境变量 | 可安全嵌入客户端包 |
SENTRY_EAS_BUILD_CAPTURE_SUCCESS | EAS 构建钩子:捕获成功的构建 | 在 EAS 密钥中设为 true |
SENTRY_EAS_BUILD_TAGS | EAS 构建钩子:额外标签 JSON | 例如:{"team":"mobile"} |
默认集成(自动启用)
这些集成会自动启用——无需配置:
| 集成 | 功能 |
|---|---|
ReactNativeErrorHandlers | 捕获未处理的 JS 异常和 Promise 拒绝 |
Release | 为所有事件附加 release/dist |
Breadcrumbs | 将控制台日志、HTTP 请求和用户手势记录为面包屑 |
HttpClient | 添加 HTTP 请求/响应面包屑 |
DeviceContext | 为事件附加设备/OS/电池信息 |
AppContext | 为事件附加应用版本、bundle ID 和内存信息 |
CultureContext | 附加区域设置和时区 |
Screenshot | 出错时截取屏幕截图(当 attachScreenshot: true 时) |
ViewHierarchy | 附加视图层级结构(当 attachViewHierarchy: true 时) |
NativeLinkedErrors | 将 JS 错误关联到对应的原生崩溃 |
TurboModuleContext | 在崩溃时上下文中跟踪 TurboModule 调用;将原生崩溃归因到高级别 RN 模块及方法(例如,RNSentry.captureEnvelope) |
可选启用的集成
| 集成 | 启用方式 |
|---|---|
mobileReplayIntegration() | 添加到 integrations 数组 |
reactNavigationIntegration() | 添加到 integrations 数组 |
reactNativeNavigationIntegration() | 添加到 integrations 数组(仅限 Wix) |
feedbackIntegration() | 添加到 integrations 数组(用户反馈小组件;支持通过 enableShakeToReport 启用原生摇晃检测) |
deeplinkIntegration() | 添加到 integrations 数组(自动将深层链接 URL 捕获为面包屑;需主动启用) |
turboModuleContextIntegration() | 默认启用——自动跟踪 RNSentry TurboModule。也可通过 { modules: [...] } 配置,以跟踪自定义 TurboModule |
跟踪自定义 TurboModule
TurboModuleContext 集成默认启用,并会自动跟踪内置的 RNSentry TurboModule。要跟踪自己的自定义 TurboModule,请显式配置该集成:
import * as Sentry from "@sentry/react-native";
import { NativeModules } from "react-native";
Sentry.init({
dsn: "YOUR_DSN",
integrations: [
Sentry.turboModuleContextIntegration({
modules: [
{
name: "MyCustomModule",
module: NativeModules.MyCustomModule,
// Optional: skip specific methods to avoid tracking overhead
skipMethods: ["addListener", "removeListeners"],
},
],
}),
],
});
当被跟踪的 TurboModule 方法调用内部发生原生崩溃时,崩溃报告会包含 contexts.turbo_module,其中记录模块名称和方法,从而更容易找出触发崩溃的确切 RN API 调用。
疯狂点击检测(TouchEventBoundary)
TouchEventBoundary(包裹应用根节点)内置疯狂点击检测功能。当用户在 1 秒内对同一元素点击 3 次或更多次时,会生成 ui.multiClick 面包屑,并显示在回放时间线上。可通过属性配置:
<Sentry.TouchEventBoundary
enableRageTapDetection={true} // default: true — set false to disable
rageTapThreshold={3} // taps required to trigger (default: 3)
rageTapTimeWindow={1000} // detection window in ms (default: 1000)
>
<App />
</Sentry.TouchEventBoundary>
生产环境设置
上线生产环境前,请降低采样率并强化配置:
Sentry.init({
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN,
environment: __DEV__ ? "development" : "production",
// Trace 10–20% of transactions in high-traffic production
tracesSampleRate: __DEV__ ? 1.0 : 0.1,
// Profile 100% of traced transactions (profiling is always a subset of tracing)
profilesSampleRate: 1.0,
// Replay all error sessions, sample 5% of normal sessions
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: __DEV__ ? 1.0 : 0.05,
// Set release and dist for accurate source map lookup
release: "my-app@" + Application.nativeApplicationVersion,
dist: String(Application.nativeBuildVersion),
// Disable debug logging in production
debug: __DEV__,
});
Source Maps 和调试符号
Source maps 和调试符号可以将压缩后的堆栈跟踪转换为易读的内容。正确配置后,Sentry 会显示引发错误的源代码确切行号。通用的身份验证令牌和 CI 配置位于 sentry-source-maps;React Native 特定的上传方式如下。
上传方式
| 平台 | 上传内容 | 时机 |
|---|---|---|
| iOS(JS) | Source maps(.map 文件) | Xcode 构建期间 |
| iOS(原生) | dSYM 包 | Xcode 归档 / Xcode Cloud 期间 |
| Android(JS) | Source maps + Hermes .hbc.map | Gradle 构建期间 |
| Android(原生) | Proguard 映射文件 + NDK .so 文件 | Gradle 构建期间 |
Expo:自动上传
@sentry/react-native/expo 配置插件会自动为原生构建设置上传钩子。Source maps 会在 eas build 和 expo run:ios/android(发布版)期间上传。
SENTRY_AUTH_TOKEN=sntrys_... npx expo run:ios --configuration Release
手动上传(bare RN)
如果需要手动上传 source maps:
npx sentry-cli sourcemaps upload \
--org YOUR_ORG \
--project YOUR_PROJECT \
--release "[email protected]+1" \
./dist
EAS 构建钩子
在 Sentry 中监控 Expo Application Services(EAS)构建。SDK 提供三个二进制钩子——sentry-eas-build-on-complete、sentry-eas-build-on-error 和 sentry-eas-build-on-success——用于将构建事件记录为 Sentry 错误或消息。
步骤 1 — 在 package.json 中注册钩子
{
"scripts": {
"eas-build-on-complete": "sentry-eas-build-on-complete"
}
}
使用 eas-build-on-complete,即可通过一个钩子捕获失败事件和(可选的)成功事件。如果希望分别控制,也可以单独使用 eas-build-on-error 或 eas-build-on-success。
步骤 2 — 在 EAS 密钥中设置 SENTRY_DSN
eas secret:create --name SENTRY_DSN --value "https://[email protected]/..."
钩子会从构建环境读取 SENTRY_DSN,不会与应用使用相同的 .env。
可选环境变量:
| 变量 | 用途 |
|---|---|
SENTRY_EAS_BUILD_CAPTURE_SUCCESS | 设置为 true 也会捕获成功的构建(默认:仅捕获错误) |
SENTRY_EAS_BUILD_TAGS | 额外标签的 JSON 对象,例如 {"team":"mobile","channel":"production"} |
SENTRY_EAS_BUILD_ERROR_MESSAGE | 构建失败时使用的自定义错误消息 |
SENTRY_EAS_BUILD_SUCCESS_MESSAGE | 构建成功时使用的自定义消息 |
**工作原理:**钩子脚本是 EAS npm 生命周期钩子。EAS 会在构建流程结束时调用
package.json中与eas-build-on-*匹配的脚本。该脚本会从@expo/env、.env或.env.sentry-build-plugin加载环境变量,但不会覆盖环境中已有的 EAS 密钥。
验证
完成设置后,测试 Sentry 是否正在接收事件:
// Quick test — throws and Sentry.wrap(App) catches it
<Button
title="Test Sentry Error"
onPress={() => {
throw new Error("My first Sentry error!");
}}
/>
// Or capture manually
<Button
title="Test Sentry Message"
onPress={() => {
Sentry.captureMessage("Sentry test message", "info");
}}
/>
检查 Sentry 控制面板:
- Issues → 你的测试错误应在几秒内出现
- Traces → 查找包含子 Span 的 "main" 事务
- Replays → 与应用交互后应能看到会话录制(仅限原生构建,Expo Go 除外)
- Logs → 如果设置了
enableLogs: true,应能看到结构化日志条目
⚠️ **Expo Go 的限制:**原生崩溃、会话回放、卡顿 / 冻结帧、TTID 和 TTFD 仅在原生构建中有效(
eas build或expo run)。Expo Go 以纯 JS 模式运行。设置enableNativeFramesTracking: !isRunningInExpoGo()可避免警告。
如果没有任何内容显示:
- 设置
debug: true— SDK 会将日志输出到 Metro 控制台 - 确认 DSN 正确,并且 Sentry 项目存在
- 确认已将
Sentry.wrap(App)应用于根组件 - 对于原生崩溃,请构建发布版(调试模式下的崩溃可能不会被转发)
阶段 4:交叉关联
完成 React Native 设置后,检查是否有尚未接入 Sentry 的后端或 Web 前端:
# Adjacent backend directories
ls ../backend ../server ../api 2>/dev/null
cat ../go.mod 2>/dev/null | head -3
cat ../requirements.txt ../pyproject.toml 2>/dev/null | head -3
cat ../Gemfile 2>/dev/null | head -3
ls ../backend/package.json ../server/package.json 2>/dev/null
# Web frontend in same or sibling repo
ls ../web ../frontend ../dashboard 2>/dev/null
cat ../web/package.json ../frontend/package.json 2>/dev/null | grep -E '"react"|"svelte"|"next"'
# Check for OpenTelemetry (for distributed tracing interop)
grep -r "opentelemetry" ../backend/go.mod ../server/requirements.txt 2>/dev/null
如果存在尚未接入 Sentry 的后端或 Web 前端,请推荐相应的技能:
| 检测到的项目 | 推荐技能 |
|---|---|
Go 后端(go.mod) | sentry-go-sdk |
Python 后端(requirements.txt、pyproject.toml) | sentry-python-sdk |
Ruby 后端(Gemfile) | sentry-ruby-sdk |
| Node.js 后端(Express、Fastify 等) | @sentry/node — 请参阅 docs.sentry.io/platforms/javascript/guides/express/ |
| React / Next.js Web | sentry-react-sdk |
| Svelte / SvelteKit Web | sentry-svelte-sdk |
分布式追踪设置——如果添加了后端技能,请在 React Native 中配置 tracePropagationTargets,以便向 API 传播追踪上下文:
Sentry.init({
tracePropagationTargets: [
"localhost",
/^https:\/\/api\.yourapp\.com/,
],
// ...
});
这样可在 Sentry 瀑布视图中关联移动端事务与后端追踪。
故障排查
| 问题 | 解决方案 |
|---|---|
| Sentry 中未显示事件 | 设置 debug: true,检查 Metro/Xcode 控制台中的 SDK 错误;确认 DSN 正确 |
pod install 失败 | 运行 cd ios && pod install --repo-update;检查 CocoaPods 版本 |
| iOS 构建因 Sentry 脚本失败 | 确认已替换(而非追加到)“Bundle React Native code and images”脚本 |
添加 sentry.gradle.kts 后 Android 构建失败 | 确保 apply from 行位于 build.gradle 中的 android {} 块之前;SDK 低于 8.13.0 时使用 sentry.gradle |
| Android Gradle 8+ 兼容性问题 | 使用 sentry-android-gradle-plugin ≥4.0.0;检查 SDK 中的 sentry.gradle 版本 |
| Source map 未上传 | 确认 sentry.properties 中的 auth.token 有效;检查构建日志中的 sentry-cli 输出 |
| Sentry 中的 Source map 未解析 | 确认 Sentry.init() 中的 release 和 dist 与已上传的 bundle 元数据一致 |
| Hermes Source map 无法使用 | Hermes 会生成 .hbc.map——Gradle 插件会自动处理;确认已应用 sentry.gradle |
| 未录制会话回放 | 必须使用原生构建(不能使用 Expo Go);确认 integrations 中包含 mobileReplayIntegration() |
| 回放显示空白/黑屏 | 检查 maskAllText/maskAllImages 设置是否符合隐私要求 |
| 未跟踪缓慢/冻结帧 | 设置 enableNativeFramesTracking: true,并确认使用的是原生构建(不是 Expo Go) |
| 未显示 TTID / TTFD | 原生构建中需要在 reactNavigationIntegration() 设置 enableTimeToInitialDisplay: true |
| 添加 Sentry 后应用启动时崩溃 | 可能是原生初始化错误——检查 Xcode/Logcat 日志;尝试设置 enableNative: false 以进行排查 |
| Expo SDK 49 或更早版本 | 使用 sentry-expo(旧版软件包);@sentry/react-native 要求 Expo SDK 50+ |
isRunningInExpoGo 导入错误 | 从 expo 软件包导入:import { isRunningInExpoGo } from "expo" |
| Xcode 构建期间找不到 Node | 在 Xcode 构建阶段添加 export NODE_BINARY=$(which node),或创建符号链接:ln -s $(which node) /usr/local/bin/node |
| Expo Go 关于原生功能的警告 | 使用 isRunningInExpoGo() 保护条件:enableNativeFramesTracking: !isRunningInExpoGo() |
原生崩溃时未触发 beforeSend | 这是预期行为——beforeSend 只拦截 JS 层错误;原生崩溃会绕过它 |
| Android 15+(16KB 页大小)崩溃 | 升级到 @sentry/react-native ≥6.3.0 |
| 控制面板中的事务过多 | 将 tracesSampleRate 调低至 0.1,或使用 tracesSampler 丢弃健康检查 |
SENTRY_AUTH_TOKEN 暴露在应用 bundle 中 | SENTRY_AUTH_TOKEN 仅用于构建时上传——切勿将其传给 Sentry.init() |
| EAS Build:缺少 Sentry 身份验证令牌 | 将 SENTRY_AUTH_TOKEN 设为 EAS 密钥:eas secret:create --name SENTRY_AUTH_TOKEN |