200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Sentry For Vue 完整接入详解( Sentry v21.8.x)前方高能预警!三万字 慎入!

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

时间:2018-08-26 11:13:48

相关推荐

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

内容源于:https://docs.sentry.io/platforms/javascript/guides/vue/

系列

1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source MapsSentry For React 完整接入详解

脑图

公众号:黑客下午茶

快速开始

SentrySDK支持自动报告错误和异常。

安装

Sentry通过在应用程序runtime使用SDK捕获数据。

# 使用 npmnpm install --save @sentry/vue @sentry/tracing# 使用 yarnyarn add @sentry/vue @sentry/tracing

配置

配置应该在应用程序的生命周期中尽早进行。

要在您的Vue应用程序中初始化Sentry,请将其添加到您的app.js中:

Vue2

import Vue from "vue";import Router from "vue-router";import * as Sentry from "@sentry/vue";import { Integrations } from "@sentry/tracing";Vue.use(Router);const router = new Router({// ...});Sentry.init({Vue,dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",integrations: [new Integrations.BrowserTracing({routingInstrumentation: Sentry.vueRouterInstrumentation(router),tracingOrigins: ["localhost", "my-site-", /^\//],}),],// Set tracesSampleRate to 1.0 to capture 100%// of transactions for performance monitoring.// We recommend adjusting this value in productiontracesSampleRate: 1.0,});// ...new Vue({router,render: h => h(App),}).$mount("#app");

Vue3

import { createApp } from "vue";import { createRouter } from "vue-router";import * as Sentry from "@sentry/vue";import { Integrations } from "@sentry/tracing";const app = createApp({// ...});const router = createRouter({// ...});Sentry.init({app,dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",integrations: [new Integrations.BrowserTracing({routingInstrumentation: Sentry.vueRouterInstrumentation(router),tracingOrigins: ["localhost", "my-site-", /^\//],}),],// Set tracesSampleRate to 1.0 to capture 100%// of transactions for performance monitoring.// We recommend adjusting this value in productiontracesSampleRate: 1.0,});app.use(router);app.mount("#app");

此外,Vue 3允许您使用具有相同Sentry SDK实例的多个应用程序,以及在SDK已经初始化后动态添加更多应用程序。

Vue 3 - 多个 App

const appOne = Vue.createApp(App);const appTwo = Vue.createApp(App);const appThree = Vue.createApp(App);Sentry.init({app: [appOne, appTwo, appThree],});

Vue 3 - 手动初始化

import * as Sentry from "@sentry/vue";// ...const app = createApp(App);Sentry.init({app,// ...});const miscApp = createApp(MiscApp);miscApp.mixin(Sentry.createTracingMixins({ trackComponents: true }));Sentry.attachErrorHandler(miscApp, { logErrors: true });

SDK接受一些不同的配置选项,可让您更改其行为:

attachProps(默认为true)- 包括所有Vue组件的带有事件的属性(props)。logErrors(默认为false) - 决定SDK是否也应该调用Vue的原始logError函数。trackComponents(默认为false)- 决定是否通过hooking到其生命周期方法来跟踪组件。可以设置为布尔值(boolean),以启用/禁用对所有组件的跟踪,或设置为特定组件名称的数组(区分大小写)。timeout(默认为2000)- 以毫秒为单位的时间,指示等待被跟踪的根活动标记为完成(finished)并发送给Sentry的时间。hooks(默认为['activate', 'mount', 'update'])- 在组件生命周期'activate' | 'create' | 'destroy' | 'mount' | 'unmount' | 'update'期间要跟踪的hooks列表。

如果启用SDKVue将不会在内部调用其logError。因此,Vue渲染器中发生的错误将不会显示在开发人员控制台中。要保留此功能,请传递logErrors:true选项。

验证

此代码段包含一个故意错误,因此您可以在设置后立即测试一切是否正常:

向页面添加一个引发错误的按钮:

// ...<button @click="throwError">Throw error</button>// ...export default {// ...methods: {throwError() {throw new Error('Sentry Error');}}};

配置

基本选项

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。因此,如果你添加,它也会匹配/myfile/。默认情况下,将发送所有错误。

allowUrls

匹配错误URL的字符串列表或正则表达式模式的遗留别名,这些错误URL应该专门发送给Sentry。默认情况下,将发送所有错误。这是一个 “contains(包含)” 匹配整个文件 URL。因此,如果您将添加到它,它也将匹配/myfile/。默认情况下,所有错误将被发送。

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@"},}});

回调函数:

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

这些选项可用于以各种方式 hookSDK,以定制事件的报告。

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,和allowUrlsSDK 选项。请记住,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

<scriptsrc="https://browser.sentry-/6.12.0/bundle.min.js"integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"crossorigin="anonymous"></script><scriptsrc="https://browser.sentry-/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 integrationsreturn 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

<scriptsrc="https://browser.sentry-/6.12.0/bundle.min.js"integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"crossorigin="anonymous"></script><scriptsrc="https://browser.sentry-/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

<scriptsrc="https://browser.sentry-/6.12.0/bundle.min.js"integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"crossorigin="anonymous"></script><scriptsrc="https://browser.sentry-/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

<scriptsrc="https://browser.sentry-/6.12.0/bundle.min.js"integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"crossorigin="anonymous"></script><scriptsrc="https://browser.sentry-/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.logdebugger: boolean;// stringify event before passing it to console.logstringify: boolean;})],});

CDN

<scriptsrc="https://browser.sentry-/6.12.0/bundle.min.js"integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"crossorigin="anonymous"></script><scriptsrc="https://browser.sentry-/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.logdebugger: boolean;// stringify event before passing it to console.logstringify: boolean;})],});

Offline

Import name:Sentry.Integrations.Offline

此集成使用Web浏览器的在线和离线事件来检测何时没有可用的网络连接。如果离线,它会将事件保存到Web浏览器的客户端存储(通常是IndexedDB),然后在网络连接恢复时自动上传事件。

Online and offline events

/en-US/docs/Web/API/Navigator/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

<scriptsrc="https://browser.sentry-/6.12.0/bundle.min.js"integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"crossorigin="anonymous"></script><scriptsrc="https://browser.sentry-/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 pathroot: 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 ititeratee: (frame) => frame;})],});

CDN

<scriptsrc="https://browser.sentry-/6.12.0/bundle.min.js"integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"crossorigin="anonymous"></script><scriptsrc="https://browser.sentry-/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 pathroot: 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 ititeratee: (frame) => frame;})],});

使用示例:

例如,如果文件的完整路径是/www/src/app/file.js

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

<scriptsrc="https://browser.sentry-/6.12.0/bundle.min.js"integrity="sha384-S3qfdh3AsT1UN84WIYNuOX9vVOoFg3nB17Jp5/pTFGDBGBt+dtz7MGAV845efkZr"crossorigin="anonymous"></script><scriptsrc="https://browser.sentry-/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'>[];})],});

Vue Router 集成

Vue跟踪集成允许您在初始应用程序加载期间跟踪渲染性能。

Sentry使用mixins功能在其生命周期阶段提供对Vue组件的访问。

Sentry遇到一个名为root的组件,它是一个顶级Vue实例(如new Vue({})),

我们使用我们的BrowserTracing集成,并创建一个名为Vue Application Render的新跨度。

一旦创建了Vue Application Render跨度,它将等待它的所有子组件都渲染完毕,然后才将跨度标记为完成(finished)。

所描述的检测功能将为您提供有关Vue实例渲染性能的非常高级的信息。

但是,集成还可以提供有关特定活动期间实际发生的情况的更细粒度的详细信息。 为此,您需要指定要跟踪的组件和要侦听的钩子(/v2/api/#Options-Lifecycle-Hooks)。

您还可以为所有组件打开跟踪。但是,如果您的应用程序由数百个组件组成,则可能会相当嘈杂。

我们鼓励更具体。如果您不提供hooksSentry将跟踪组件的mountupdate钩子。

请注意,在指定hooks时,我们使用简单动词而不是before-ed对。

例如,destroy是正确的。beforeDestroydestroyed是不正确的。

要设置Vue Tracing集成,您首先需要配置BrowserTracing集成本身。

有关如何执行此操作的详细信息,请查看我们的性能文档。

配置完BrowserTracing集成后,继续配置Vue集成本身。Sentry将新的跟踪功能构建到原始Vue错误处理程序集成中,因此无需添加任何新包。

您只需要提供适当的配置。

跟踪Vue应用程序的最基本配置(仅跟踪顶级组件)如下所示:

import Vue from "vue";import * as Sentry from "@sentry/browser";import { Integrations } from "@sentry/tracing";Sentry.init({// ...integrations: [new Integrations.BrowserTracing()],// We recommend adjusting this value in production, or using tracesSampler// for finer controltracesSampleRate: 1.0,});

如果要跟踪子组件,并查看有关渲染过程的更多详细信息,请配置集成以跟踪它们:

Sentry.init({Vue,trackComponents: true,});

或者,您可以选择更多粒度:

Sentry.init({Vue,integrations: [new Integrations.BrowserTracing()],trackComponents: ["App","RwvHeader","RwvFooter","RwvArticleList","Pagination",],});

例如,如果您想知道某些组件是否在初始页面加载期间被删除,请向默认值添加一个destroy钩子:

Sentry.init({Vue,integrations: [new Integrations.BrowserTracing()],trackComponents: ["App","RwvHeader","RwvFooter","RwvArticleList","Pagination",],hooks: ["mount", "update", "destroy"],});

您可以指定顶级活动应等待最后一个组件渲染的时间。

每个新的渲染周期都会消除超时的抖动,并从头开始计数。

一旦达到超时,跟踪就完成了,所有的信息都会发送给Sentry

Sentry.init({Vue,integrations: [new Integrations.BrowserTracing()],trackComponents: true,timeout: 4000,});

配置

tracingOptions: {/*** Decides whether to track components by hooking into its lifecycle methods.* Can be either set to `boolean` to enable/disable tracking for all of them.* Or to an array of specific component names (case-sensitive).* Default: false*/trackComponents: boolean | string[];/*** How long to wait (in ms) until the tracked root activity is marked as finished and sent to Sentry* Default: 2000*/timeout: number;/*** List of hooks to keep track of during component lifecycle.* Available hooks: 'activate' | 'create' | 'destroy' | 'mount' | 'unmount' | 'update'* Based on /v2/api/#Options-Lifecycle-Hooks*/hooks: string[];}

使用 Vue Router

如果您使用Vue Router,您可以使用我们提供的集成来获得更好的transaction名称。这是如何使用它的完整示例:

import Vue from "vue";import App from "./App";import * as Sentry from "@sentry/vue";import { Integrations } from "@sentry/tracing";import Router from "vue-router";import HelloWorld from "@/components/HelloWorld";Vue.use(Router);const Foo = { template: "<div>foo</div>" };const Bar = { template: "<div>bar</div>" };const router = new Router({routes: [{path: "/",name: "HelloWorld",component: HelloWorld,},{ path: "/foo/:id", component: Foo },{ path: "/bar", component: Bar },],});Vue.config.productionTip = false;Sentry.init({Vue: Vue,dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",tracesSampleRate: 1.0,integrations: [new Integrations.BrowserTracing({routingInstrumentation: Sentry.vueRouterInstrumentation(router),}),],trackComponents: true,});/* eslint-disable no-new */new Vue({el: "#app",router,components: { App },template: "<App/>",});

自定义集成

使用以下格式向JavaScript添加自定义集成:

// All integration that come with an SDK can be found on Sentry.Integrations object// Custom integration must conform Integration interface: /getsentry/sentry-javascript/blob/master/packages/types/src/integration.tsSentry.init({// ...integrations: [new MyAwesomeIntegration()],});

rrweb:Session 重播

Sentry提供了与rrweb的概念验证集成 - 一个用于记录和重放用户会话的工具包。 这在诊断丰富的单页应用程序中的复杂用户行为时非常有用。

更多信息:

https://www.rrweb.io/https://docs.sentry.io/platforms/javascript/guides/react/configuration/filtering/#using-hintshttps://docs.sentry.io/platforms/javascript/guides/react/enriching-events/attachments/

配置

要开始,您需要添加@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` hereimport * 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)”中找到它。

更多:/getsentry/sentry-rrweb

采样

为了满足您组织的需求,您可能更喜欢对回放进行采样。最简单的方法是在初始化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

Release & 运行状况

Release是部署到环境中的代码版本。当您向 Sentry 提供有关您的版本的信息时,您可以:

确定新版本中引入的问题和回归预测哪个提交导致了问题以及谁可能负责通过在提交消息中包含问题编号来解决问题部署代码时接收电子邮件通知

此外,release用于将source maps应用于被压缩的 JavaScript 以查看原始的、未转换的源代码。

绑定版本

配置客户端SDK时包含release ID(通常称为“版本version”)。

release名称不能:

包含换行符、制表符、正斜杠 (/) 或反斜杠 (\)是(全部)句号 (.)、双句号 (..) 或空格 ()超过200个字符

该值可以是任意的,但我们推荐以下任一命名策略:

语义版本控制:package@versionpackage@version+build(例如,my.project.name@2.3.12+1234)packageproject/app的唯一标识符(iOS上的CFBundleIdentifierAndroid上的packageName)version是类似于semver的结构<major>.<minor?>.<patch?>.<revision?>-<prerelease?>(iOS上的CFBundleShortVersionStringAndroid上的versionName)build是标识app迭代的数字(iOS上的CFBundleVersionAndroid上的versionCode)Commit SHA:如果您使用DVCS,我们建议使用标识哈希 identifying hash(例如,commit SHAda39a3ee5e6b4b0d3255bfef95601890afd80709)。您可以让Sentry CLI使用sentry-clireleases proposal-version为支持的版本控制系统自动确定此哈希值。

每个组织的发布都是全局性的;为它们添加特定于项目的前缀,以便于区分。

Sentry.init({release: "my-project-name@2.3.12",});

Node/npm环境中使用JavaScript执行此操作的一种常见方法是使用process.env.npm_package_version,如下所示:

更多:/misc/scripts#packagejson-vars

Sentry.init({release: "my-project-name@" + process.env.npm_package_version,});

您如何使版本(version)可用于您的代码取决于您。例如,您可以使用在构建过程中设置的环境变量。

这用release值标记每个事件。我们建议您在部署之前告诉Sentry一个新release,因为这将解锁我们关于releases的文档中讨论的更多功能。但是,如果您不这样做,Sentry将在第一次看到具有该release ID的事件时自动在系统中创建一个release实体。

release:https://docs.sentry.io/product/releases/

配置您的SDK后,您可以安装repository integration或手动为Sentry提供您自己的commit metadata。 阅读我们关于设置 releases的文档,以获取有关集成 integrations关联提交 associating commits以及在部署releases时通知Sentry的更多信息。

设置 releases: https://docs.sentry.io/product/releases/setup/

Release 运行状况

通过观察用户采用情况、应用程序使用情况、崩溃百分比和会话数据来监控release的运行状况。release运行状况将深入了解与用户体验相关的崩溃和错误的影响,并通过release详细信息、图表和过滤器揭示每个新问题的趋势。

health of releases : https://docs.sentry.io/product/releases/health/crashes:https://docs.sentry.io/product/releases/health/#crashsession data:https://docs.sentry.io/product/releases/health/#session

SDK将在SDK初始化时自动管理会话的开始和结束。

我们为每个页面加载创建一个会话。对于单页应用程序,我们将为每次导航更改(History API)创建一个新会话。

我们将会话标记为:

如果unhandled errorunhandled promise rejection冒泡到全局处理程序,则崩溃。如果SDK捕获包含异常的事件(这包括手动捕获的错误),则会出现错误。

要接收有关用户采用的数据,例如用户崩溃率百分比和采用特定版本的用户数,请在初始化SDK时将用户设置在initialScope上。

默认情况下,JavaScript SDK正在发送会话。

要禁用发送会话,请将autoSessionTracking标志设置为false

Sentry.init({autoSessionTracking: false // default: true});

环境

Sentry在收到带有environment标签的事件时会自动创建环境。环境区分大小写。 环境名称不能包含换行符、空格或正斜杠,不能是字符串“None”或超过64个字符。 您无法删除环境,但可以隐藏它们。

hidden-environments: https://docs.sentry.io/product/sentry-basics/environments/#hidden-environments

Sentry.init({environment: "production",});

环境可帮助您在sentry.io的问题详细信息页面中更好地过滤问题、版本和用户反馈,您可以在我们涵盖使用环境的文档中了解更多信息。

environments:https://docs.sentry.io/product/sentry-basics/environments/

过滤

将 Sentry 添加到您的应用程序可为您提供大量关于错误和性能的非常有价值的信息,否则您将无法获得这些信息。 大量的信息是好的——只要它是正确的信息,并且数量合理。

Sentry SDK有几个配置选项可以帮助您过滤事件。

我们还提供入站过滤器 Inbound Filters来过滤sentry.io中的事件。 不过,我们建议在客户端级别进行过滤,因为它消除了发送您实际上不想要的事件的开销。 了解有关事件中可用字段的更多信息。

Inbound Filters: https://docs.sentry.io/product/data-management-settings/filtering/fields available in an event:https://develop.sentry.dev/sdk/event-payloads/

过滤错误事件

通过使用beforeSend回调方法和配置、启用或禁用集成来配置您的SDK以过滤错误事件。

使用 beforeSend

所有Sentry SDK都支持beforeSend回调方法。beforeSend在事件发送到服务器之前立即调用,因此它是您可以编辑其数据的最后位置。它将事件对象作为参数接收,因此您可以使用该参数根据自定义逻辑和事件上可用的数据修改事件的数据或完全删除它(通过返回null)。

Sentry.init({// ...beforeSend(event, hint) {const error = hint.originalException;if (error &&error.message &&error.message.match(/database unavailable/i)) {event.fingerprint = ["database-unavailable"];}return event;},});

还要注意,正如我们的breadcrumbs文档中所讨论的,breadcrumbs可以被过滤。

breadcrumbs: https://docs.sentry.io/product/error-monitoring/breadcrumbs/

Event Hints

before-send回调传递event和第二个参数hint,该参数包含一个或多个hints

通常,hint保存原始异常,以便可以提取附加数据或影响分组。 在本例中,如果捕获到某种类型的异常,指纹将被强制为一个公共值:

Sentry.init({// ...beforeSend(event, hint) {const error = hint.originalException;if (error &&error.message &&error.message.match(/database unavailable/i)) {event.fingerprint = ["database-unavailable"];}return event;},});

有关哪些hints可用的信息,请参阅:

hints in JavaScript: https://docs.sentry.io/platforms/javascript/guides/react/configuration/filtering/#using-hints

SDK创建用于传输(transmission)的事件或面包屑时,该传输通常是从某种源对象创建的。例如,错误事件通常是从日志记录或异常实例中创建的。为了更好地定制,SDK 将这些对象发送到某些回调(beforeSendbeforeBreadcrumb或 SDK 中的事件处理器系统)。

使用 Hints

Hints可在两个地方获得:

beforeSend / beforeBreadcrumbeventProcessors

事件和面包屑hints是包含用于组合事件或面包屑的各种信息的对象。 通常hints保存原始异常,以便可以提取附加数据或影响分组。

对于事件,例如event_idoriginalExceptionsyntheticException(在内部用于生成更清晰的堆栈跟踪)以及您附加的任何其他任意数据。

对于面包屑,hints的使用取决于实现。对于XHR请求,hint包含xhr对象本身;对于用户交互,提示包含DOM元素和事件名称等。

在本例中,如果捕获到某种类型的异常,指纹将被强制为一个公共值:

Sentry.init({// ...beforeSend(event, hint) {const error = hint.originalException;if (error &&error.message &&error.message.match(/database unavailable/i)) {event.fingerprint = ["database-unavailable"];}return event;},});

Hints for Events

originalException

导致Sentry SDK创建事件的原始异常。这对于更改Sentry SDK分组事件的方式或提取附加信息很有用。

syntheticException

当引发字符串(string)或非错误(non-error)对象时,Sentry 会创建一个合成异常(synthetic exception),以便您可以获得基本的堆栈跟踪。 此异常存储在此处以供进一步提取数据。

Hints for Breadcrumbs

event

对于从浏览器事件创建的面包屑,Sentry SDK通常将事件作为hint提供给面包屑。例如,这可用于将目标 DOM 元素中的数据提取到面包屑中。

level / input

对于从控制台日志(console.log)拦截创建的面包屑。 这保存了原始console log levellog function的原始输入数据。

response / input

对于从HTTP请求创建的面包屑。它保存响应对象(来自fetch API)和fetch函数的输入参数。

request / response / event

对于从HTTP请求创建的面包屑。这包含请求和响应对象(来自node HTTP API)以及node event(responseerror)。

xhr

对于通过遗留XMLHttpRequest API完成的HTTP请求创建的面包屑。这保存了原始的xhr对象。

整理 Sentry

您可以构建一个允许的域列表,这些域可能会引发可接受的异常。 例如,如果您的脚本是从加载的并且您的站点是,您可以将allowUrls设置为:

Sentry.init({allowUrls: [/https?:\/\/((cdn|www)\.)?example\.com/]});

如果您想永远阻止特定的URL,您也可以使用denyUrls

Note

5.17.0版本之前,allowUrlsdenyUrls分别称为whitelistUrlsblacklistUrls

出于向后兼容性的原因,这些选项仍受支持,但它们将在6.0版中删除。 有关更多信息,请参阅

Inclusive Language Policy:https://develop.sentry.dev/inclusion/

此外,我们的社区还为日常事务编制了一份常见的忽略规则列表,例如FacebookChrome extensions等。 这很有用,建议您检查一下这些内容,看看它们是否适用于您。这不是我们 SDK 的默认值; 这只是一个广泛示例的一个亮点。

Here is the original gist:/impressiver/5092952

Sentry.init({ignoreErrors: [// Random plugins/extensions"top.GLOBALS",// See: //03/tale-of-unfindable-js-error.html"originalCreateNotification","canvas.contentDocument","MyApp_RemoveAllHighlights","","Can't find variable: ZiteReader","jigsaw is not defined","ComboSearch is not defined","http://loading./","atomicFindClose",// Facebook borked"fb_xd_fragment",// ISP "optimizing" proxy - `Cache-Control: no-transform` seems to// reduce this. (thanks @acdha)// See /questions/4113268"bmi_SafeAddOnload","EBCallBackMessageReceived",// See /Developer/HtmlAndGadget/Methods/JSInjection.aspx"conduitPage",],denyUrls: [// Facebook flakiness/graph\.facebook\.com/i,// Facebook blocked/connect\.facebook\.net\/en_US\/all\.js/i,// Woopra flakiness/eatdifferent\.com\.woopra-ns\.com/i,/static\.woopra\.com\/js\/woopra\.js/i,// Chrome extensions/extensions\//i,/^chrome:\/\//i,// Other plugins/127\.0\.0\.1:4001\/isrunning/i, // Cacaoweb/webappstoolbarba\.texthelp\.com\//i,/metrics\.itunes\.apple\.com\.edgesuite\.net\//i,],});

使用采样过滤 Transaction 事件

为了防止某些transactions被报告给Sentry,请使用tracesSampler配置选项,它允许您提供一个函数来评估当前transaction并在它不是您想要的时候删除它。 (它还允许您以不同的采样率对不同的transaction进行抽样。)

注意:tracesSamplertracesSampleRate配置选项是互斥的。 如果您定义了一个tracesSampler来过滤掉某些transaction,您还必须通过返回您希望对它们进行采样的速率来处理未过滤transaction的情况。

最简单的形式,仅用于过滤transaction,它看起来像这样:

Sentry.init({// ...tracesSampler: samplingContext => {if ("...") {// Drop this transaction, by setting its sample rate to 0%return 0;} else {// Default sample rate for all others (replaces tracesSampleRate)return 0.1;}};});

关闭与清空

大多数SDK的默认行为是在后台通过网络异步发送事件。 这意味着如果应用程序意外关闭,某些事件可能会丢失。SDK提供了处理这种情况的机制。

close方法可选地接受以毫秒为单位的timeout,并返回一个promise,该promise在刷新所有挂起事件或timeout生效时resolve

Sentry.close(2000).then(function() {// perform something after close});

调用close后,不能再使用当前客户端。 仅在关闭应用程序之前立即调用close很重要。

或者,flush方法清空事件队列,同时保持客户端启用以供继续使用。

采样

Sentry添加到您的应用程序可为您提供大量关于错误和性能的非常有价值的信息,否则您将无法获得这些信息。 大量的信息是好的——只要它是正确的信息,并且数量合理。

采样 Error 事件

要将具有代表性的错误样本发送到Sentry,请将SDK配置中的sampleRate选项设置为0(发送的错误的0%)和1(发送的错误的100%)之间的数字。 这是一个静态比率,它同样适用于所有错误。例如,要对25%的错误进行抽样:

Sentry.init({ sampleRate: 0.25 });

更改错误采样率需要重新部署。

此外,设置SDK采样率会限制对事件源的可见性。

为您的项目设置速率限制(仅在volume高时丢弃事件)可能更适合您的需求。

采样 Transaction 事件

我们建议对您的transaction进行抽样,原因有两个:

捕获单个跟踪涉及的开销最小,但捕获每个页面加载或每个 API 请求的跟踪可能会给您的系统增加不必要的负载。启用采样可以让您更好地管理发送到 Sentry 的事件数量,因此您可以根据组织的需求定制您的数量。

选择采样率的目标是在性能和数量问题与数据准确性之间找到平衡。 您不想收集太多数据,但希望收集足够的数据以得出有意义的结论。 如果您不确定要选择什么速率,请从一个较低的值开始,随着您对流量模式和流量的了解越来越多,逐渐增加它。

配置 Transaction 采样率

Sentry SDK有两个配置选项来控制发送到Sentrytransaction量,让您可以获取具有代表性的样本:

统一采样率(tracesSampleRate): 提供均匀的事务横截面,无论它们在您的应用程序中的哪个位置或在什么情况下发生。使用默认继承(inheritance)和优先(precedence)行为 采样函数(tracesSampler)其中: 以不同的速率采样不同的transaction完全过滤掉一些transaction修改默认优先级和继承行为

inheritance: https://docs.sentry.io/platforms/javascript/guides/react/configuration/sampling/#inheritance

precedence:https://docs.sentry.io/platforms/javascript/guides/react/configuration/sampling/#precedence

Filters:https://docs.sentry.io/platforms/javascript/guides/react/configuration/filtering/

设置统一采样率

为此,请将Sentry.init()中的tracesSampleRate选项设置为01之间的数字。设置此选项后,创建的每个transaction都有该百分比的机会被发送到Sentry。(因此,例如,如果您将tracesSampleRate设置为0.2,大约20%transaction将被记录和发送。)看起来像这样:

Sentry.init({// ...tracesSampleRate: 0.2,});

设置采样函数

要使用采样函数,请将Sentry.init()中的tracesSampler选项设置为一个函数,该函数将接受samplingContext对象并返回介于01之间的采样率。例如:

Sentry.init({// ...tracesSampler: samplingContext => {// Examine provided context data (including parent decision, if any) along// with anything in the global namespace to compute the sample rate or// sampling decision for this transactionif ("...") {// These are important - take a big samplereturn 0.5;} else if ("...") {// These are less important or happen much more frequently - only take 1%return 0.01;} else if ("...") {// These aren't something worth tracking - drop all transactions like thisreturn 0;} else {// Default sample ratereturn 0.1;}};});

为方便起见,该函数还可以返回一个布尔值。返回true等同于返回1,并且将保证transaction将发送到Sentry。返回false相当于返回0,并保证transaction不会被发送到Sentry

采样 Context 数据

默认采样 Context 数据

transaction事务时传递给tracesSamplerSamplingContext对象中包含的信息因平台和集成(integration)而异。

对于基于浏览器的SDK,它至少包括以下内容:

// contents of `samplingContext`{transactionContext: {name: string; // human-readable identifier, like "GET /users"op: string; // short description of transaction type, like "pageload"}parentSampled: boolean; // if this transaction has a parent, its sampling decisionlocation: Location | WorkerLocation; // the window.location or self.location object... // custom context as passed to `startTransaction`}

自定义采样 Context 数据

使用自定义检测创建transaction时,您可以通过将数据作为可选的第二个参数传递给startTransaction来将数据添加到samplesContext。 如果您希望采样器可以访问某些数据,但又不想将其作为标签(tag)或数据(data)附加到transaction中,例如敏感信息或太大而无法与transaction一起发送的信息,这将非常有用。例如:

Sentry.startTransaction({// `transactionContext` - will be recorded on transactionname: 'Search from navbar',op: 'search',tags: {testGroup: 'A3',treatmentName: 'eager load',},},// `customSamplingContext` - won't be recorded{// PIIuserId: '1231',// too big to sendresultsFromLastSearch: { ... }},);

继承

无论transaction的抽样决策如何,该决策都将传递到其子跨度,并从那里传递到它们随后在其他服务中引起的任何transaction。 (有关如何完成传播的更多信息,请参阅连接服务。)

Connecting Services: https://docs.sentry.io/platforms/javascript/performance/

如果当前正在创建的transaction是那些后续事务之一(换句话说,如果它有父transaction),则上游(父)采样决策将始终包含在采样上下文数据中,以便您的tracesSampler可以选择是否和何时继承该决策。 (在大多数情况下,继承是正确的选择,以避免部分跟踪痕迹。)

在某些SDK中,为了方便起见,tracesSampler函数可以返回一个布尔值,这样如果这是所需的行为,则可以直接返回父级的决策。

tracesSampler: samplingContext => {// always inheritif (samplingContext.parentSampled !== undefined) {return samplingContext.parentSampled}...// rest of sampling logic here}

如果您使用的是tracesSampleRate而不是tracesSampler,则决策将始终被继承。

强制抽样决策

如果您在transaction创建时知道是否要将transaction发送到Sentry,您还可以选择将采样决策直接传递给transaction构造函数(注意,不是在customSamplingContext对象中)。如果您这样做,transaction将不受tracesSampleRate的约束,也不会运行tracesSampler,因此您可以指望通过的决策不会被覆盖。

Sentry.startTransaction({name: "Search from navbar",sampled: true,});

优先级

transaction以多种方式结束抽样决策。

根据tracesSampleRate中设置的静态采样率随机采样根据tracesSampler采样函数返回的采样率随机采样tracesSampler返回的绝对决策(100%机会或0%机会)如果transaction有父级,继承其父级的抽样决策绝对决策传递给startTransaction

当有可能不止一个发挥作用时,以下优先规则适用:

如果将抽样决策传递给startTransaction(请参阅上面的强制抽样决策),则将使用该决策,而不管其他任何事情如果定义了tracesSampler,则将使用其决策。 它可以选择保留或忽略任何父采样决策,或使用采样上下文数据来做出自己的决策或为transaction选择采样率。如果未定义tracesSampler,但存在父采样决策,则将使用父采样决策。如果未定义tracesSampler并且没有父采样决策,则将使用tracesSampleRate

Sentry Testkit

在为您的应用程序构建测试时,您希望断言正确的流跟踪(flow-tracking)或错误正在发送到Sentry,但没有真正将其发送到Sentry服务器。 这样您就不会在测试运行或其他 CI 操作期间用错误报告淹没Sentry

注意:Sentry 合作伙伴Wix维护 Sentry Testkit。

Wix:https://wix.github.io/sentry-testkit/

Sentry Testkit是一个Sentry插件,它允许拦截 Sentry 的report并进一步检查正在发送的数据。它使Sentry能够在您的应用程序中原生工作,并且通过覆盖默认Sentry的传输机制(transport mechanism),报告不会真正发送,而是本地记录到内存中。 这样,您可以稍后获取记录的报告以供您自己使用、验证或您在本地开发/测试环境中可能拥有的任何其他用途。

Sentry Testkit: https://wix.github.io/sentry-testkit/

安装

npm install sentry-testkit --save-dev

在测试中使用

const sentryTestkit = require("sentry-testkit");const { testkit, sentryTransport } = sentryTestkit();// initialize your Sentry instance with sentryTransportSentry.init({dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",transport: sentryTransport,//... other configurations});// then run any scenario that should call Sentry.catchException(...)expect(testkit.reports()).toHaveLength(1);const report = testkit.reports()[0];expect(report).toHaveProperty(/*...*/);

您也可以在sentry-testkit存储库的测试部分看到更多使用示例。

testing section: /wix/sentry-testkit/tree/master/test

Testkit API

Sentry Testkit 由一个非常简单直接的 API 组成。 请参阅 Sentry Testkit Docs 中的完整 API 描述和文档。

Sentry Testkit Docs: https://wix.github.io/sentry-testkit/

用法

SentrySDK与您的运行时环境挂钩,并根据平台自动报告错误、未捕获的异常和未处理的拒绝以及其他类型的错误。

关键术语:

event是向Sentry发送数据的一个实例。 通常,此数据是错误(error)或异常(exception)。issue是一组相似的事件。事件的报告称为捕获(capturing)。当一个事件被捕获时,它被发送到Sentry

最常见的捕获形式是捕获错误。可以捕获为错误的内容因平台而异。 一般来说,如果你有一些看起来像异常的东西,它可以被捕获。对于某些SDK,您还可以省略captureException的参数,Sentry将尝试捕获当前异常。它对于手动向Sentry报告错误或消息也很有用。

在捕获事件时,您还可以记录导致该事件的面包屑(breadcrumbs)。 面包屑与事件不同:它们不会在 Sentry 中创建事件,而是会被缓冲,直到发送下一个事件。 在我们的面包屑文档中了解有关面包屑的更多信息。

breadcrumbs: https://docs.sentry.io/platforms/javascript/guides/react/enriching-events/breadcrumbs/

捕获 Errors

通过包含和配置Sentry,我们的React SDK会自动附加全局处理程序(global handlers)来捕获未捕获的异常和未处理的promise拒绝,如官方ECMAScript 6标准中所述。您可以通过在GlobalHandlers集成中将onunhandledrejection选项更改为false并手动挂接到每个事件处理程序,然后直接调用Sentry.captureExceptionSentry.captureMessage来禁用此默认行为。

您可以将Error对象传递给captureException()以将其捕获为事件。也可以传递非 Error(non-Error) 对象和字符串(string),但请注意Sentry中的结果事件(resulting events)可能会丢失堆栈跟踪。

import * as Sentry from "@sentry/react";try {aFunctionThatMightFail();} catch (err) {Sentry.captureException(err);}

捕获 Messages

另一种常见的操作是捕获裸消息。消息是应该发送给Sentry的文本信息。通常不会发出消息,但它们对某些团队很有用。

Sentry.captureMessage("Something went wrong");

设置 Level

级别 - 类似于日志级别 - 通常基于集成默认添加。 您还可以在事件中覆盖它。

要设置超出范围的级别,您可以为每个事件调用captureMessage()

Sentry.captureMessage("this is a debug message", "debug");

要在作用域内设置级别,您可以调用setLevel()

Sentry.configureScope(function(scope) {scope.setLevel(Sentry.Severity.Warning);});

或每个事件:

Sentry.withScope(function(scope) {scope.setLevel("info");Sentry.captureException("info");});

SDK 指纹

所有事件都有一个指纹。具有相同指纹的事件被组合成一个issue

默认情况下,Sentry将运行一种内置分组算法,以根据事件中可用的信息(如堆栈跟踪stacktrace、异常exception和消息message)生成指纹。 要扩展默认分组行为或完全更改它,您可以使用以下选项的组合:

在您的SDK中,使用SDK指纹识别,如下所述在您的项目中,使用指纹规则或堆栈跟踪规则Fingerprint Rules: https://docs.sentry.io/product/data-management-settings/event-grouping/fingerprint-rules/Stack Trace Rules:https://docs.sentry.io/product/data-management-settings/event-grouping/stack-trace-rules/

在受支持的sdk中,您可以覆盖Sentry的默认分组,该分组将指纹属性作为字符串数组传递。指纹数组的长度不受限制。这类似于指纹规则功能,它总是可用的,可以实现类似的结果。

fingerprint-rules:https://docs.sentry.io/product/data-management-settings/event-grouping/fingerprint-rules/

基本示例

在最基本的情况下,直接传递值:

function makeRequest(method, path, options) {return fetch(method, path, options).catch(function(err) {Sentry.withScope(function(scope) {// group errors together based on their request and responsescope.setFingerprint([method, path, String(err.statusCode)]);Sentry.captureException(err);});});}

您可以使用变量替换将动态值填充到通常在服务器上计算的指纹中。 例如,可以添加值{{ default }}以将整个正常生成的分组哈希添加到指纹中。 这些值与服务器端指纹识别相同。有关更多信息,请参阅:

Variables: https://docs.sentry.io/product/data-management-settings/event-grouping/fingerprint-rules/#variables

以更大的粒度对错误进行分组

您的应用程序查询远程过程调用模型 (RPC) 接口或外部应用程序编程接口 (API) 服务,因此堆栈跟踪通常是相同的(即使传出请求非常不同)。

以下示例将进一步拆分 Sentry 将创建的默认组(由{{ default }}表示),并考虑到错误对象的一些属性:

class MyRPCError extends Error {constructor(message, functionName, errorCode) {super(message);// The name of the RPC function that was called (e.g. "getAllBlogArticles")this.functionName = functionName;// For example a HTTP status code returned by the server.this.errorCode = errorCode;}}Sentry.init({...,beforeSend: function(event, hint) {const exception = hint.originalException;if (exception instanceof MyRPCError) {event.fingerprint = ['{{ default }}',String(exception.functionName),String(exception.errorCode)];}return event;}});

更进一步地分组错误

通用错误(例如数据库连接错误)具有许多不同的堆栈跟踪,并且永远不会组合在一起。

以下示例将通过从数组中省略{{ default }}来完全覆盖Sentry的分组:

class DatabaseConnectionError extends Error {}Sentry.init({...,beforeSend: function(event, hint) {const exception = hint.originalException;if (exception instanceof DatabaseConnectionError) {event.fingerprint = ['database-connection-error'];}return event;}});

Source Maps

生成 Source Maps

大多数现代JavaScript编译器都支持source maps。以下是一些常用工具的说明。

我们建议使用SentryWebpack插件来配置source maps并在构建过程中自动上传它们。

sentry-webpack-plugin: /getsentry/sentry-webpack-plugin

source-map-support

要依赖 Sentry 的 source map 解析,您的代码不能使用source-map-support包。 该包以一种阻止我们的处理器正确解析它的方式覆盖捕获的堆栈跟踪。

source-map-support:/package/source-map-support

Webpack

Sentry 提供了一个方便的Webpack插件,可以配置source maps并自动将它们上传到Sentry

要使用该插件,您首先需要安装它:

npm install --save-dev @sentry/webpack-plugin// oryarn add --dev @sentry/webpack-plugin

然后,配置它webpack.config.js

const SentryWebpackPlugin = require("@sentry/webpack-plugin");module.exports = {// other webpack configurationdevtool: 'source-map',plugins: [new SentryWebpackPlugin({// sentry-cli configuration - can also be done directly through sentry-cli// see https://docs.sentry.io/product/cli/configuration/ for detailsauthToken: process.env.SENTRY_AUTH_TOKEN,org: "example-org",project: "example-project",release: process.env.SENTRY_RELEASE,// other SentryWebpackPlugin configurationinclude: ".",ignore: ["node_modules", "webpack.config.js"],}),],};

此外,Webpack插件会自动设置window.SENTRY_RELEASE,因此您的Sentry.init调用不需要包含release值。

将 Webpack 插件设置为最后运行的插件;

否则,插件收到的 source maps 可能不是最终的。

高级用法

如果您更喜欢手动上传source maps,请配置 Webpack 去输出source maps

module.exports = {devtool: 'source-map',output: {// Make maps auto-detectable by sentry-clifilename: "[name].js",sourceMapFilename: "[name].js.map",// Other `output` configuration},// Other webpack configuration};

如果您使用SourceMapDevToolPlugin对 source map 生成进行更细粒度的控制,请关闭noSources,以便 Sentry 可以在事件堆栈跟踪中显示正确的源代码上下文。

SourceMapDevToolPlugin:/plugins/source-map-dev-tool-plugin

Rollup

您可以配置Rollup以生成source maps,然后您可以使用sentry-cli上传source maps

Rollup:/upload using sentry-cli:https://docs.sentry.io/product/cli/releases/#sentry-cli-sourcemaps

export default {entry: "./src/app.js",output: {file: "bundle.js",format: "cjs",sourceMap: true,},};

SystemJS

SystemJS可以配置为输出source maps,然后您可以使用 sentry-cli 上传source maps

builder.bundle("src/app.js", "dist/app.min.js", {minify: true,sourceMaps: true,sourceMapContents: true,});

此示例配置将您的原始、未转换的源代码内联到生成的source map文件中。Sentry 需要source map和您的原始源文件来执行反向转换。 如果您选择不内联源文件,则除了source map外,您还必须使这些源文件可供 Sentry 使用(见下文)。

SystemJS:/systemjs/builderupload using sentry-cli:https://docs.sentry.io/product/cli/releases/#sentry-cli-sourcemaps

TypeScript

TypeScript 编译器可以输出source maps,然后您可以使用sentry-cli上传源映射。

sourceRoot属性配置为/以从生成的源代码引用中去除构建路径前缀。这允许Sentry相对于您的源根文件夹匹配源文件:

{"compilerOptions": {"sourceMap": true,"inlineSources": true,"sourceRoot": "/"}}

UglifyJS

我们强烈建议您使用更高级的打包器(或转译器),因为UglifyJS配置会变得非常复杂,并且很难达到预期的结果。

UglifyJS 可以配置为输出source maps,然后您可以使用sentry-cli上传:

uglifyjs app.js \-o app.min.js.map \--source-map url=app.min.js.map,includeSources

UglifyJS:/mishoo/UglifyJS

上传 Source Maps

Webpack

Sentry 使用releases来将正确的source maps与您的事件相匹配。release API 旨在允许您在 Sentry 中存储源文件(和source maps)。

您可以在我们的 Webpack 插件的帮助下完成此操作,该插件在内部使用我们的Sentry CLI

从您的[Account] > API keys创建一个新的身份验证令牌确认您在“Scopes”下选择了project:write使用npm安装@sentry/webpack-plugin使用必要的配置创建.sentryclirc文件,如本页所述更新你的webpack.config.js

const SentryPlugin = require("@sentry/webpack-plugin");module.exports = {// ... other config above ...plugins: [new SentryPlugin({release: process.env.RELEASE,include: "./dist",}),],};

使用我们的 Sentry Webpack 插件文档了解有关插件进一步配置的更多信息。sentry-webpack-plugin:/getsentry/sentry-webpack-plugin

此外,您需要配置client以发送release

Sentry.init({dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",release: process.env.RELEASE,});

您不必使用RELEASE环境变量。只要您上传的版本与SDKinit调用的版本相匹配,您就可以以任何形式提供它们。

Releases API:https://docs.sentry.io/api/releases/

Sentry CLI

使用 sentry-cli 上传 Source Maps

使用sentry-cli上传source maps时,您需要设置构建系统以创建版本(release)并上传与该版本对应的各种源文件。要让Sentry对您的堆栈跟踪进行解码,请同时提供:

要部署的文件(换句话说,您的编译/压缩/打包(transpilation/minification/bundling)过程的结果;例如,app.min.js)对应的source maps

如果source map文件不包含您的原始源代码 (sourcesContent),您还必须提供原始源文件。 如果源文件丢失,Sentry CLI将尝试自动将源嵌入到您的source maps中。

Sentry使用releases将正确的source maps与您的事件相匹配。

要创建新版本,请运行以下命令(例如,在发布期间):

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

sentry-cli releases new <release_name>

release名称在您的组织中必须是唯一的,并且与您的SDK初始化代码中的release选项相匹配。

然后,使用upload-sourcemaps命令扫描文件夹中的source maps,处理它们,并将它们上传到Sentry

sentry-cli releases files <release_name> upload-sourcemaps /path/to/files

您可以通过导航到[Project] > Project Settings > Source Maps找到上传到Sentry的工件。

此命令会将所有以.js.map结尾的文件上传到指定的版本(release)。如果你想改变这些扩展 — 例如,上传 typescript 源文件 — 使用--ext选项:

sentry-cli releases files <release_name> upload-sourcemaps --ext ts --ext map /path/to/files

到目前为止,该版本处于草稿状态(“unreleased”)。

上传所有source maps后,您的应用程序已成功发布,使用以下命令完成release

sentry-cli releases finalize <release_name>

为方便起见,您可以将--finalize标志传递给新命令,这将立即完成release

有关更多信息,请参阅我们的sentry-cli文档。

sentry-cli:https://docs.sentry.io/product/cli/releases/#managing-release-artifacts

Web 应用程序可在多个来源访问的情况并不少见。 请参阅我们关于多源的文档以了解如何处理此问题。

multiple origins:https://docs.sentry.io/platforms/javascript/guides/react/sourcemaps/uploading/multiple-origins/

公开托管

source maps提供给 Sentry 的最可靠方法是上传它们,因为它减少了网络流量并确保将使用正确版本的代码和源映射。

默认情况下,Sentry 将在您编译的 JavaScript 文件中查找source map指令。这些指令位于最后一行,格式如下:

//# sourceMappingURL=<url>

当 Sentry 遇到这样的指令时,它会解析相对于它所在的源文件的 source map URL,并尝试一个 HTTP 请求来获取它。

例如,如果您有一个位于/js/app.min.js的压缩的 JavaScript 文件,并且在该文件的最后一行,可以找到以下指令:

//# sourceMappingURL=app.js.map

Sentry 将尝试从/js/app.js.map获取app.js.map

或者,在source map生成期间,您可以指定source map所在的完全限定URL

//# sourceMappingURL=/js/app.js.map

虽然从您的服务器向 Sentry 提供source maps是最自然的集成,但并不总是可取的:

Sentry 可能并不总是能够访问您的服务器。如果您未在asset URL中指定版本,则可能存在版本不匹配额外的延迟可能意味着源映射并非适用于所有错误。

由于这些原因,最好事先将source maps上传到 Sentry(见下文)。

在防火墙后面工作

虽然推荐的解决方案是将您的源工件(打包转译后的代码)上传到Sentry,但有时需要允许来自Sentry的内部IP的通信。

有关 Sentry public IP 的更多信息,请参阅:

IP Ranges:https://docs.sentry.io/product/security/ip-ranges/

安全访问 Source Maps

如果您想对source maps保密并选择不将source maps直接上传到Sentry,您可以在项目设置中启用“Security Token”选项。

这将导致从Sentry的服务器发出的来自你的 “Allowed Domains” 的url的出站请求附加 HTTP headerX-Sentry-Token头:

GET /assets/bundle.min.jsX-Sentry-Token: {token}

token是您在项目设置中定义的安全值。然后,您可以配置您的 Web 服务器以允许在此header/token对存在时访问您的source maps。 您也可以覆盖默认header名称 (X-Sentry-Token) 并使用HTTP Basic Authentication,例如通过传递Authorization: Basic {encoded_password}

多个 Origin

Web 应用程序可在多个来源访问的情况并不少见。例如:

网站可通过httpshttp运行地理定位网址:例如多个静态CDN:如客户特定的域/子域

在这种情况下,相同的JavaScriptsource map文件可能位于两个或多个不同的来源。 在这种情况下,我们建议在路径上使用我们特殊的波浪号 (~) 前缀。

例如,如果您有以下内容:

/js/app.js/js/app.js

您可以使用~/js/app.jsURL上传。这将告诉Sentry忽略域并将artifact用于任何来源。

此外,您还可以以多个名称上传同一个文件。 在引擎盖(hood)下 Sentry 将对这些进行重复数据删除。

~前缀告诉Sentry对于给定的URL,路径为/js/app.js的协议和主机名的任何组合都应该使用这个工件。

验证文件

确保source maps本身有效并正确上传可能非常具有挑战性。 为了解决这个问题,我们维护了一个在线验证工具,可用于针对您的托管源测试您的source mapsourcemaps.io

https://sourcemaps.io/

此外,您可以在使用sentry-cli上传source maps时使用--validate标志,这将尝试在本地解析源映射并查找引用。 请注意,在已知情况下,验证标志将在设置正确时指示失败(如果您引用了外部source maps,则验证工具将指示失败)。

除了验证步骤之外,您还可以检查这些:

确保您的文件的 URL 前缀正确。 这很容易出错。上传压缩文件的匹配source maps。确保您在服务器上的压缩文件实际上引用了您的文件。

最佳实践

一个简单的设置

在这个简单的项目中,minified/transpiled的文件及其source maps位于同一目录中:

├── build/│ ├── worker.js│ ├── worker.js.map│ ├── app.js│ ├── app.js.map│ ├── index.html├── package.json├── public/│ └── index.html├── sentry.properties├── src/│ ├── app.js│ └── worker.js├── webpack.config.js

对于这个项目,我们可以使用一个简单的Sentry配置:

const SentryWebpackPlugin = require("@sentry/webpack-plugin");// ...plugins: [new SentryWebpackPlugin({authToken: process.env.SENTRY_AUTH_TOKEN,org: "example-org",project: "example-project",include: "build",configFile: "sentry.properties",release: process.env.SENTRY_RELEASE,}),],// ...

我们建议使用Webpack插件将source maps集成到Sentry。 如果您的项目中没有使用Webpack,则可以使用Sentry CLI

一致的版本

要让Sentry将错误堆栈跟踪与您的source maps相关联,请将您的版本号定义为Webpack插件选项或Sentry CLI参数(无论您使用哪个)。如果您使用Sentry CLI,您还应该在Sentry.init()调用中定义相同的版本号。 确保版本号一致性的最简单方法是将其设置为项目中的环境变量:

# ...SENTRY_RELEASE="1.2.3"# ...

然后,如果您使用的是sentry-webpack-plugin

// ...new SentryWebpackPlugin({// ... other optionsrelease: process.env.SENTRY_RELEASE,});// ...

或者,如果您使用的是Sentry CLI

sh sentry-cli releases new "$SENTRY_RELEASE" sentry-cli releases files "$SENTRY_RELEASE" upload-sourcemaps /path/to/sourcemaps

// ...Sentry.init({// ... other optionsrelease: process.env.SENTRY_RELEASE,});// ...

正确的 Source Paths

您的release artifacts(bundle文件和源source maps)的文件名应与堆栈跟踪中报告的路径匹配。 您可以使用上传配置来调整文件的名称。Webpack插件和Sentry CLI都有相同的选项;下面介绍了与source maps相关的内容。还可以使用我们的RewriteFrames集成来调整堆栈跟踪内的路径。

根据您的设置,您可能需要在开发和生产环境中为source maps进行不同的配置,因为堆栈跟踪中的路径可能不同。

Webpack 和 Sentry CLI 的选项

这些选项和示例将有助于集成您的source maps

include

此选项接受一个或多个路径来递归扫描源和*.map文件。例如:

包括您的转译器/捆绑器输出文件的位置:include: './app/.next'include: './build'包括来自多个文件夹:包括:['./src', './lib']递归搜索整个项目:include: '.'

rewrite

允许重写匹配的source maps,以便在可能的情况下将索引映射扁平化并内联缺失的源。默认为true

应该启用此选项以使stripPrefixstripCommonPrefix工作。

urlPrefix

此选项在所有文件名的开头添加一个公共前缀。默认为~/,这是一个匹配任何schemehostname的通配符(http://my.web.site/path/to/script.jshttp://my.web.site/部分)。

当应用程序的入口点(通常是浏览器端的index.htmlNodeindex.js)位于源/源映射文件之上一个或多个级别时,此选项很有用,如下例所示:

├── build/│ ├── index.html│ ├── static/│ │ ├── app.js│ │ ├── app.js.map

在这种情况下,请按照以下示例进行配置:

// ...new SentryWebpackPlugin({// ...include: "build/static/",urlPrefix: "~/static/"// ...}),// ...

stripPrefix

此选项从sourcemap中(例如,在sources entry中)引用的文件名中删除给定的前缀。 当您需要修剪捆绑器/开发(bundler/development)服务器可能添加到文件名的额外前缀时,这很有用,例如webpack://_N_E/

请注意,使用stripPrefix选项不会更改上传文件的名称。 当您将目标文件的父文件夹作为不需要的前缀时,请在包含Webpack插件选项或传递给sentry-clipath/to/sourcemaps中包含要删除的部分。例如,如果您的文件存储在./build/static/js/并且您在Webpack插件配置中有include: "build",您的文件将使用类似~/static/js/bundle.js的名称上传。如果您更新您的配置include: "build/static/js",您的文件将上传为~/bundle.js(等等)。

调整帧(Frames)

或者,您可以使用SentryRewriteFrames集成来微调堆栈跟踪内的路径。

import { RewriteFrames } from "@sentry/integrations";Sentry.init({dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",integrations: [new RewriteFrames({// ... options}),],});

对 Source Maps 进行故障排除

Source maps有时很难开始。如果您遇到问题:

验证在您的 SDK 中配置了一个 release

要定位和应用上传的source maps,需要通过 CLI 或 API(以及随其上传的正确工件)创建release,并且需要在您的 SDK 配置中指定新创建的release的名称。

要验证这一点,请从Sentry UI打开issue并检查release是否已配置。如果屏幕右侧的“Release”旁边显示“not configured”“N/A”(或者如果您在标签列表中没有看到release tag),则需要返回并标记你的错误。如果设置正确,您将看到"Release: my_example_release"

验证工件(artifacts)已上传

正确配置您的release并标记问题后,您可以通过导航到[Project] » Project Settings » Source Maps找到上传到Sentry的工件。

此外,请确保所有必要的文件都可用。要让 Sentryde-minify堆栈跟踪,您必须同时提供minify的文件(例如app.min.js)和相应的source map。如果source map文件不包含您的原始源代码 (sourcesContent),您必须另外提供原始源代码文件。或者,sentry-cli会自动将源代码(如果缺少)嵌入到您的source maps中。

验证sourceMappingURL是否存在

一些CDN会自动从静态文件(包括JavaScript文件)中去除注释。 这可能会导致删除JavaScript文件的sourceMappingURL指令,因为它被视为注释。例如,CloudFlare有一个名为Auto-Minify的功能,如果启用它,它将去除sourceMappingURL

Auto-Minify:/an-all-new-and-improved-autominify/

仔细检查您部署的最终JavaScript文件是否存在sourceMappingURL

或者,您可以在minify的文件上设置SourceMap HTTP header,而不是sourceMappingURL。如果此header存在,Sentry将使用它来发现source map的位置。

验证 artifact 发布值是否与您的 SDK 中配置的值匹配

每当您使用分发标识符(SDK中的dist配置选项)时,在source map上传期间必须使用相同的值。相反,如果您的source map使用dist值上传,则必须在您的SDK中设置相同的值。要将dist值添加到您上传的source maps,请使用--dist标志和sentry-clidist选项和@sentry/webpack-plugin。要在SDK中设置dist值,请使用Sentry.init()中的dist选项。

要验证 SDK 中的分发设置是否正确,请在Sentry UI中打开一个issue并检查dist标签是否存在。对于工件,转到项目设置中的Source Maps页面,选择您刚刚检查的事件中显示的release,并验证dist值(在upload time旁边的小椭圆中)与事件上的值匹配。

验证 artifact 名称与sourceMappingURL值匹配

bundledminified的 JavaScript 文件最后一行的sourceMappingURL注释告诉 Sentry(或浏览器)在哪里找到相应的source map。这可以是完全限定的URL、相对路径或文件名本身。 将artifact上传到Sentry时,您必须使用文件解析为的值命名源映射文件。

也就是说,如果您的文件类似于:

// -- end script.min.js//# sourceMappingURL=script.min.js.map

并托管在/js/script.min.js,然后Sentry将在/js/script.min.js.map查找该source map文件。 因此,您上传的artifact必须命名为/js/script.min.js.map(或~/js/script.min.js.map)。

或者,如果您的文件类似于:

//-- end script.min.js//# sourceMappingURL=/dist/js/script.min.js.map

那么您上传的artifact也应该命名为:

/dist/js/script.min.js.map(或~/dist/js/script.min.js.map)。

最后,如果您的文件类似于:

//-- end script.min.js//# sourceMappingURL=../maps/script.min.js.map

那么您上传的artifact应命名为/dist/maps/script.min.js.map(或~/dist/maps/script.min.js.map)。

验证 artifact 名称与堆栈跟踪帧匹配

如果您已上传source maps,但它们并未应用于Sentry问题中的代码,请查看事件的JSON并查找abs_path以准确查看我们尝试解析文件的位置 - 对于 例如,http://localhost:8000/scripts/script.js(对于堆栈跟踪中的每一帧,abs_path将出现一次 - 将其与未deminified的文件匹配。)。 可以在事件发生日期旁边的issue页面顶部找到指向JSON视图的链接。上传的artifact名称必须与这些值匹配。

如果您的路径中有动态值(例如,/{some_value}/scripts/script.js),您可能需要使用rewriteFrames集成来更改您的abs_path值。

使用 sentry-cli

如果您的sourceMappingURL注释类似于:

// -- end script.min.js (located at http://localhost:8000/scripts/script.min.js)//# sourceMappingURL=script.min.js.map

正确上传这些文件的示例sentry-cli命令如下所示(假设您在/scripts目录中,从上一级目录运行 Web 服务器,这就是我们使用--url-prefix选项的原因) :

sentry-cli releases files VERSION upload-sourcemaps . --url-prefix '~/scripts'

此命令上传当前目录中的所有JavaScript文件。Sentry中的Artifacts页面现在应如下所示:

~/scripts/script.js~/scripts/script.min.js~/scripts/script.min.js.map

或者,您可以指定要上传的文件。 例如:

sentry-cli releases files VERSION upload-sourcemaps script.min.js script.min.js.map --url-prefix '~/scripts'

您还可以使用完全限定的 URL 上传它。例如:

sentry-cli releases files VERSION upload-sourcemaps . --url-prefix 'http://localhost:8000/scripts'

使用 API

您也可以使用API上传artifact

curl -X POST \https://sentry.io/api/0/organizations/ORG_SLUG/releases/VERSION/files/ \-H 'Authorization: Bearer AUTH_TOKEN' \-H 'content-type: multipart/form-data' \-F file=@script.min.js.map \-F 'name=~/scripts/script.min.js.map'

使用 ~

~Sentry中用于替换schemedomain

/dist/js/script.js将匹配~/dist/js/script.js/dist/js/script.js

但不会匹配~/script.js

在发生错误之前验证 artifact 已上传

Sentry期望给定版本中的源代码和source maps在该release中发生错误之前上传到Sentry

如果您在Sentry捕获错误后上传artifactSentry将不会返回并追溯将任何源注释(source annotations)应用于这些错误。 只有在artifact上传后触发的新错误才会受到影响。

验证您的 source maps 是否正确构建

我们维护一个在线验证工具,可用于针对您的托管源测试您的source mapssourcemaps.io

https://sourcemaps.io/

或者,如果您使用Sentry CLIsource maps上传到Sentry,您可以使用--validate命令行选项来验证您的source maps是否正确。

验证您的 source maps 在本地工作

如果您发现Sentry没有正确映射文件名、行或列映射,您应该验证您的source maps是否在本地运行。为此,您可以将Node.jsMozillasource-map library结合使用。

/mozilla/source-map

首先,将source-map作为npm模块全局安装:

npm install -g source-map

然后,编写一个脚本来读取您的source map文件并测试映射。 下面是一个例子:

var fs = require("fs"),path = require("path"),sourceMap = require("source-map");// file output by Webpack, Uglify, and so forthvar GENERATED_FILE = path.join(".", "app.min.js.map");// line and column located in your generated file (for example, the source of your error// from your minified file)var GENERATED_LINE_AND_COLUMN = { line: 1, column: 1000 };var rawSourceMap = fs.readFileSync(GENERATED_FILE).toString();new sourceMap.SourceMapConsumer(rawSourceMap).then(function(smc) {var pos = smc.originalPositionFor(GENERATED_LINE_AND_COLUMN);// should see something like:// { source: 'original.js', line: 57, column: 9, name: 'myfunc' }console.log(pos);});

如果您在本地获得与通过Sentry获得的结果相同(不正确)的结果,请仔细检查您的source map生成配置。

验证您的源文件不是太大

对于单个artifactSentry接受的最大文件大小为40 MB

用户通常会达到此限制,因为他们在临时构建阶段传输源文件。例如,在Webpack/Browserify合并所有源文件之后,但在minification之前。 如果可能,请发送原始源文件。

验证 artifact 没有被 gzip

Sentry API目前仅适用于以纯文本(UTF-8编码)形式上传的source maps和源文件。如果文件以压缩格式(例如gzip)上传,它们将不会被正确解释。

这有时发生在生成pre-compressed minified文件的构建脚本和插件中。 例如,Webpackcompression插件。您需要禁用此类插件并在生成的source maps/source files上传到 Sentry 后执行压缩。

/webpack/compression-webpack-plugin

验证 worker 与 Web 共享相同的卷(如果通过 Docker 运行自托管 Sentry)

Sentry 在其worker中进行source map计算。 这意味着worker需要访问通过前端上传的文件。仔细检查cron workerweb worker是否可以从同一个磁盘读取/写入文件。

故障排除

如果您需要帮助解决Sentry JavaScript SDK integration问题,您可以阅读此处记录的边缘案例。

调试附加数据

您可以查看事件的JSON payload以了解Sentry如何在事件中存储其他数据。数据的形状可能与描述不完全匹配。

有关更多详细信息,请参阅有关事件有效负载的完整文档。

https://develop.sentry.dev/sdk/event-payloads/

最大 JSON Payload 大小

maxValueLength的默认值为250,但如果您的消息较长,您可以根据需要调整此值。 请注意,并非每个值都受此选项影响。

CORS 属性和 Header

要了解从不同来源的脚本引发的 JavaScript 异常,请执行以下两项操作:

添加crossorigin="anonymous"脚本属性

<script src="http://another-/app.js" crossorigin="anonymous"></script>

脚本属性告诉浏览器“anonymously”获取目标文件。 请求此文件时,浏览器不会将潜在的用户识别信息(如cookieHTTP凭据)传输到服务器。

添加Cross-Origin HTTP header

Access-Control-Allow-Origin: *

跨域资源共享 (CORS) 是一组API(主要是HTTP header),用于规定文件应该如何跨域下载和提供服务。

通过设置Access-Control-Allow-Origin: *,服务器向浏览器表明任何来源都可以获取此文件。 或者,您可以将其限制为您控制的已知来源:

Access-Control-Allow-Origin:

大多数社区CDN正确设置了Access-Control-Allow-Originheader。

$ curl --head /ajax/libs/jquery/2.2.0/jquery.js | \grep -i "access-control-allow-origin"Access-Control-Allow-Origin: *

意外的 OPTIONS 请求

如果您的应用程序由于执行额外的OPTIONS请求而开始行为异常,则很可能是不需要的sentry-trace请求header的问题,当您在浏览器SDK中为我们的Tracing Integration使用过于通用的配置时可能会发生这种情况。

要解决此问题,请在SDK初始化期间更改trackingOrigins选项。 有关更多详细信息,请参阅我们的性能监控文档中的自动检测。

https://docs.sentry.io/platforms/javascript/performance/instrumentation/automatic-instrumentation/#tracingorigins

instrument.jsConsole Log 语句的行号

如果调试时在您的控制台中显示了instrument.js,请将Sentry添加到您的框架黑盒设置中,例如:/@sentry/,以便Chrome在调试时忽略SDK堆栈帧。

blackboxing:https://docs.sentry.io/platforms/javascript/guides/react/troubleshooting/

处理广告拦截器(Ad-Blockers)

当您使用我们的CDN时,广告拦截或脚本拦截扩展可能会阻止我们的SDK被正确获取和初始化。因此,对SDK API的任何调用都将失败,并可能导致您的应用程序出现意外行为。

此外,即使正确下载并初始化SDK,也可能会阻止需要接收捕获数据的Sentry端点。这将阻止任何错误报告、会话运行状况或性能数据的传递,从而使其在sentry.io中实际上不可用。

您可以通过上述多种方式解决第一个issue。但是,端点阻塞只能使用隧道解决。

使用 tunnel 选项

隧道是一个HTTP端点,充当Sentry和您的应用程序之间的代理。 由于您控制此服务器,因此不会有任何发送到它的请求被阻止的风险。 当端点位于同一个源下时(尽管它不必为了隧道工作),浏览器不会将任何对端点的请求视为第三方请求。因此,这些请求将应用不同的安全措施,默认情况下不会触发广告拦截器。可以在下面找到流程的快速摘要。

JavaScript SDK 6.7.0版开始,您可以使用tunnel选项告诉 SDK 将事件传送到配置的 URL,而不是使用DSN。 这允许SDK从查询参数中删除sentry_key,这是广告拦截器首先阻止发送事件的主要原因之一。此选项还会阻止SDK发送预检请求,这是需要在查询参数中发送sentry_key的要求之一。

要启用tunnel选项,请在Sentry.init调用中提供相对或绝对URL。当您使用相对URL时,它是相对于当前来源的,这是我们推荐的形式。使用相对 URL 不会触发预检CORS请求,因此不会阻止任何事件,因为广告拦截器不会将这些事件视为第三方请求。

Sentry.init({dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",tunnel: "/tunnel",});

配置完成后,所有事件都将发送到/tunnel端点。 但是,此解决方案需要在服务器上进行额外配置,因为现在需要解析事件并将其重定向到Sentry。 这是您的服务器组件的示例:

<?php// Change $host appropriately if you run your own Sentry instance.$host = "sentry.io";// Set $known_project_ids to an array with your Sentry project IDs which you// want to accept through this proxy.$known_project_ids = array( );$envelope = stream_get_contents(STDIN);$pieces = explode("\n", $envelope, 2);$header = json_decode($pieces[0], true);if (isset($header["dsn"])) {$dsn = parse_url($header["dsn"]);$project_id = intval(trim($dsn["path"], "/"));if (in_array($project_id, $known_project_ids)) {$options = array('http' => array('header' => "Content-type: application/x-sentry-envelope\r\n",'method' => 'POST','content' => $envelope));echo file_get_contents("https://$host/api/$project_id/envelope/",false,stream_context_create($options));}}

// Requires .NET Core 3.1 and C# 9 or higherusing System;using System.Collections.Generic;using System.IO;using .Http;using System.Text.Json;using Microsoft.AspNetCore;using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Hosting;using Microsoft.AspNetCore.Http;// Change host appropriately if you run your own Sentry instance.const string host = "sentry.io";// Set knownProjectIds to a list with your Sentry project IDs which you// want to accept through this proxy.var knownProjectIds = new HashSet<string>() { };var client = new HttpClient();WebHost.CreateDefaultBuilder(args).Configure(a =>a.Run(async context =>{context.Request.EnableBuffering();using var reader = new StreamReader(context.Request.Body);var header = await reader.ReadLineAsync();var headerJson = JsonSerializer.Deserialize<Dictionary<string, object>>(header);if (headerJson.TryGetValue("dsn", out var dsnString)&& Uri.TryCreate(dsnString.ToString(), UriKind.Absolute, out var dsn)){var projectId = dsn.AbsolutePath.Trim('/');if (knownProjectIds.Contains(projectId) && string.Equals(dsn.Host, host, StringComparison.OrdinalIgnoreCase)) {context.Request.Body.Position = 0;await client.PostAsync($"https://{dsn.Host}/api/{projectId}/envelope/",new StreamContent(context.Request.Body));}}})).Build().Run();

查看我们的示例存储库以了解更多信息。

/getsentry/examples/tree/master/tunneling

如果您的用例与 SDK 包本身被阻止有关,以下任何一种解决方案都可以帮助您解决此问题。

直接使用 Package

处理脚本阻塞扩展的最佳方法是直接通过npm使用SDK包并将其与您的应用程序捆绑在一起。 这样,您就可以确保代码始终如您所愿。

第二种方法是从我们的CDN下载SDK并自己托管。这样,SDK仍将与您的其余代码分开,但您可以确定它不会被阻止,因为它的来源将与您网站的来源相同。

您可以使用curl或任何其他类似工具轻松获取它:

curl https://browser.sentry-/5.20.1/bundle.min.js -o sentry.browser.5.20.1.min.js -s

使用 JavaScript Proxy API

最后一个选项是使用Proxy保护,这将确保您的代码不会中断,即使您调用我们的 SDK,它被阻止。 除了 Internet Explorer 之外的所有浏览器都支持Proxy。此外,如果Proxy不在您用户的任何浏览器中,它将被悄悄跳过,因此您不必担心它会破坏任何内容。

将此代码段直接放在包含我们的CDN包的<script>标签上方。可读格式的代码片段如下所示:

if ("Proxy" in window) {var handler = {get: function(_, key) {return new Proxy(function(cb) {if (key === "flush" || key === "close") return Promise.resolve();if (typeof cb === "function") return cb(window.Sentry);return window.Sentry;}, handler);},};window.Sentry = new Proxy({}, handler);}

如果您想直接复制和粘贴代码段,这里将其minified

<script>if ("Proxy" in window) {var n = {get: function(o, e) {return new Proxy(function(n) {return "flush" === e || "close" === e? Promise.resolve(): "function" == typeof n? n(window.Sentry): window.Sentry;}, n);},};window.Sentry = new Proxy({}, n);}</script>

直接使用 Client

为了能够管理多个Sentry实例而它们之间没有任何冲突,您需要创建自己的Client。 如果您的应用程序集成在其中,这也有助于防止跟踪任何父应用程序错误。在这个例子中,我们使用@sentry/browser但它也适用于@sentry/node

import { BrowserClient } from "@sentry/browser";const client = new BrowserClient({dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",});client.captureException(new Error("example"));

虽然上面的示例应该可以正常工作,但Client上缺少一些方法,如configureScopewithScope,因为Hub负责状态管理。这就是为什么创建新Hub并将Client绑定到它可能更容易的原因。结果是一样的,但你也会得到状态管理。

import { BrowserClient, Hub } from "@sentry/browser";const client = new BrowserClient({dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",});const hub = new Hub(client);hub.configureScope(function(scope) {scope.setTag("a", "b");});hub.addBreadcrumb({ message: "crumb 1" });hub.captureMessage("test");try {a = b;} catch (e) {hub.captureException(e);}hub.withScope(function(scope) {hub.addBreadcrumb({ message: "crumb 2" });hub.captureMessage("test2");});

处理集成

集成是在Client上设置的,如果您需要处理多个ClientHub,您还必须确保正确进行集成处理。这是一个如何使用多个Client和多个运行全局集成的Hub的工作示例。

import * as Sentry from "@sentry/browser";// Very happy integration that'll prepend and append very happy stick figure to the messageclass HappyIntegration {constructor() {this.name = "HappyIntegration";}setupOnce() {Sentry.addGlobalEventProcessor(event => {const self = Sentry.getCurrentHub().getIntegration(HappyIntegration);// Run the integration ONLY when it was installed on the current Hubif (self) {event.message = `\\o/ ${event.message} \\o/`;}return event;});}}HappyIntegration.id = "HappyIntegration";const client1 = new Sentry.BrowserClient({dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",integrations: [...Sentry.defaultIntegrations, new HappyIntegration()],beforeSend(event) {console.log("client 1", event);return null; // Returning null does not send the event},});const hub1 = new Sentry.Hub(client1);const client2 = new Sentry.BrowserClient({dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", // Can be a different DSNintegrations: [...Sentry.defaultIntegrations, new HappyIntegration()],beforeSend(event) {console.log("client 2", event);return null; // Returning null does not send the event},});const hub2 = new Sentry.Hub(client2);hub1.run(currentHub => {// The hub.run method makes sure that Sentry.getCurrentHub() returns this hub during the callbackcurrentHub.captureMessage("a");currentHub.configureScope(function(scope) {scope.setTag("a", "b");});});hub2.run(currentHub => {// The hub.run method makes sure that Sentry.getCurrentHub() returns this hub during the callbackcurrentHub.captureMessage("x");currentHub.configureScope(function(scope) {scope.setTag("c", "d");});});

第三方 Promise 库

当您包含和配置Sentry时,我们的JavaScript SDK会自动附加global handlerscapture未捕获的exceptions和未处理的promise rejections。 您可以通过在GlobalHandlers集成中将onunhandledrejection选项更改为false并手动挂接到每个事件处理程序,然后直接调用Sentry.captureExceptionSentry.captureMessage来禁用此默认行为。

如果您使用第三方库来实现Promise,您可能还需要管理您的配置。 此外,请记住,浏览器通常会实施安全措施,在提供来自不同来源的脚本文件时阻止错误报告。

具有“非错误异常Non-Error Exception”的事件

如果您看到错误消息“Non-Error exception (or promise rejection) captured with keys: x, y, z.”,这会发生在您a) 使用plain object调用Sentry.captureException()时,b) 抛出一个plain object,或者c) 拒绝一个带有plain objectpromise

您可以在“Additional Data”部分的__serialized__条目中查看有问题的非错误对象的内容。

为了更好地了解这些错误事件,我们建议根据__serialized__数据的内容找到plain object被传递或抛出到Sentry的位置,然后将plain object转换为Error对象。

支持的浏览器

SentryJavaScript SDK支持以下浏览器:

支持 <= IE 11

5.7.0版本之前,我们的JavaScript SDK需要一些polyfills用于旧版浏览器,如IE 11及更低版本。如果您正在使用它,请在加载我们的SDK之前升级到最新版本或添加下面的脚本标签。

<script src="https://polyfill.io/v3/polyfill.min.js?features=Promise%2CObject.assign%2CString.prototype.includes%2CNumber.isNaN"></script>

我们需要以下polyfill

PromiseObject.assignNumber.isNaNString.prototype.includes

此外,请记住在HTML页面顶部定义有效的HTML doctype,以确保IE不会进入兼容模式(compatibility mode)

公众号:黑客下午茶

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。