关于 sentry-react-native-sdk
这项技能引导编码 Agent 为 React Native 和 Expo 项目配置 Sentry。它会识别项目结构,并针对错误监控及其他可观测性功能提供设置步骤。
主要功能
- 01识别 React Native 和 Expo 项目配置
- 02指导安装和初始化 Sentry
- 03涵盖错误监控、追踪和回放
- 04提供性能分析、日志和反馈选项
- 05包含验证步骤与配置参考
适用场景
- 01为新的 React Native 应用添加 Sentry
- 02配置 Expo 项目的监控
- 03为现有配置增加性能功能
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ getsentry/ sentry-agent-skills --skill sentry-react-native-sdk安装后在 Claude Code 中输入/sentry-react-native-sdk确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/error-monitoring.mdlogging.mdprofiling.mdsession-replay.mdtracing.mduser-feedback.md详细介绍
Sentry React Native SDK
一个具有主见的向导,会扫描你的 React Native 或 Expo 项目,并引导你完成 Sentry 的完整设置——错误监控、追踪、性能剖析、会话回放、日志记录等。
在以下情况调用此 Skill
- 用户要求在 RN 或 Expo 应用中“将 Sentry 添加到 React Native”或“设置 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(推荐用于所有项目类型)
运行向导——它会以交互方式引导你完成登录、组织/项目选择以及认证令牌设置。随后它会处理安装、原生配置、Source Map 上传以及初始 Sentry.init():
npx @sentry/wizard@latest -i reactNative
向导创建/修改的内容:
| 文件 | 操作 | 用途 |
|---|---|---|
package.json | 安装 @sentry/react-native | 核心 SDK |
metro.config.js | 添加 @sentry/react-native/metro 序列化器 | Source Map 生成 |
app.json | 添加 @sentry/react-native/expo 插件(仅 Expo) | 原生构建的配置插件 |
App.tsx / _layout.tsx | 添加 Sentry.init() 和 Sentry.wrap() | SDK 初始化 |
ios/sentry.properties | 存储组织/项目/令牌 | iOS Source Map + dSYM 上传 |
android/sentry.properties | 存储组织/项目/令牌 | Android Source Map 上传 |
android/app/build.gradle | 添加 Sentry Gradle 插件 | Android Source Map + proguard |
ios/[AppName].xcodeproj | 包装 "Bundle RN" 构建阶段 + 添加 dSYM 上传 | iOS 符号上传 |
.env.local | SENTRY_AUTH_TOKEN | 认证令牌(添加到 .gitignore) |
向导运行完成后,跳转到验证。
路径 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);
module.exports = config;
如果 metro.config.js 尚不存在:
npx expo customize metro.config.js
# Then replace contents with the above
步骤 3 — app.json — 添加 Expo 配置插件
{
"expo": {
"plugins": [
[
"@sentry/react-native/expo",
{
"url": "https://sentry.io/",
"project": "YOUR_PROJECT_SLUG",
"organization": "YOUR_ORG_SLUG"
}
]
]
}
}
注意: 将
SENTRY_AUTH_TOKEN设置为原生构建的环境变量——切勿将其提交到版本控制中。
步骤 4 — 初始化 Sentry
对于 Expo Router(app/_layout.tsx):
import { Stack, useNavigationContainerRef } from "expo-router";
import { isRunningInExpoGo } from "expo";
import * as Sentry from "@sentry/react-native";
import React from "react";
const navigationIntegration = Sentry.reactNavigationIntegration({
enableTimeToInitialDisplay: !isRunningInExpoGo(), // disabled in Expo Go
});
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,
// Navigation
integrations: [
navigationIntegration,
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: !isRunningInExpoGo(), // slow/frozen frames
environment: __DEV__ ? "development" : "production",
});
function RootLayout() {
const ref = useNavigationContainerRef();
React.useEffect(() => {
if (ref) {
navigationIntegration.registerNavigationContainer(ref);
}
}, [ref]);
return <Stack />;
}
export default Sentry.wrap(RootLayout);
对于标准 Expo(App.tsx):
import { NavigationContainer, createNavigationContainerRef } from "@react-navigation/native";
import { isRunningInExpoGo } from "expo";
import * as Sentry from "@sentry/react-native";
const navigationIntegration = Sentry.reactNavigationIntegration({
enableTimeToInitialDisplay: !isRunningInExpoGo(),
});
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: [
navigationIntegration,
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: !isRunningInExpoGo(),
environment: __DEV__ ? "development" : "production",
});
const navigationRef = createNavigationContainerRef();
function App() {
return (
<NavigationContainer
ref={navigationRef}
onReady={() => {
navigationIntegration.registerNavigationContainer(navigationRef);
}}
>
{/* your navigation here */}
</NavigationContainer>
);
}
export default Sentry.wrap(App);
路径 C:手动 — 裸 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);
步骤 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"
步骤 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 { NavigationContainer, createNavigationContainerRef } from "@react-navigation/native";
import * as Sentry from "@sentry/react-native";
const navigationIntegration = Sentry.reactNavigationIntegration({
enableTimeToInitialDisplay: true,
});
Sentry.init({
dsn: "YOUR_SENTRY_DSN",
sendDefaultPii: true,
tracesSampleRate: 1.0,
profilesSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
enableLogs: true,
integrations: [
navigationIntegration,
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: true,
environment: __DEV__ ? "development" : "production",
});
const navigationRef = createNavigationContainerRef();
function App() {
return (
<NavigationContainer
ref={navigationRef}
onReady={() => {
navigationIntegration.registerNavigationContainer(navigationRef);
}}
>
{/* your navigation here */}
</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);
导航设置 — React Navigation(v5+)
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 | 始终(基线) |
| Tracing 与性能 | ${SKILL_ROOT}/references/tracing.md | 移动端始终(应用启动、导航、网络) |
| Profiling | ${SKILL_ROOT}/references/profiling.md | 性能敏感的生产应用 |
| 会话重放 | ${SKILL_ROOT}/references/session-replay.md | 面向用户的应用 |
| 日志记录 | ${SKILL_ROOT}/references/logging.md | 结构化日志 / 日志到 Trace 关联 |
| 用户反馈 | ${SKILL_ROOT}/references/user-feedback.md | 收集用户提交的报告 |
对于每项功能: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 个字符) |
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) |
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 | — | 添加或过滤集成 |
追踪选项
| 选项 | 类型 | 默认值 | 用途 |
|---|---|---|---|
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) |
autoInitializeNativeSdk | boolean | true | 设为 false 以手动初始化原生 SDK |
onReady | function | — | 原生 SDK 初始化后的回调 |
会话与发布健康选项
| 选项 | 类型 | 默认值 | 用途 |
|---|---|---|---|
autoSessionTracking | boolean | true | 会话追踪(无崩溃用户 / 会话) |
sessionTrackingIntervalMillis | number | 30000 | 会话结束前的后台毫秒数 |
Replay 选项
| 选项 | 类型 | 默认值 | 用途 |
|---|---|---|---|
replaysSessionSampleRate | number | 0 | 所有会话中被录制的比例 |
replaysOnErrorSampleRate | number | 0 | 出错会话中被录制的比例 |
日志选项(SDK ≥7.0.0)
| 选项 | 类型 | 用途 |
|---|---|---|
enableLogs | boolean | 启用 Sentry.logger.* API |
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 | 在存储前处理面包屑 |
环境变量
| 变量 | 用途 | 备注 |
|---|---|---|
SENTRY_DSN | 数据源名称 | 从 dsn 选项回退 |
SENTRY_AUTH_TOKEN | 上传 source maps 和 dSYMs | 切勿提交 — 使用 CI 密钥 |
SENTRY_ORG | 组织 slug | 由向导和构建插件使用 |
SENTRY_PROJECT | 项目 slug | 由向导和构建插件使用 |
SENTRY_RELEASE | 发布标识符 | 从 release 选项回退 |
SENTRY_ENVIRONMENT | 环境名称 | 从 environment 选项回退 |
SENTRY_DISABLE_AUTO_UPLOAD | 跳过 source map 上传 | 在本地构建时设为 true |
EXPO_PUBLIC_SENTRY_DSN | 用于 DSN 的 Expo 公共环境变量 | 可安全嵌入客户端 bundle |
Source Maps 与调试符号
Source maps 和调试符号可将压缩后的堆栈跟踪转换为可读的堆栈跟踪。正确设置后,Sentry 会向你显示抛出异常的源代码的确切行。
上传的工作原理
| 平台 | 上传内容 | 时机 |
|---|---|---|
| iOS(JS) | Source maps(.map 文件) | 在 Xcode 构建期间 |
| iOS(原生) | dSYM bundle | 在 Xcode archive / Xcode Cloud 期间 |
| Android(JS) | Source maps + Hermes .hbc.map | 在 Gradle 构建期间 |
| Android(原生) | Proguard mapping + NDK .so 文件 | 在 Gradle 构建期间 |
Expo:自动上传
@sentry/react-native/expo 配置插件会自动为原生构建设置上传 hook。Source maps 会在 eas build 和 expo run:ios/android(release)期间上传。
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
默认集成(自动启用)
这些集成会自动启用 — 无需配置:
| 集成 | 功能 |
|---|---|
ReactNativeErrorHandlers | 捕获未处理的 JS 异常和 promise rejection |
Release | 将 release/dist 附加到所有事件 |
Breadcrumbs | 将控制台日志、HTTP 请求、用户手势记录为面包屑 |
HttpClient | 添加 HTTP 请求/响应面包屑 |
DeviceContext | 将设备/OS/电池信息附加到事件 |
AppContext | 附加应用版本、bundle ID 和内存信息 |
CultureContext | 附加区域设置和时区 |
Screenshot | 在错误时捕获截图(当 attachScreenshot: true 时) |
ViewHierarchy | 附加视图层级(当 attachViewHierarchy: true 时) |
NativeLinkedErrors | 将 JS 错误链接到其对应的原生崩溃 |
可选加入的集成
| 集成 | 如何启用 |
|---|---|
mobileReplayIntegration() | 添加到 integrations 数组 |
reactNavigationIntegration() | 添加到 integrations 数组 |
reactNativeNavigationIntegration() | 添加到 integrations 数组(仅限 Wix) |
feedbackIntegration() | 添加到 integrations 数组(用户反馈小组件) |
Expo 配置插件参考
在 app.json 或 app.config.js 中配置插件:
{
"expo": {
"plugins": [
[
"@sentry/react-native/expo",
{
"url": "https://sentry.io/",
"project": "my-project",
"organization": "my-org",
"note": "Set SENTRY_AUTH_TOKEN env var for native builds"
}
]
]
}
}
或在 app.config.js 中(允许环境变量插值):
export default {
expo: {
plugins: [
[
"@sentry/react-native/expo",
{
url: "https://sentry.io/",
project: process.env.SENTRY_PROJECT,
organization: process.env.SENTRY_ORG,
},
],
],
},
};
生产环境设置
在发布到生产环境之前,降低采样率并加固配置:
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__,
});
验证
完成设置后,测试 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)已应用于根组件 - 对于原生崩溃,请构建 release 构建(debug 模式下的崩溃可能不会上报)
阶段 4:交叉链接
完成 React Native 设置后,检查是否有后端或 Web 前端缺少 Sentry 覆盖:
# 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
如果存在后端或 Web 前端但未接入 Sentry,建议匹配的技能:
| 检测到 | 建议技能 |
|---|---|
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 后 Android 构建失败 | 确保 apply from 行位于 build.gradle 中 android {} 块之前 |
| Android Gradle 8+ 兼容性问题 | 使用 sentry-android-gradle-plugin ≥4.0.0;检查 SDK 中的 sentry.gradle 版本 |
| Source maps 未上传 | 确认 sentry.properties 中有有效的 auth.token;检查构建日志中的 sentry-cli 输出 |
| Source maps 在 Sentry 中无法解析 | 确认 Sentry.init() 中的 release 和 dist 与上传的 bundle 元数据匹配 |
| Hermes source maps 不工作 | Hermes 生成 .hbc.map — Gradle 插件会自动处理;确认 sentry.gradle 已应用 |
| Session replay 未录制 | 必须使用原生构建(而非 Expo Go);确认 mobileReplayIntegration() 在 integrations 中 |
| Replay 显示空白/黑屏 | 检查 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 auth token | 将 SENTRY_AUTH_TOKEN 设为 EAS 密钥:eas secret:create --name SENTRY_AUTH_TOKEN |