Sentry For React 完整接入详解(2021 Sentry v21.8.x)前方高能预警!三万字,慎入!(一)

简介: Sentry For React 完整接入详解(2021 Sentry v21.8.x)前方高能预警!三万字,慎入!(一)

快速开始



SentryReact 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)生成 spanreact.mountreact.renderreact.update


react.mount

  • 表示被分析组件 mount 所需时间的跨度。

react.render

  • 表示被分析组件在页面上的时间跨度。只有在事务发生时 mountunmount 被分析的组件时,才会生成这个跨度。

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_DSNSENTRY_ENVIRONMENTSENTRY_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 integrationssource map uploads 同步。Release 名称是字符串,但是 Sentry 会检测到某些格式,并且它们的呈现方式可能有所不同。

更多:https://docs.sentry.io/product/releases/

默认情况下,SDK 会尝试从环境变量 SENTRY_RELEASE 中读取该值(在浏览器 SDK 中,将从 window.SENTRY_RELEASE 中读取该值,如果可用)。


environment

设置环境。此字符串为自由形式,默认情况下不设置。一个 release 可以与多个环境相关联,以便在 UI 中将它们分开(可以考虑stagingprod 或类似的方式)。

默认情况下,SDK 将尝试从 SENTRY_ENVIRONMENT 环境变量中读取该值(浏览器 SDK 除外)。


tunnel

设置将用于传输捕获事件的 URL,而不是使用 DSN。这可用于解决广告拦截器(ad-blockers)或对发送到 Sentry 的事件进行更精细的控制。此选项需要实现自定义服务器端点。

更多:https://docs.sentry.io/platforms/javascript/troubleshooting/#dealing-with-ad-blockers


sampleRate

配置错误事件的采样率,范围为 0.01.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

01 之间的数字,控制给定事务发送到 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 errorJavascript error: Script error 开头的错误。


要配置这个集成,直接使用 ignoreErrorsdenyUrls,和 allowUrls SDK 选项。请记住,denyURLallowURL 只对捕获的异常有效,而不是原始消息事件。

FunctionToString

Import name: Sentry.Integrations.FunctionToString

这种集成使 SDK 可以提供原始的函数和方法名称,即使我们的错误(error)或面包屑处理程序(breadcrumbs handlers)包装了它们也是如此。


TryCatch

Import name: Sentry.Integrations.TryCatch

这个集成封装了原生 timeevents 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,使用的键 keycause

可用的选项:


{
  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


此插件不会尝试为其他场景提供本地存储或重试。例如,如果浏览器有本地连接但没有互联网连接,那么它可能会报告它在线,并且在这种情况下,SentryOffline 插件不会尝试保存或重试任何发送失败。


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 中使用的静态路由配置。有两种方法可以实现这一点:


  1. 传递路由配置对象

您可以根据 react-router-config 传递一组路由配置对象。到检测函数调用。您还需要提供从 react-router-domreact-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>
  );
}


  1. 使用 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、您的 routesmatch 函数传递给它。React Router v3React 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 的概念验证集成 - 一个用于记录和重放用户会话的工具包。这在诊断丰富的单页应用程序中的复杂用户行为时非常有用。

更多信息:


微信图片_20220612180700.png

配置


要开始,您需要添加 @sentry/rrwebrrweb 包:


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

相关实践学习
Serverless极速搭建Hexo博客
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
存储 Web App开发 前端开发
Sentry For React 完整接入详解(2021 Sentry v21.8.x)前方高能预警!三万字,慎入!(二)
Sentry For React 完整接入详解(2021 Sentry v21.8.x)前方高能预警!三万字,慎入!(二)
714 0
|
Web App开发 存储 JSON
Sentry For React 完整接入详解(2021 Sentry v21.8.x)前方高能预警!三万字,慎入!(三)
Sentry For React 完整接入详解(2021 Sentry v21.8.x)前方高能预警!三万字,慎入!(三)
988 0
Sentry For React 完整接入详解(2021 Sentry v21.8.x)前方高能预警!三万字,慎入!(三)
|
6月前
|
监控 Ubuntu Docker
Sentry 监控 Docker 方式部署
Sentry 监控 Docker 方式部署
465 0
|
6月前
|
监控 前端开发 JavaScript
Sentry 监控部署与使用(详细流程)
Sentry 监控部署与使用(详细流程)
854 0
|
存储 监控 前端开发
Sentry 监控部署与使用(详细流程)
Sentry 监控部署与使用(详细流程)
6073 0
|
编解码 监控 前端开发
Sentry 监控 - Alerts 告警
Sentry 监控 - Alerts 告警
690 0
Sentry 监控 - Alerts 告警
|
监控 Ubuntu Unix
Sentry 监控 Docker 方式部署
Sentry 监控 Docker 方式部署
666 0
|
人工智能 监控 前端开发
大型网站重构指南 第1.3部分:前端监控和小程序监控 Sentry
大型网站重构指南 第1.3部分:前端监控和小程序监控 Sentry
1022 0
|
监控 前端开发 JavaScript
前端项目接入Sentry监控系统
本文适合项目需要接入错误监控的小伙伴阅读
前端项目接入Sentry监控系统
|
存储 SQL 监控
Sentry 监控 - Snuba 数据中台架构(Data Model 简介)
Sentry 监控 - Snuba 数据中台架构(Data Model 简介)
247 0
Sentry 监控 - Snuba 数据中台架构(Data Model 简介)