快速开始
Sentry
的React SDK
支持自动报告错误和异常。SDK
是@sentry/browser
的包装器,增加了与React
相关的功能。@sentry/browser
中可用的所有方法都可以从
@sentry/react
中导入。
安装
Sentry
通过在应用程序 runtime
使用 SDK
捕获数据。
# 使用 npm npm install --save @sentry/react @sentry/tracing # 使用 yarn yarn add @sentry/react @sentry/tracing export const _frontmatter = {}
配置
配置应该在应用程序的生命周期中尽早进行。
import React from "react"; import ReactDOM from "react-dom"; import * as Sentry from "@sentry/react"; import { Integrations } from "@sentry/tracing"; import App from "./App"; Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new Integrations.BrowserTracing()], // 我们建议在生产中调整此值,或使用 tracesSampler 进行更精细的控制 tracesSampleRate: 1.0, }); ReactDOM.render(<App />, document.getElementById("root")); // 也可以与 React Concurrent Mode 一起使用 // ReactDOM.createRoot(document.getElementById('root')).render(<App />);
一旦完成,所有未处理的异常都会被 Sentry
自动捕获。
添加 Error Boundary
如果您使用的是 React 16
或更高版本,则可以使用 Error Boundary
组件将组件树内部的 Javascript
错误自动发送到 Sentry
,并设置回退 UI
。
设置 React Router
React Router 集成
旨在与我们的跟踪包一起使用。请在下方配置
部分了解有关 React Router Integration
及其选项的更多信息。
应用 Redux
要将 Sentry
应用于 Redux
,请在下方配置
部分了解有关 Redux Integration
及其选项的更多信息。
验证
此代码段包含一个故意错误,因此您可以在设置后立即测试一切是否正常:
return <button onClick={methodDoesNotExist}>Break the world</button>;
组件
Sentry React SDK
公开自定义组件,以便与 React 框架进行一级集成。
React Error Boundary
React SDK
导出一个错误边界组件,该组件利用 React component API
自动捕获 JavaScript
错误并将其从 React
组件树内部发送到 Sentry
。
import React from "react"; import * as Sentry from "@sentry/react"; <Sentry.ErrorBoundary fallback={<p>An error has occurred</p>}> <Example /> </Sentry.ErrorBoundary>;
Sentry Error Boundary
也可用作高阶组件。
import React from "react"; import * as Sentry from "@sentry/react"; Sentry.withErrorBoundary(Example, { fallback: <p>an error has occurred</p> });
Note:在
development
模式下,React
会重新抛出在错误边界内捕获的错误。这将导致使用上述设置向Sentry
报告两次错误,但这不会发生在您的生产版本中。
在下面的示例中,当 <Example />
组件遇到错误时,<Sentry.ErrorBoundary>
组件会将有关该错误的数据和组件树发送到 Sentry
,打开用户反馈对话框,并呈现 fallback UI
。
import React from "react"; import * as Sentry from "@sentry/react"; import { Example } from "../example"; function FallbackComponent() { return <div>An error has occurred</div>; } const myFallback = <FallbackComponent />; // Alternatively: // const myFallback = () => <FallbackComponent />; class App extends React.Component { render() { return ( <Sentry.ErrorBoundary fallback={myFallback} showDialog> <Example /> </Sentry.ErrorBoundary> ); } } export default App;
选项
ErrorBoundary
组件公开了各种可以传入以进行额外配置的属性。没有必需的选项,但我们强烈建议您设置 fallback
组件。
showDialog
(boolean)
- 当
Error Boundary
捕捉到错误时,是否应呈现Sentry User Feedback Widget
。
dialogOptions
(Object)
- 传递到
Sentry User Feedback Widget
的选项。在下方查看所有可能的自定义选项。
fallback
(React.ReactNode or Function)
- 当错误边界捕获错误时要呈现的
React
元素。可以是实际的React
元素(即<Fallback />
),也可以是返回React
元素的函数。如果您提供一个函数,Sentry
将使用附加信息和帮助程序调用它(参见下面的示例)。
onError
(Function)
- 当
Error Boundary
遇到错误时调用的函数。如果您想将错误传播到Redux
之类的状态管理库中,或者您想检查由于错误而可能发生的任何副作用,onError
非常有用。
onUnmount
(Function)
- 在
ErrorBoundary componentWillUnmount()
上调用的函数。
beforeCapture
(Function) *(5.20.0
及以上版本可用)
- 在将错误发送到
Sentry
之前调用的函数,允许将额外的标签(tag
)或上下文(context
)添加到错误中。
示例
设置 Fallback 函数(渲染属性)
下面是一个示例,其中使用渲染属性方法的 fallback
属性用于在错误时显示 fallback UI
。使用组件通过渲染属性提供的 resetError() API
重置时,fallback UI
会返回到标准组件状态。
import React from "react"; import * as Sentry from "@sentry/react"; class App extends React.Component { constructor(props) { super(props); this.state = { message: "This is my app", }; } render() { return ( <Sentry.ErrorBoundary fallback={({ error, componentStack, resetError }) => ( <React.Fragment> <div>You have encountered an error</div> <div>{error.toString()}</div> <div>{componentStack}</div> <button onClick={() => { this.setState({ message: "This is my app" }); {/* When resetError() is called it will remove the Fallback component */} {/* and render the Sentry ErrorBoundary's children in their initial state */} resetError(); }} > Click here to reset! </button> </React.Fragment> )} > <div>{this.state.message}</div> {/* on click, this button sets an Object as a message, not a string. */} {/* which will cause an error to occur in the component tree */} <button onClick={() => this.setState({ message: { text: "Hello World" } })} > Click here to change message! </button> </Sentry.ErrorBoundary> ); } } export default App;
使用多个错误边界
(5.20.0 及以上版本可用)
当使用多个错误边界时,我们建议使用 beforeCapture
设置标签/上下文(tags/context)
,以便您可以知道错误发生在哪个错误边界。在下面的示例中,我们根据错误渲染的路径将标记(tag
)附加到错误(error
)。
import React from 'react'; import * as Sentry from '@sentry/react'; function App({ props }) { return ( <React.Fragment> <Sentry.ErrorBoundary beforeCapture={(scope) => { scope.setTag("location", "first"); scope.setTag("anotherTag", "anotherValue"); }} > <Route to="path/to/first" component={First} /> </Sentry.ErrorBoundary> <Sentry.ErrorBoundary beforeCapture={(scope) => { scope.setTag("location", "second"); }} > <Route to="path/to/second" component={Second} /> </Sentry.ErrorBoundary> </React.Fragment> ); } export default App;
React Profiler
@sentry/react
导出一个 withProfiler
高阶组件,该组件将 React
相关的 span
附加到作用域上的当前活动事务(transaction
)。
在下面的示例中,withProfiler
高阶组件用于检测 App
组件。
import React from "react"; import * as Sentry from "@sentry/react"; class App extends React.Component { render() { return ( <FancyComponent> <NestedComponent someProp={2} /> <AnotherComponent /> </FancyComponent> ); } } export default Sentry.withProfiler(App);
React Profiler
目前使用三种不同类型的操作码(op-codes
)生成 span
:react.mount
、react.render
和 react.update
。
react.mount
- 表示被分析组件
mount
所需时间的跨度。
react.render
- 表示被分析组件在页面上的时间跨度。只有在事务发生时
mount
和unmount
被分析的组件时,才会生成这个跨度。
react.update
- 表示被分析组件更新时的跨度。只有当被分析组件已
mount
时才生成此span
。
在
React Strict Mode
下,某些组件方法将被调用两次。这可能会导致在事务中出现重复的react.mount
跨度。React Strict Mode
仅在开发模式下运行,因此这不会影响您的生产跟踪。
Profiler 选项
withProfiler
高阶组件有多种选项可用于进一步定制。它们可以作为第二个参数传入 withProfiler
函数。
export default Sentry.withProfiler(App, { name: "CustomAppName" });
name
(string)
- 被分析的组件的名称。默认情况下,名称取自组件的
displayName
属性或组件的name
属性。
includeRender
(boolean)
- 是否应该由
Profiler
创建react.render
跨度。默认设置为true
。
includeUpdates
(boolean)
react.update
spans 是否应该由Profiler
创建。默认设置为true
。对于将经历多次重新渲染的组件(例如文本输入text input
组件),我们建议将此属性设置为false
,因为生成的span
可能非常嘈杂。
配置
基本选项
SDK
可以使用多种选项进行配置。这些选项在 SDK
中基本上是标准化的,但在更好地适应平台特性方面存在一些差异。选项是在 SDK
首次初始化时设置的。
选项作为对象传递给 init()
函数:
Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", maxBreadcrumbs: 50, debug: true, });
常见选项
跨 SDK
的常用选项列表。这些在所有 SDK
中的工作方式或多或少都相同,但为了更好地支持平台,将存在一些细微差别。可以从环境变量(SENTRY_DSN
、SENTRY_ENVIRONMENT
、SENTRY_RELEASE
)中读取的选项会自动读取。
dsn
DSN
告诉 SDK
将事件发送到哪里。如果没有提供这个值,SDK
将尝试从 SENTRY_DSN
环境变量中读取它。如果这个变量也不存在,SDK
就不会发送任何事件。
在没有进程环境(如浏览器)的运行时中,fallback
不会应用。
更多:https://docs.sentry.io/product/sentry-basics/dsn-explainer/#dsn-utilization
debug
打开或关闭调试模式。如果启用了调试,如果发送事件时出现问题,SDK
将尝试打印出有用的调试信息。默认值总是 false
。一般不建议在生产环境中打开它,尽管打开 debug
模式不会引起任何安全问题。
release
设置 release。某些 SDK
会尝试自动配置 release
,但是最好手动设置 release
,以确保该 release
与您的 deploy integrations
或 source map uploads
同步。Release
名称是字符串,但是 Sentry
会检测到某些格式,并且它们的呈现方式可能有所不同。
更多:https://docs.sentry.io/product/releases/
默认情况下,SDK
会尝试从环境变量 SENTRY_RELEASE
中读取该值(在浏览器 SDK
中,将从 window.SENTRY_RELEASE
中读取该值,如果可用)。
environment
设置环境。此字符串为自由形式,默认情况下不设置。一个 release
可以与多个环境相关联,以便在 UI 中将它们分开(可以考虑staging
与 prod
或类似的方式)。
默认情况下,SDK
将尝试从 SENTRY_ENVIRONMENT
环境变量中读取该值(浏览器 SDK
除外)。
tunnel
设置将用于传输捕获事件的 URL
,而不是使用 DSN
。这可用于解决广告拦截器(ad-blockers
)或对发送到 Sentry
的事件进行更精细的控制。此选项需要实现自定义服务器端点。
更多:https://docs.sentry.io/platforms/javascript/troubleshooting/#dealing-with-ad-blockers
sampleRate
配置错误事件的采样率,范围为 0.0
到 1.0
。默认值为 1.0
,表示发送了 100%
的错误事件。如果设置为 0.1
,则仅发送 10%
的错误事件。事件是随机选择的。
maxBreadcrumbs
这个变量控制应该捕获的面包屑总数。默认值为 100
。
attachStacktrace
当启用时,堆栈跟踪将自动附加到所有记录的消息。堆栈跟踪总是附加到异常;然而,当设置此选项时,堆栈跟踪也会与消息一起发送。例如,该选项意味着堆栈跟踪显示在所有日志消息的旁边。
该选项默认为 off
。
Sentry
中的分组对于有和没有堆栈跟踪的事件是不同的。因此,当您为某些事件启用或禁用此 flag
时,您将获得新组。
denyUrls
与不应该发送到 Sentry
的错误 URL
相匹配的字符串或正则表达式模式列表。默认情况下,将发送所有错误。这是一个 “contains(包含)” 匹配整个文件 URL。因此,如果你添加 foo.com
,它也会匹配 https://bar.com/myfile/foo.com
。默认情况下,将发送所有错误。
allowUrls
匹配错误 URL
的字符串列表或正则表达式模式的遗留别名,这些错误 URL
应该专门发送给 Sentry
。默认情况下,将发送所有错误。这是一个 “contains(包含)” 匹配整个文件 URL。因此,如果您将 foo.com
添加到它,它也将匹配 https://bar.com/myfile/foo.com
。默认情况下,所有错误将被发送。
autoSessionTracking
设置为 true
时,SDK
将向 Sentry
发送 session
事件。这在所有浏览器 SDK
中都受支持,每个页面加载和页面导航都向 Sentry
发出一个 session
。在移动 SDK
中,当应用进入后台超过 30
秒时,会话结束。
initialScope
要设置为初始作用域的数据。初始作用域可以定义为对象或回调函数,如下所示。
对象:
Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", debug: true, initialScope: { tags: {"my-tag": "my value"}, user: {id: 42, email: "john.doe@example.com"}, } });
回调函数:
Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", debug: true, initialScope: scope => { scope.setTags({ a: 'b' }); return scope; }, });
maxValueLength
单个值在被截断之前可以具有的最大字符数(默认为 250
)。
normalizeDepth
Sentry SDK
将任何上下文数据标准化到给定的深度。任何包含结构比这更深的数据的 key
都将使用其类型([Object]
或 [Array]
)进行修剪和标记,而不会进一步遍历树。默认情况下,步行执行 3
级深度。
集成配置
对于许多平台,SDK 集成可以与之一起配置。在一些平台上,这是 init()
调用的一部分,而在另一些平台上,则应用不同的模式。
integrations
在某些 SDK 中,在库初始化时通过此参数配置集成。
更多:
defaultIntegrations
这可以用来禁用默认添加的集成。当设置为 false
时,不会添加默认的集成。
Hooks
这些选项可用于以各种方式 hook SDK
,以定制事件的报告。
beforeSend
使用 SDK-specific
事件对象调用此函数,可以返回修改后的事件对象或不返回任何内容,以跳过报告事件。例如,这可以用于在发送前手动剥离 PII
。
beforeBreadcrumb
在将面包屑添加到作用域之前,使用 SDK
特定的面包屑(SDK-specific breadcrumb
)对象调用此函数。当该函数未返回任何内容时,将删除 breadcrumb
。要传递 breadcrumb
,请返回第一个参数,其中包含 breadcrumb
对象。回调通常会获得第二个参数(称为“hint”
),该参数包含创建 breadcrumb
的原始对象,以进一步自定义面包屑的外观。
传输选项
Transports
被用来发送事件到 Sentry
。可以在某种程度上对传输进行定制,以更好地支持高度特定的部署。
transport
切换出用于发送事件的 transport
。如何运作取决于 SDK
。例如,它可以用于捕获事件以进行单元测试,或通过需要代理身份验证的更复杂的设置发送事件。
跟踪选项
tracesSampleRate
0
到 1
之间的数字,控制给定事务发送到 Sentry
的概率百分比。(0
表示 0%
,1
表示 100%
)同样适用于应用程序中创建的所有事务。必须定义这个或 tracesSampler
以启用跟踪。
tracesSampler
一个函数负责确定一个给定的事务将被发送到 Sentry
的概率百分比。它将自动被传递有关事务和创建它的上下文的信息,并且必须返回一个介于 0
(被发送的概率为 0%
)和 1
(被发送的概率为 100%
) 之间的数字。还可以用于过滤事务,对不需要的事务返回 0
。必须定义这个或 tracesSampleRate
来启用跟踪。
集成
默认集成
Sentry
的所有 SDK
都提供集成,可扩展 SDK
的功能。
默认情况下启用系统集成以集成到标准库或解释器本身。它们被记录在案,因此您既可以了解它们的作用,也可以在它们引起问题时禁用它们。
默认启用
InboundFilters
Import name: Sentry.Integrations.InboundFilters
通过这种集成,您可以根据给定异常中的类型,消息或 URL 忽略特定错误。
默认情况下,它忽略以 Script error
或 Javascript error: Script error
开头的错误。
要配置这个集成,直接使用 ignoreErrors
,denyUrls
,和 allowUrls
SDK 选项。请记住,denyURL
和 allowURL
只对捕获的异常有效,而不是原始消息事件。
FunctionToString
Import name: Sentry.Integrations.FunctionToString
这种集成使 SDK
可以提供原始的函数和方法名称,即使我们的错误(error
)或面包屑处理程序(breadcrumbs handlers
)包装了它们也是如此。
TryCatch
Import name: Sentry.Integrations.TryCatch
这个集成封装了原生 time
和 events APIs
(setTimeout
, setInterval
, requestAnimationFrame
, addEventListener/removeEventListener
) 在 try/catch
块处理 async
异常。
Breadcrumbs
Import name: Sentry.Integrations.Breadcrumbs
这种集成封装了原生 API 以捕获面包屑。默认情况下,Sentry SDK
封装了所有 API
。
可用选项:
{ // 记录对 `console.log`、`console.debug` 等的调用 console: boolean; // 记录所有点击和按键事件 // - 当提供带有 `serializeAttribute` key 的对象时, // 面包屑集成将在 DOM 元素中查找给定的属性,同时生成面包屑路径。 // 匹配的元素后跟它们的自定义属性,而不是它们的 `id` 或 `class` 名称。 dom: boolean | { serializeAttribute: string | string[] }; // 记录使用 `Fetch API` 完成的 `HTTP` 请求 fetch: boolean; // 记录对 `history.pushState` 的调用 history: boolean; // 每当我们向服务器发送事件时记录 sentry: boolean; // 记录使用 XHR API 完成的 HTTP 请求 xhr: boolean; }
GlobalHandlers
Import name: Sentry.Integrations.GlobalHandlers
这个集成附加了全局处理程序来捕获未捕获的 exceptions
和未处理的 rejections
。
可用的选项:
{ onerror: boolean; onunhandledrejection: boolean; }
LinkedErrors
Import name: Sentry.Integrations.LinkedErrors
此集成允许您配置 linked
错误。它们将被递归地读取到指定的限制,并由特定的 key
执行查找。默认情况下,Sentry SDK
将限制设置为 5
,使用的键 key
是 cause
。
可用的选项:
{ key: string; limit: number; }
这是如何实现的代码示例:
document .querySelector("#get-reviews-btn") .addEventListener("click", async event => { const movie = event.target.dataset.title; try { const reviews = await fetchMovieReviews(movie); renderMovieReviews(reviews); } catch (e) { const fetchError = new Error(`Failed to fetch reviews for: ${movie}`); fetchError.cause = e; Sentry.captureException(fetchError); renderMovieReviewsError(fetchError); } });
UserAgent
Import name: Sentry.Integrations.UserAgent
这种集成将 user-agent
信息附加到事件中,这使我们能够正确地分类并使用特定的操作系统(OS
),浏览器(browser
)和版本(version
)信息对其进行标记。
Dedupe
Import name: Sentry.Integrations.Dedupe
这种集成消除了某些事件的重复数据。如果您收到许多重复的错误,这会很有帮助。请注意,Sentry
只会比较堆栈跟踪(stack traces
)和指纹(fingerprints
)。默认情况下为浏览器启用此集成。
import * as Sentry from "@sentry/browser"; import { Dedupe as DedupeIntegration } from "@sentry/integrations"; Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new DedupeIntegration()], });
CDN
<script src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js" integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr" crossorigin="anonymous" ></script> <script src="https://browser.sentry-cdn.com/6.12.0/dedupe.min.js" integrity="sha384-3IMGY+DN27Yns7KDiKL3sOWXBYlILQ/bxLogt02NG7DL7qEJHIMbpnXfqNlO0J8G" crossorigin="anonymous" ></script> Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new Dedupe()], });
修改系统集成
要禁用系统集成,请在调用 init()
时设置 defaultIntegrations: false
。
要覆盖它们的设置,请提供一个带有您的配置到集成选项的新实例。例如,要关闭浏览器捕获控制台调用:integrations: [new Sentry.Integrations.Breadcrumbs({ console: false })]
。
删除集成
此示例删除了用于向事件添加面包屑的默认启用集成:
Sentry.init({ // ... integrations: function(integrations) { // integrations will be all default integrations return integrations.filter(function(integration) { return integration.name !== "Breadcrumbs"; }); }, });
可插拔集成
这些可插拔的集成是为特定的应用程序和/或框架增加功能的代码片段。我们对它们进行了记录,这样您就可以看到它们的功能,并且可以启用它们。
如何启用
安装 @sentry/integrations
包,并提供一个带有你配置到 integrations
选项的新实例。加载 SDK
之后,包括插件。
示例:
import * as Sentry from "@sentry/browser"; import { ReportingObserver as ReportingObserverIntegration } from "@sentry/integrations"; Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new ReportingObserverIntegration()], });
CDN
<script src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js" integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr" crossorigin="anonymous" ></script> <script src="https://browser.sentry-cdn.com/6.12.0/reportingobserver.min.js" integrity="sha384-20D83MPBNSRANJFguhj0o9Qo7p9MCemwdMMQXotwA8742WuIwga85k+T7qEgIMWK" crossorigin="anonymous" ></script> Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new ReportingObserver()], });
ExtraErrorData
Import name: Sentry.Integrations.ExtraErrorData
这个集成从错误对象中提取所有非原生(non-native)属性,并将它们作为 extra
数据附加到事件中。
可用的选项:
import * as Sentry from "@sentry/browser"; import { ExtraErrorData as ExtraErrorDataIntegration } from "@sentry/integrations"; Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new ExtraErrorDataIntegration( { // limit of how deep the object serializer should go. Anything deeper than limit will // be replaced with standard Node.js REPL notation of [Object], [Array], [Function] or // a primitive value. Defaults to 3. depth: number; } )], });
CDN
<script src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js" integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr" crossorigin="anonymous" ></script> <script src="https://browser.sentry-cdn.com/6.12.0/extraerrordata.min.js" integrity="sha384-DMO/ZWwA4ztkOtskx1Uad3cH6lbfSA/PGdW2IZ7A/c2qd/BU6zh5xiJ5D4nxJbye" crossorigin="anonymous" ></script> Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new ExtraErrorData( { // limit of how deep the object serializer should go. Anything deeper than limit will // be replaced with standard Node.js REPL notation of [Object], [Array], [Function] or // a primitive value. Defaults to 3. depth: number; } )], });
CaptureConsole
Import name: Sentry.Integrations.CaptureConsole
这种集成捕获所有的 Console API
调用,并使用 captureMessage
调用将它们重定向到 Sentry
。然后,它会重新触发以保留默认的原生行为。
import * as Sentry from "@sentry/browser"; import { CaptureConsole as CaptureConsoleIntegration } from "@sentry/integrations"; Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new CaptureConsoleIntegration( { // array of methods that should be captured // defaults to ['log', 'info', 'warn', 'error', 'debug', 'assert'] levels: string[]; } )], });
CDN
<script src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js" integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr" crossorigin="anonymous" ></script> <script src="https://browser.sentry-cdn.com/6.12.0/captureconsole.min.js" integrity="sha384-FJ5n80A08NroQF9DJzikUUhiCaQT2rTIYeJyHytczDDbIiejfcCzBR5lQK4AnmVt" crossorigin="anonymous" ></script> Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new CaptureConsole( { // array of methods that should be captured // defaults to ['log', 'info', 'warn', 'error', 'debug', 'assert'] levels: string[]; } )], });
Debug
Import name: Sentry.Integrations.Debug
通过这种集成,您可以检查已处理事件的内容,该事件将被传递到 beforeSend
并有效地发送到 Sentry SDK
。无论何时注册,它都将始终作为最后的集成运行。
可用的选项:
import * as Sentry from "@sentry/browser"; import { Debug as DebugIntegration } from "@sentry/integrations"; Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new DebugIntegration( { // trigger DevTools debugger instead of using console.log debugger: boolean; // stringify event before passing it to console.log stringify: boolean; } )], });
CDN
<script src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js" integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr" crossorigin="anonymous" ></script> <script src="https://browser.sentry-cdn.com/6.12.0/debug.min.js" integrity="sha384-OIzIETBTnmaXcnCVlI4DzHq1+YxDdBS6uyZPp8yS60YZNUqzIQvrudJplBqEZ09K" crossorigin="anonymous" ></script> Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new Debug( { // trigger DevTools debugger instead of using console.log debugger: boolean; // stringify event before passing it to console.log stringify: boolean; } )], });
Offline
Import name: Sentry.Integrations.Offline
此集成使用 Web
浏览器的在线和离线事件
来检测何时没有可用的网络连接。如果离线,它会将事件保存到 Web
浏览器的客户端存储(通常是 IndexedDB
),然后在网络连接恢复时自动上传事件。
Online and offline events
此插件不会尝试为其他场景提供本地存储或重试。例如,如果浏览器有本地连接但没有互联网连接,那么它可能会报告它在线,并且在这种情况下,Sentry
的 Offline
插件不会尝试保存或重试任何发送失败。
import * as Sentry from "@sentry/browser"; import { Offline as OfflineIntegration } from "@sentry/integrations"; Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new OfflineIntegration( { // limit how many events will be localled saved. Defaults to 30. maxStoredEvents: number; } )], });
CDN
<script src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js" integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr" crossorigin="anonymous" ></script> <script src="https://browser.sentry-cdn.com/6.12.0/offline.min.js" integrity="sha384-rRq5WRQ3OncIj4lduaVZMtyfVwZnqeWXM0nXyXckOrhFLS2mlKEYX+VAlbLlIZL4" crossorigin="anonymous" ></script> Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new Offline( { // limit how many events will be localled saved. Defaults to 30. maxStoredEvents: number; } )], });
RewriteFrames
Import name: Sentry.Integrations.RewriteFrames
这种集成允许您对堆栈跟踪的每个帧应用转换。在流线型(streamlined
)场景中,它可用于更改其来源的文件帧的名称,或者可以使用迭代函数为其提供任意变换。
在 Windows
机器上,您必须使用 Unix
路径并跳过 root
选项中的卷号才能启用。例如 C:\\Program Files\\Apache\\www
将不起作用,但是 /Program Files/Apache/www
将起作用。
可用的选项:
import * as Sentry from "@sentry/browser"; import { RewriteFrames as RewriteFramesIntegration } from "@sentry/integrations"; Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new RewriteFramesIntegration( { // root path that will be stripped from the current frame's filename by the default iteratee if the filename is an absolute path root: string; // a custom prefix that will be used by the default iteratee (default: `app://`) prefix: string; // function that takes the frame, applies a transformation, and returns it iteratee: (frame) => frame; } )], });
CDN
<script src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js" integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr" crossorigin="anonymous" ></script> <script src="https://browser.sentry-cdn.com/6.12.0/rewriteframes.min.js" integrity="sha384-WOm9k3kzVt1COFAB/zCXOFx4lDMtJh/2vmEizIwgog7OW0P/dPwl3s8f6MdwrD7q" crossorigin="anonymous" ></script> Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new RewriteFrames( { // root path that will be stripped from the current frame's filename by the default iteratee if the filename is an absolute path root: string; // a custom prefix that will be used by the default iteratee (default: `app://`) prefix: string; // function that takes the frame, applies a transformation, and returns it iteratee: (frame) => frame; } )], });
使用示例:
例如,如果文件的完整路径是 /www/src/app/file.js
:
用法 | 堆栈跟踪中的路径 | 描述 |
RewriteFrames() | app:///file.js | 默认行为是替换除文件名之外的绝对路径,并使用默认前缀 (app:/// ) 作为前缀。 |
RewriteFrames({prefix: 'foo/'}) | foo/file.js | 使用前缀 foo/ 代替默认前缀 app:/// 。 |
RewriteFrames({root: '/www'}) | app:///src/app/file.js | root 定义为 /www ,因此仅从路径的开头修剪该部分。 |
ReportingObserver
Import name: Sentry.Integrations.ReportingObserver
此集成挂钩到 ReportingObserver API
并将捕获的事件发送到 Sentry
。它可以配置为仅处理特定的 issue
类型。
可用的选项:
import * as Sentry from "@sentry/browser"; import { ReportingObserver as ReportingObserverIntegration } from "@sentry/integrations"; Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new ReportingObserverIntegration( { types: <'crash'|'deprecation'|'intervention'>[]; } )], });
CDN
<script src="https://browser.sentry-cdn.com/6.12.0/bundle.min.js" integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr" crossorigin="anonymous" ></script> <script src="https://browser.sentry-cdn.com/6.12.0/reportingobserver.min.js" integrity="sha384-20D83MPBNSRANJFguhj0o9Qo7p9MCemwdMMQXotwA8742WuIwga85k+T7qEgIMWK" crossorigin="anonymous" ></script> Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [new ReportingObserver( { types: <'crash'|'deprecation'|'intervention'>[]; } )], });
React Router 集成
(适用于 5.21.0
及以上版本)
自 5.21.0
版起,@sentry/react
包中包含 React Router
支持。
注意:
React Router
集成旨在与我们的跟踪 SDK@sentry/tracing
一起使用。有关如何设置和安装 SDK 的更多详细信息,请参阅 React Performance 入门。https://docs.sentry.io/platforms/javascript/guides/react/performance/
我们支持 React Router 3、4 和 5
的集成。
React Router v4/v5
要使用 router integration
,请使用自定义 history
导入和设置自定义路由检测。确保将 Router
组件与 createBrowserHistory
(或等效的)结合使用。
import { Router } from 'react-router-dom'; import { createBrowserHistory } from 'history'; import * as Sentry from '@sentry/react'; import { Integrations } from '@sentry/tracing'; const history = createBrowserHistory(); Sentry.init({ integrations: [ new Integrations.BrowserTracing({ // Can also use reactRouterV3Instrumentation or reactRouterV4Instrumentation routingInstrumentation: Sentry.reactRouterV5Instrumentation(history), }), ], // We recommend adjusting this value in production, or using tracesSampler // for finer control tracesSampleRate: 1.0, }); // ... // In your App render: render() { return ( // Use custom history with a Router component <Router history={history}> <Components /> </Router> ); }
现在您应该使用 react router
检测从 BrowserTracing
集成生成 pageload/navigation
事务。
参数化事务名称
要获取参数化的交易名称(例如 /teams/:teamid/user/:userid
而不是 /teams/123/user/345
),您必须授予 SDK
访问路由渲染匹配路径的权限。这是因为 SDK
没有可以在 React Router v4/v5
中使用的静态路由配置。有两种方法可以实现这一点:
- 传递路由配置对象
您可以根据 react-router-config
传递一组路由配置对象。到检测函数调用。您还需要提供从 react-router-dom
或 react-router
包导出的 matchPath
函数。
import { Route, Router, Switch, matchPath } from 'react-router-dom'; import { createBrowserHistory } from 'history'; import * as Sentry from '@sentry/react'; import { Integrations } from '@sentry/tracing'; const history = createBrowserHistory(); // Array of Route Config Objects // Make sure the order of the routes is correct. The longest url under the same parent should be placed first and in decreasing order. const routes = [{ path: '/users/:userid' }, { path: '/users' }, { path: '/' }]; Sentry.init({ integrations: [ new Integrations.BrowserTracing({ routingInstrumentation: Sentry.reactRouterV5Instrumentation(history, routes, matchPath), }), ], // We recommend adjusting this value in production, or using tracesSampler // for finer control tracesSampleRate: 1.0, }); // In your App render: render() { return ( <Router history={history}> <Switch> <Route path="/users/:userid" component={() => <div>UserId</div>} /> <Route path="/users" component={() => <div>Users</div>} /> <Route path="/" component={() => <div>Home</div>} /> </Switch> </Router> ); }
- 使用 Sentry Route 组件
使用 withSentryRouting
高阶组件创建一个 SentryRoute
组件,该组件将在渲染时更新匹配路径。
import {Route, Router, Switch } from 'react-router-dom'; import { createBrowserHistory } from 'history'; import * as Sentry from '@sentry/react'; import { Integrations } from '@sentry/tracing'; // Create Custom Sentry Route component const SentryRoute = Sentry.withSentryRouting(Route); const history = createBrowserHistory(); Sentry.init({ integrations: [ new Integrations.BrowserTracing({ routingInstrumentation: Sentry.reactRouterV5Instrumentation(history), }), ], // We recommend adjusting this value in production, or using tracesSampler // for finer control tracesSampleRate: 1.0, }); render() { return ( <Router history={history}> <Switch> <SentryRoute path="/users/:userid" component={() => <div>UserId</div>} /> <SentryRoute path="/users" component={() => <div>Users</div>} /> <SentryRoute path="/" component={() => <div>Home</div>} /> </Switch> </Router> ); }
React Router v3
要使用 router integration
,请导入并设置自定义路由工具并将 history
、您的 routes
和 match
函数传递给它。React Router v3
对 React Router >= 3.2.0
和 < 4.0.0
的支持保持不变。
Redux 集成
(5.20.0 及以上版本可用)
自 5.20.0
版起,Redux
支持包含在 @sentry/react
包中。要将 Sentry
应用于 Redux
,请在初始化 Redux store
的同一位置使用 Sentry.createReduxEnhancer
。
import { createStore, compose } from "redux"; import * as Sentry from "@sentry/react"; // ... const sentryReduxEnhancer = Sentry.createReduxEnhancer({ // Optionally pass options listed below }); const store = createStore(rootReducer, sentryReduxEnhancer); // ...
如果您有其他增强器或中间件,例如 thunk
:
const store = createStore( rootReducer, compose(applyMiddleware(thunk), sentryReduxEnhancer) );
注意:
Sentry 使用 redux enhancer。通过 enhancer,如上所示。
不要将它传递给 applyMiddleware 并且在将它传递给 createStore 方法时不要调用该方法。
Normalization 深度
默认情况下,Sentry SDK
将任何上下文规范化为 3
的深度,在发送 Redux
状态的情况下,您可能希望增加该深度。您可以通过将 normalizeDepth
传递给 Sentry.init
调用来实现:
Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", normalizeDepth: 10, // Or however deep you want your state context to be. });
Redux Enhancer 选项
将选项对象作为第一个参数传递给 Sentry.createReduxEnhancer
以对其进行配置。
注意:
我们建议不要向 Sentry 发送敏感信息,但如果您这样做,我们将尽力过滤掉诸如用户密码之类的内容。
actionTransformer
(Function)
用于从 action
中删除敏感信息。传递给函数的第一个参数是 Redux action
。返回 null
以不向 Sentry
发送操作。默认情况下,我们发送所有 action
。
const sentryReduxEnhancer = Sentry.createReduxEnhancer({ actionTransformer: action => { if (action.type === "GOVERNMENT_SECRETS") { // Return null to not log the action to Sentry return null; } if (action.type === "SET_PASSWORD") { // Return a transformed action to remove sensitive information return { ...action, password: null, }; } return action; }, });
stateTransformer
(Function)
用于从 state
中删除敏感信息。传递给函数的第一个参数是 Redux state
。返回 null
以不将 state
附加到发送给 Sentry
的事件。请注意,如果您选择不向 Sentry
发送 state
,您的错误可能没有附加最新版本的 state
。默认情况下,我们附加所有 state
更改。
const sentryReduxEnhancer = Sentry.createReduxEnhancer({ stateTransformer: state => { if (state.topSecret.doNotSend) { // Return null to not send this version of the state. return null; } // Transform the state to remove sensitive information const transformedState = { ...state, topSecret: { ...state.topSecret, // Replace sensitive information with something else nuclearLaunchCodes: "I love pizza", // or just remove it entirely hiddenTreasureLocation: null, }, // You should also remove large data that is irrelevant to debugging to not clutter your Sentry issues giganticState: null, }; return transformedState; }, });
configureScopeWithState
(Function)
在每次 state
更新时调用,使用 Redux state
配置 Sentry Scope
。第一个参数是作用域,与调用 Sentry.configureScope
时得到的作用域实例相同,第二个参数是最新的 Redux state
。
const sentryReduxEnhancer = Sentry.createReduxEnhancer({ configureScopeWithState: (scope, state) => { // Set tag if the user is using imperial units. if (state.settings.useImperialUnits) { scope.setTag("user.usesImperialUnits", true); } }, });
自定义集成
使用以下格式向 JavaScript
添加自定义集成:
// All integration that come with an SDK can be found on Sentry.Integrations object // Custom integration must conform Integration interface: https://github.com/getsentry/sentry-javascript/blob/master/packages/types/src/integration.ts Sentry.init({ // ... integrations: [new MyAwesomeIntegration()], });
rrweb:Session 重播
Sentry
提供了与 rrweb
的概念验证集成 - 一个用于记录和重放用户会话的工具包。这在诊断丰富的单页应用程序中的复杂用户行为时非常有用。
更多信息:
- https://www.rrweb.io/
- https://docs.sentry.io/platforms/javascript/guides/react/configuration/filtering/#using-hints
- https://docs.sentry.io/platforms/javascript/guides/react/enriching-events/attachments/
配置
要开始,您需要添加 @sentry/rrweb
和 rrweb
包:
npm install --save @sentry/rrweb rrweb
接下来注册与 Sentry SDK
的集成。这将根据您使用的框架而有所不同:
// If you're using one of our integration packages, like `@sentry/react` or // `@sentry/angular`, substitute its name for `@sentry/browser` here import * as Sentry from "@sentry/browser"; import SentryRRWeb from "@sentry/rrweb"; Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [ new SentryRRWeb({ // ...options }), ], // ... });
捕获事件的重播后,您会在事件的“重播(Replay
)”部分下的“问题详细信息(Issue Details
)”中找到它。
采样
为了满足您组织的需求,您可能更喜欢对回放进行采样。最简单的方法是在初始化 Sentry SDK
时做出采样决定。例如,以下是 Sentry
本身如何使用抽样来仅为员工捕获这些信息:
const hasReplays = getCurrentUser().isStaff; let integrations = []; if (hasReplays) { console.log("[sentry] Instrumenting session with rrweb"); integrations.push(new SentryRRWeb()); } Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations, }); Sentry.setTag("rrweb.active", hasReplays ? "yes" : "no");
您会注意到我们还设置了 rrweb.active
标签,这有助于我们识别附加了重播(replay
)的事件,否则我们将无法找到它们。配置完成后,您就可以在搜索查询中简单地使用 rrweb.active:yes
。