采样

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

将 Sentry 添加到您的应用程序中可以为您提供许多关于错误和性能的宝贵信息,否则您将无法获得这些信息。大量信息是好的——只要它是正确的信息,并且量适中。

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

config/packages/sentry.yaml
Copied
sentry:
  options:
    sample_rate: 0.25

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

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

我们推荐对事务进行采样,原因如下:

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

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

Sentry SDK 提供了两个配置选项来控制发送到 Sentry 的事务量,允许您获取代表性样本:

  1. 均匀采样率 (traces_sample_rate):

    • 提供应用程序中任何位置和任何情况下事务的均匀样本。
    • 使用默认的 继承优先级 行为
  2. 采样函数 (traces_sampler):

    • 以不同的速率对不同的事务进行采样
    • 过滤掉某些 事务完全
    • 修改默认的 优先级继承 行为

默认情况下,这些选项均未设置,这意味着不会向 Sentry 发送任何事务。您必须设置其中一个选项以开始发送事务。

要实现这一点,请将 traces_sample_rate 选项设置为介于 0 和 1 之间的数字。使用此选项设置后,每个创建的事务都有该百分比的机会被发送到 Sentry。(例如,如果您将 traces_sample_rate 设置为 0.2,则大约 20% 的事务将被记录并发送。)如下所示:

config/packages/sentry.yaml
Copied
sentry:
  options:
    traces_sample_rate: 0.2

要使用采样函数,请将 traces_sampler 选项设置为一个闭包,该闭包将接受一个 \Sentry\Tracing\SamplingContext 对象并返回一个介于 0 和 1 之间的采样率。例如:

config/packages/sentry.yaml
Copied
sentry:
  options:
    traces_sampler: "sentry.callback.traces_sampler"

services:
  sentry.callback.traces_sampler:
    class: 'App\Service\Sentry'
    factory: ['@App\Service\Sentry', "getTracesSampler"]

The service needed for the traces_sampler option can be implemented as follows:

src/Service/Sentry.php
Copied
<?php

namespace App\Service;

class Sentry
{
    public function getTracesSampler(): callable
    {
        return function (\Sentry\Tracing\SamplingContext $context): float {
            if ($context->getParentSampled()) {
                // If the parent transaction (for example a JavaScript front-end)
                // is sampled, also sample the current transaction
                return 1.0;
            }

            if (some_condition()) {
                // Drop this transaction, by setting its sample rate to 0
                return 0;
            }

            // Default sample rate for all other transactions (replaces `traces_sample_rate`)
            return 0.25;
        };
    }
}

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

对于 PHP SDK,它至少包括以下内容:

Copied
/** @var \Sentry\Tracing\SamplingContext $context */

// The context of the transaction (of type \Sentry\Tracing\TransactionContext)
$context->getTransactionContext();

// Sampling decision from the parent transaction, if any
$context->getParentSampled();

// Additional context, depending on where the SDK runs
$context->getAdditionalContext();

当使用自定义检测来创建事务时,可以通过将数据作为可选的第二个参数传递给 start_transaction 来添加到 sampling_context 对象中。这对于您希望采样器访问但不想作为 tagsdata 附加到事务的数据非常有用,例如敏感信息或太大而无法与事务一起发送的信息。例如:

Copied
\Sentry\startTransaction(
    new \Sentry\Tracing\TransactionContext(
        $name = 'Search from navbar',
        $parentSampled = false
    ),
    $customSamplingContext = [
        // PII
        'userId' => '12312012',
        // too big to send
        'resultsFromLastSearch' => [ ... ]
    ]
);

无论事务的采样决策如何,该决策将传递给其子 span,并从那里传递给它们在其他服务中引发的任何事务。

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

config/packages/sentry.yaml
Copied
sentry:
  options:
    traces_sampler: "sentry.callback.traces_sampler"

services:
  sentry.callback.traces_sampler:
    class: 'App\Service\Sentry'
    factory: ['@App\Service\Sentry', "getTracesSampler"]

The service needed for the traces_sampler option can be implemented as follows:

src/Service/Sentry.php
Copied
<?php

namespace App\Service;

class Sentry
{
    public function getTracesSampler(): callable
    {
        return function (\Sentry\Tracing\SamplingContext $context): float {
            // always inherit
            if ($context->getParentSampled()) {
                return 1.0;
            }

            // the rest of sampling logic
        };
    }
}

如果您使用的是 traces_sample_rate 而不是 traces_sampler,决策将始终被继承。

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

Copied
$transactionContext = (new \Sentry\Tracing\TransactionContext(
    $name = 'Search from navbar',
    $parentSampled = false
))
    ->setSampled(true);

$transaction = \Sentry\startTransaction($transactionContext);

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

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

当存在多种采样决策的可能性时,以下优先级规则适用:

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