采样

采样是限制系统生成跟踪数量的过程。Erlang SDK 提供了几种 头部采样器

默认行为

默认情况下,所有 span 都会被采样,因此 100% 的跟踪都会被采样。如果您不需要管理数据量,则无需配置采样器。

ParentBasedSampler

在采样时,ParentBasedSampler 最常用于 头部采样。它利用 Span 的父级或不存在父级这一事实来决定使用哪个次级采样器。

可以通过环境变量 OTEL_TRACES_SAMPLEROTEL_TRACES_SAMPLER_ARG 或通过应用程序配置来配置采样器,允许您配置 Span 父级的 5 种潜在状态。

  • root - 无父级
  • remote_parent_sampled - 父级来自已采样的远程 Span
  • remote_parent_not_sampled - 父级来自未采样的远程 Span
  • local_parent_sampled - 父级来自已采样的本地 Span
  • local_parent_not_sampled - 父级来自未采样的本地 Span

TraceIdRatioBasedSampler

ParentBasedSampler 中,最常见的是 TraceIdRatioBasedSampler。它会以确定性的方式对您作为参数传入的跟踪百分比进行采样。

环境变量

您可以通过环境变量配置 TraceIdRatioBasedSampler

export OTEL_TRACES_SAMPLER="parentbased_traceidratio"
export OTEL_TRACES_SAMPLER_ARG="0.1"

这会告诉 SDK 对 span 进行采样,以便只创建 10% 的跟踪。

应用程序配置

应用程序配置中的示例,使用 root sampler 对 10% 的跟踪进行采样,并在其他情况下使用父级决策。

%% config/sys.config.src
{opentelemetry, {sampler, {parent_based, #{root => {trace_id_ratio_based, 0.10},
                                          remote_parent_sampled => always_on,
                                          remote_parent_not_sampled => always_off,
                                          local_parent_sampled => always_on,
                                          local_parent_not_sampled => always_off}}}}
# config/runtime.exs
config :opentelemetry, sampler: {:parent_based, %{root: {:trace_id_ratio_based, 0.10},
                                                  remote_parent_sampled: :always_on,
                                                  remote_parent_not_sampled: :always_off,
                                                  local_parent_sampled: :always_on,
                                                  local_parent_not_sampled: :always_off}}

AlwaysOn 和 AlwaysOff Sampler

另外两个内置采样器是 AlwaysOnSamplerAlwaysOffSampler

环境变量

您可以使用环境变量 OTEL_TRACES_SAMPLERParentBasedSampler 配置为使用 AlwaysOnSamplerAlwaysOffSampler

export OTEL_TRACES_SAMPLER="parentbased_always_on"

以及 AlwaysOffSampler

export OTEL_TRACES_SAMPLER="parentbased_always_off"

应用程序配置

以下是在应用程序配置中使用 root sampler 始终采样的示例,并在其他情况下使用父级决策。

%% config/sys.config.src
{opentelemetry, {sampler, {parent_based, #{root => always_on,
                                          remote_parent_sampled => always_on,
                                          remote_parent_not_sampled => always_off,
                                          local_parent_sampled => always_on,
                                          local_parent_not_sampled => always_off}}}}
# config/runtime.exs
config :opentelemetry, sampler: {:parent_based, %{root: :always_on,
                                                  remote_parent_sampled: :always_on,
                                                  remote_parent_not_sampled: :always_off,
                                                  local_parent_sampled: :always_on,
                                                  local_parent_not_sampled: :always_off}}

自定义 Sampler

可以通过实现 otel_sampler behaviour 来创建自定义采样器。此示例采样器

-module(attribute_sampler).

-behavior(otel_sampler).

-export([description/1,
         setup/1,
         should_sample/7]).

-include("otel_sampler.hrl").

setup(Attributes) when is_map(Attributes) ->
    Attributes;
setup(_) ->
    #{}.

description(_) ->
    <<"AttributeSampler">>.

should_sample(_Ctx, _TraceId, _Links, _SpanName, _SpanKind, Attributes, ConfigAttributes) ->
    AttributesSet = sets:from_list(maps:to_list(Attributes)),
    ConfigSet = sets:from_list(maps:to_list(ConfigAttributes)),
    case sets:is_disjoint(AttributesSet, ConfigSet) of
        true -> {?RECORD_AND_SAMPLE, [], []};
        _ -> {?DROP, [], []}
end.
defmodule AttributesSampler do
  def setup(attributes) when is_map(attributes) do
    attributes
  end

  def setup(_) do
    %{}
  end

  def description(_) do
    "ExampleSampler"
  end

  def should_sample(_ctx, _trace_id, _links, _span_name, _span_kind, attributes, config_attributes) do
    no_match =
      Enum.into(attributes, %MapSet{})
      |> MapSet.disjoint?(Enum.into(config_attributes, %MapSet{}))

    if no_match, do: {:record_and_sample, [], []}, else: {:drop, [], []}
  end
end

将对不具有与作为采样器配置传入的属性匹配的任何属性的 Span 进行采样。

不采样任何具有指定请求 URL 为 /healthcheck 的属性的 Span 的示例配置。

{opentelemetry, {sampler, {attributes_sampler, #{'http.target' => <<"/healthcheck">>}}}}
config :opentelemetry, sampler: {AttributesSampler, %{"http.target": "/healthcheck"}}

最后修改于 2024 年 3 月 20 日: fix: erlang elixir samples (#4177) (800f4a7d)