From 3ba57a04fcacae0a29cc45c4c128c0c940264391 Mon Sep 17 00:00:00 2001 From: Adrian Gruntkowski Date: Mon, 13 Nov 2023 14:57:51 +0100 Subject: [PATCH] Make OpenTelemetry sampler ratio configurable via env (#3514) --- config/runtime.exs | 7 ++++++- lib/plausible/open_telemetry/sampler.ex | 23 ++++++++++++----------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/config/runtime.exs b/config/runtime.exs index 7e92329d4..424496ea9 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -178,6 +178,11 @@ google_cid = get_var_from_path_or_env(config_dir, "GOOGLE_CLIENT_ID") google_secret = get_var_from_path_or_env(config_dir, "GOOGLE_CLIENT_SECRET") postmark_api_key = get_var_from_path_or_env(config_dir, "POSTMARK_API_KEY") +{otel_sampler_ratio, ""} = + config_dir + |> get_var_from_path_or_env("OTEL_SAMPLER_RATIO", "0.5") + |> Float.parse() + cron_enabled = config_dir |> get_var_from_path_or_env("CRON_ENABLED", "false") @@ -612,7 +617,7 @@ end if honeycomb_api_key && honeycomb_dataset do config :opentelemetry, resource: Plausible.OpenTelemetry.resource_attributes(runtime_metadata), - sampler: {Plausible.OpenTelemetry.Sampler, nil}, + sampler: {Plausible.OpenTelemetry.Sampler, %{ratio: otel_sampler_ratio}}, span_processor: :batch, traces_exporter: :otlp diff --git a/lib/plausible/open_telemetry/sampler.ex b/lib/plausible/open_telemetry/sampler.ex index 53571159e..e6a459904 100644 --- a/lib/plausible/open_telemetry/sampler.ex +++ b/lib/plausible/open_telemetry/sampler.ex @@ -10,13 +10,10 @@ defmodule Plausible.OpenTelemetry.Sampler do import Bitwise, only: [&&&: 2] - # effective sampling ratio for non-ignored traces - @ratio 0.5 + # mask for extracting first 64 bits of trace ID # 2^63 - 1 @max_value 9_223_372_036_854_775_807 - @id_upper_bound @ratio * @max_value - @behaviour :otel_sampler require OpenTelemetry.Tracer, as: Tracer @@ -24,13 +21,17 @@ defmodule Plausible.OpenTelemetry.Sampler do @tables_to_ignore ["oban_jobs"] @impl true - def setup(_sampler_opts), do: [] + def setup(%{ratio: ratio}) when is_number(ratio) do + %{ratio: ratio, id_upper_bound: ratio * @max_value} + end @impl true - def description(_sampler_config), do: inspect(__MODULE__) + def description(%{ratio: ratio}) do + "#{inspect(__MODULE__)}{ratio=#{ratio}}" + end @impl true - def should_sample(context, trace_id, _links, _name, _kind, attributes, _config) do + def should_sample(context, trace_id, _links, _name, _kind, attributes, config) do tracestate = context |> Tracer.current_span_ctx() |> OpenTelemetry.Span.tracestate() case attributes do @@ -41,19 +42,19 @@ defmodule Plausible.OpenTelemetry.Sampler do {:drop, [], tracestate} _any -> - {decide(trace_id), [], tracestate} + {decide(trace_id, config.id_upper_bound), [], tracestate} end end - defp decide(trace_id) when is_integer(trace_id) and trace_id > 0 do + defp decide(trace_id, id_upper_bound) when is_integer(trace_id) and trace_id > 0 do lower_64_bits = trace_id &&& @max_value - if abs(lower_64_bits) < @id_upper_bound do + if abs(lower_64_bits) < id_upper_bound do :record_and_sample else :drop end end - defp decide(_), do: :drop + defp decide(_, _), do: :drop end