作用域
SDK 通常会在框架集成中自动管理作用域。了解什么是作用域以及如何利用它来发挥优势。
当事件被捕获并发送到 Sentry 时,SDK 会将事件数据与当前作用域中的额外信息合并。SDK 通常会在框架集成中自动管理作用域,因此您无需特别考虑它们。然而,您应该了解什么是作用域以及如何利用它来发挥优势。
作用域保存了与事件一起发送的有用信息。例如,上下文 和 面包屑 都存储在作用域中。当作用域被分叉时,它会继承其父作用域中的所有数据。
默认的 SDK 集成会智能地分叉作用域。例如,Web 框架集成会在您的路由或请求处理程序周围分叉作用域。
作用域基本上是一个附加到事件的数据栈。当事件被捕获时,SDK 会将活动作用域中的数据合并到事件中。这使得您可以将与事件捕获上下文相关的重要数据附加到事件上。
作用域通常在回调或执行上下文中有效。这意味着您的应用程序的不同部分可能在同一时间有不同的作用域处于活动状态。例如,Web 服务器可能同时处理多个请求,每个请求可能具有不同的作用域数据来应用于其事件。
Sentry SDK 有三种不同类型的作用域:
全局作用域应用于 所有 事件,无论它们来自何处。您可以使用它来存储应适用于所有事件的数据,例如环境信息。
您可以通过 Sentry.getGlobalScope()
访问全局作用域。
请注意,全局作用域只能用于写入数据,不能用于捕获事件。事件只能在当前作用域中捕获(例如 getCurrentScope().captureException()
和类似的 API)。
隔离作用域用于隔离事件,使其互不干扰。例如,在 Web 服务器中,每个请求可能会有自己的隔离作用域,以确保一个请求的事件不会干扰另一个请求的事件。在大多数情况下,您希望将应应用于事件的数据放在隔离作用域上——这也是为什么所有 Sentry.setXXX
方法(如 Sentry.setTag()
)会将数据写入当前活动的隔离作用域。一个经典的例子是用户数据——每个请求可能有不同的用户,因此您需要确保用户数据设置在隔离作用域上。
您可以通过 Sentry.getIsolationScope()
访问隔离作用域,但通常您只需使用 Sentry.setXXX
方法将数据设置到当前活动的隔离作用域:
Sentry.setTag("my-tag", "my value");
// Is identical to:
Sentry.getIsolationScope().setTag("my-tag", "my value");
请注意,隔离作用域只能用于写入数据,不能用于捕获事件。事件只能在当前作用域中捕获(例如 getCurrentScope().captureException()
和类似的 API)。
当前作用域是当前活跃的本地作用域。与较少分叉的隔离作用域不同,当前作用域可能会更频繁地在内部分叉。它可用于存储仅应用于特定事件的数据。在大多数情况下,您不应直接访问此作用域,而是使用 Sentry.withScope
创建一个仅在代码特定部分活跃的新作用域:
Sentry.withScope((scope) => {
// scope is the current scope inside of this callback!
scope.setTag("my-tag", "my value");
// this tag will only be applied to events captured inside of this callback
// the following event will have the tag:
Sentry.captureException(new Error("my error"));
});
// this event will not have the tag:
Sentry.captureException(new Error("my other error"));
您可以通过 Sentry.getCurrentScope()
访问当前作用域,但通常应该使用 Sentry.withScope()
来与本地作用域进行交互。
在事件(如错误或事务)发送到 Sentry 之前,当前活跃的作用域会被应用到事件上。
全局作用域首先被应用,接着是隔离作用域,最后是当前作用域。这意味着在当前作用域上设置的任何数据将覆盖其他作用域中的相同数据。
Sentry.getGlobalScope().setExtras({
shared: "global",
global: "data",
});
Sentry.getIsolationScope().setExtras({
shared: "isolation",
isolation: "data",
});
Sentry.getCurrentScope().setExtras({
shared: "current",
current: "data",
});
Sentry.captureException(new Error("my error"));
// --> Will have the following extra:
// { shared: 'current', global: 'data', isolation: 'data', current: 'data' }
与作用域交互主要有两种方式。您可以使用 Sentry.getCurrentScope()
访问当前作用域,并在返回的作用域上使用设置方法,或者直接使用全局方法如 Sentry.setTag()
,这些方法会在底层设置到相应的隔离作用域。
首先,您需要像往常一样导入 SDK:
const Sentry = require("@sentry/node");
例如,您可以添加自定义标签或告知 Sentry 当前已验证的用户。
/// Usually, you don't want to write on the current scope, so use with care!
const scope = Sentry.getCurrentScope();
scope.setTag("my-tag", "my value");
scope.setUser({
id: 42,
email: "john.doe@example.com",
});
// Or use the global methods (which will set data on the isolation scope):
Sentry.setTag("my-tag", "my value");
Sentry.setUser({
id: 42,
email: "john.doe@example.com",
});
要了解可以与作用域关联的有用信息,请参阅 上下文、标签、用户 和 面包屑。
在以下示例中,我们使用 withScope
为仅一个特定错误附加 level
和 tag
:
Sentry.withScope(function (scope) {
scope.setTag("my-tag", "my value");
scope.setLevel("warning");
// will be tagged with my-tag="my value"
Sentry.captureException(new Error("my error"));
});
// will not be tagged with my-tag
Sentry.captureException(new Error("my other error"));
withScope()
回调中的作用域仅在回调内部有效。一旦回调结束,作用域将被移除且不再应用。内部作用域仅应用于在回调内捕获的事件。withScope()
会克隆(或分叉)当前作用域,因此不会修改当前作用域。这使您可以更轻松地将上下文信息隔离到代码中的特定位置,甚至可以调用 clear
短暂移除所有上下文信息。
withIsolationScope
的工作原理与 withScope
基本相同,但它会分叉隔离作用域而不是当前作用域。通常,隔离作用域比当前作用域分叉得更少频繁,并且在大多数情况下 SDK 会自动为您处理。
但在某些情况下,例如您希望隔离一个非请求进程(如后台任务),可以使用 withIsolationScope
创建一个新的隔离作用域,该作用域仅在回调期间有效:
Sentry.withIsolationScope(function () {
// This user & tag is set inside of this callback
Sentry.setUser({ id: "123" });
Sentry.setTag("my-tag", "my value");
// will be tagged with my-tag="my value" & user
Sentry.captureException(new Error("my error"));
});
// will not be tagged with my-tag & user
Sentry.captureException(new Error("my other error"));