采样

了解如何配置发送到 Sentry 的错误和事务事件的数量。

将 Sentry 添加到你的应用程序中,可以为你提供大量关于错误和性能的宝贵信息,这些信息在其他情况下你可能无法获得。大量的信息是有益的——只要它们是正确的信息,并且数量合理。

为了向 Sentry 发送具有代表性的错误样本,请在 SDK 配置中将 sampleRate 选项设置为介于 0(0% 的错误被发送)和 1(100% 的错误被发送)之间的数字。这是一个静态比率,将同样应用于所有错误。例如,要采样 25% 的错误:

Copied
Sentry.init({ sampleRate: 0.25 });

错误采样率默认为 1,意味着所有错误都将发送到 Sentry。

更改错误采样率需要重新部署。此外,设置 SDK 采样率会限制对事件来源的可见性。为项目设置速率限制(仅在事件量高时丢弃事件)可能更符合你的需求。

我们建议对事务进行采样的原因有两个:

  1. 捕获单个跟踪涉及的开销很小,但为每次页面加载或每个 API 请求捕获跟踪可能会给系统增加不必要的负载。
  2. 启用采样可以让你更好地管理发送到 Sentry 的事件数量,从而根据你组织的需求调整事件量。

选择采样率时,目标是找到性能和数据准确性之间的平衡。你不希望收集过多的数据,但需要收集足够的数据以得出有意义的结论。如果你不确定选择什么比率,可以从较低的值开始,随着你对流量模式和数量的了解逐渐增加它。

Sentry SDK 提供了两个配置选项来控制发送到 Sentry 的事务数量,使你可以获取具有代表性的样本:

  1. 统一采样率 (tracesSampleRate):
  • 提供一个均匀的事务横截面,无论这些事务在应用程序的哪个部分或在什么情况下发生。
  • 使用默认的继承优先级行为
  1. 采样函数 (tracesSampler),它可以:
  • 以不同的速率对不同的事务进行采样
  • 过滤 掉一些事务
  • 修改默认的优先级继承行为

默认情况下,这些选项均未设置,这意味着不会有任何事务发送到 Sentry。你需要设置其中一个选项以开始发送事务。

为了实现这一点,在 Sentry.init() 中将 tracesSampleRate 选项设置为 0 到 1 之间的一个数字。设置此选项后,创建的每个事务都有该百分比的机会被发送到 Sentry。(例如,如果您将 tracesSampleRate 设置为 0.5,大约 50% 的事务将被记录并发送。)这看起来像这样:

Copied
Sentry.init({
  // ...

  tracesSampleRate: 0.5,
});

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

Copied
// The shape of samplingContext that is passed to the tracesSampler function
interface SamplingContext {
  // Name of the span
  name: string;
  // Initial attributes of the span
  attributes: SpanAttributes | undefined;
  // If the parent span was sampled - undefined if there is no parent span
  parentSampled: boolean | undefined;
}

Sentry.init({
  // ...

  tracesSampler: ({ name, attributes, parentSampled }) => {
    // Do not sample health checks ever
    if (name.includes("healthcheck")) {
      // Drop this completely by setting its sample rate to 0%
      return 0;
    }

    // These are important - take a big sample
    if (name.includes("auth")) {
      return 1;
    }

    // These are less important or happen much more frequently - only take 1%
    if (name.includes("comment")) {
      return 0.01;
    }

    // Continue trace decision, if there is any parentSampled information
    if (typeof parentSampled === "boolean") {
      return parentSampled;
    }

    // Else, use default sample rate
    return 0.5;
  },
});

为了方便,该函数也可以返回布尔值。返回 true 等同于返回 1,将保证事务会被发送到 Sentry。返回 false 等同于返回 0,将保证事务不会被发送到 Sentry。

在创建事务时传递给 tracesSampler 的 samplingContext 对象中包含的信息因平台和集成而异。

在使用自定义 instrumentation 创建事务时,可以通过将数据作为可选的第二个参数传递给 startTransaction 来添加到 samplingContext。这在有你不希望作为 tagsdata 附加到事务但又希望采样器能够访问的数据时非常有用,例如敏感信息或过大的数据。例如:

Copied
Sentry.startSpan({
  name: "Search from navbar",
  op: "search",
  attributes: {
    testGroup: "A3",
    treatmentName: "eager load",
  },
});

// Will result in `tracesSampler` receiving:
function tracesSampler(samplingContext) {
  /*
  samplingContext = { 
    name: "Search from navbar", 
    attributes: {
      testGroup: 'A3',
      treatmentName: 'eager load',
    },
  }
  */

  // Do not sample this specific span
  return name !== "Search from navbar";
}

无论事务的采样决策是什么,该决策都会传递给其子跨度(spans),然后从那里传递给这些子跨度在其他服务中引发的任何事务。

(有关传播方式的更多信息,请参阅 分布式跟踪。)

如果当前创建的事务是这些后续事务之一(换句话说,它有父事务),上游(父)采样决策将包含在采样上下文数据中。你的 tracesSampler 可以使用这些信息来决定是否继承该决策。在大多数情况下,继承是正确的选择,以避免破坏分布式跟踪。一个断裂的跟踪将不会包含所有你的服务。

Copied
tracesSampler: samplingContext => {
  // always inherit
  if (samplingContext.parentSampled !== undefined) {
    return samplingContext.parentSampled
  }

  ...
  // rest of sampling logic here
}

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

如果你在创建事务时已经知道是否要将事务发送到 Sentry,你也可以直接将采样决策传递给事务构造函数(注意,不是在 customSamplingContext 对象中)。如果你这样做,事务将不会受 tracesSampleRate 的影响,tracesSampler 也不会运行,因此你可以确保传递的决策不会被覆盖。

事务可以通过多种方式获得采样决策:

  • 根据在 tracesSampleRate 中设置的静态采样率进行随机采样
  • 根据 tracesSampler 返回的采样函数率进行随机采样
  • tracesSampler 返回的绝对决策(100% 概率或 0% 概率)
  • 如果事务有父事务,则继承其父事务的采样决策
  • 传递给 startTransaction 的绝对决策

当有可能多个决策同时生效时,以下优先级规则适用:

  1. 如果将采样决策传递给 startTransaction,则使用该决策,覆盖其他所有决策。
  2. 如果定义了 tracesSampler,则使用其决策。它可以决定保留或忽略任何父采样决策,使用采样上下文数据做出自己的决策,或为事务选择采样率。(我们建议不要覆盖父采样决策,因为这会破坏分布式跟踪)
  3. 如果未定义 tracesSampler 但有父采样决策,则使用父采样决策。
  4. 如果未定义 tracesSampler 且没有父采样决策,则使用 tracesSampleRate