|
1 | 1 | defmodule Sentry.Config do
|
2 | 2 | @moduledoc false
|
3 | 3 |
|
| 4 | + @typedoc """ |
| 5 | + A function that determines the sample rate for transaction events. |
| 6 | +
|
| 7 | + The function receives a sampling context map and should return a boolean or a float between `0.0` and `1.0`. |
| 8 | + """ |
| 9 | + @type traces_sampler_function :: (map() -> boolean() | float()) | {module(), atom()} |
| 10 | + |
4 | 11 | integrations_schema = [
|
5 | 12 | max_expected_check_in_time: [
|
6 | 13 | type: :integer,
|
@@ -143,6 +150,49 @@ defmodule Sentry.Config do
|
143 | 150 | be used as the value for this option.
|
144 | 151 | """
|
145 | 152 | ],
|
| 153 | + traces_sample_rate: [ |
| 154 | + type: {:custom, __MODULE__, :__validate_traces_sample_rate__, []}, |
| 155 | + default: nil, |
| 156 | + doc: """ |
| 157 | + The sample rate for transaction events. A value between `0.0` and `1.0` (inclusive). |
| 158 | + A value of `0.0` means no transactions will be sampled, while `1.0` means all transactions |
| 159 | + will be sampled. |
| 160 | +
|
| 161 | + This value is also used to determine if tracing is enabled: if it's not `nil`, tracing is enabled. |
| 162 | +
|
| 163 | + Tracing requires OpenTelemetry packages to work. See [the |
| 164 | + OpenTelemetry setup documentation](https://opentelemetry.io/docs/languages/erlang/getting-started/) |
| 165 | + for guides on how to set it up. |
| 166 | + """ |
| 167 | + ], |
| 168 | + traces_sampler: [ |
| 169 | + type: {:custom, __MODULE__, :__validate_traces_sampler__, []}, |
| 170 | + default: nil, |
| 171 | + type_doc: "`t:traces_sampler_function/0` or `nil`", |
| 172 | + doc: """ |
| 173 | + A function that determines the sample rate for transaction events. This function |
| 174 | + receives a sampling context struct and should return a boolean or a float between `0.0` and `1.0`. |
| 175 | +
|
| 176 | + The sampling context contains: |
| 177 | + - `:parent_sampled` - boolean indicating if the parent trace span was sampled (nil if no parent) |
| 178 | + - `:transaction_context` - map with transaction information (name, op, etc.) |
| 179 | +
|
| 180 | + If both `:traces_sampler` and `:traces_sample_rate` are configured, `:traces_sampler` takes precedence. |
| 181 | +
|
| 182 | + Example: |
| 183 | + ```elixir |
| 184 | + traces_sampler: fn sampling_context -> |
| 185 | + case sampling_context.transaction_context.op do |
| 186 | + "http.server" -> 0.1 # Sample 10% of HTTP requests |
| 187 | + "db.query" -> 0.01 # Sample 1% of database queries |
| 188 | + _ -> false # Don't sample other operations |
| 189 | + end |
| 190 | + end |
| 191 | + ``` |
| 192 | +
|
| 193 | + This value is also used to determine if tracing is enabled: if it's not `nil`, tracing is enabled. |
| 194 | + """ |
| 195 | + ], |
146 | 196 | included_environments: [
|
147 | 197 | type: {:or, [{:in, [:all]}, {:list, {:or, [:atom, :string]}}]},
|
148 | 198 | deprecated: "Use :dsn to control whether to send events to Sentry.",
|
@@ -607,6 +657,12 @@ defmodule Sentry.Config do
|
607 | 657 | @spec sample_rate() :: float()
|
608 | 658 | def sample_rate, do: fetch!(:sample_rate)
|
609 | 659 |
|
| 660 | + @spec traces_sample_rate() :: nil | float() |
| 661 | + def traces_sample_rate, do: fetch!(:traces_sample_rate) |
| 662 | + |
| 663 | + @spec traces_sampler() :: traces_sampler_function() | nil |
| 664 | + def traces_sampler, do: get(:traces_sampler) |
| 665 | + |
610 | 666 | @spec hackney_opts() :: keyword()
|
611 | 667 | def hackney_opts, do: fetch!(:hackney_opts)
|
612 | 668 |
|
@@ -644,6 +700,9 @@ defmodule Sentry.Config do
|
644 | 700 | @spec integrations() :: keyword()
|
645 | 701 | def integrations, do: fetch!(:integrations)
|
646 | 702 |
|
| 703 | + @spec tracing?() :: boolean() |
| 704 | + def tracing?, do: not is_nil(fetch!(:traces_sample_rate)) or not is_nil(get(:traces_sampler)) |
| 705 | + |
647 | 706 | @spec put_config(atom(), term()) :: :ok
|
648 | 707 | def put_config(key, value) when is_atom(key) do
|
649 | 708 | unless key in @valid_keys do
|
@@ -743,6 +802,35 @@ defmodule Sentry.Config do
|
743 | 802 | end
|
744 | 803 | end
|
745 | 804 |
|
| 805 | + def __validate_traces_sample_rate__(value) do |
| 806 | + if is_nil(value) or (is_float(value) and value >= 0.0 and value <= 1.0) do |
| 807 | + {:ok, value} |
| 808 | + else |
| 809 | + {:error, |
| 810 | + "expected :traces_sample_rate to be nil or a value between 0.0 and 1.0 (included), got: #{inspect(value)}"} |
| 811 | + end |
| 812 | + end |
| 813 | + |
| 814 | + def __validate_traces_sampler__(nil), do: {:ok, nil} |
| 815 | + |
| 816 | + def __validate_traces_sampler__(fun) when is_function(fun, 1) do |
| 817 | + {:ok, fun} |
| 818 | + end |
| 819 | + |
| 820 | + def __validate_traces_sampler__({module, function}) |
| 821 | + when is_atom(module) and is_atom(function) do |
| 822 | + if function_exported?(module, function, 1) do |
| 823 | + {:ok, {module, function}} |
| 824 | + else |
| 825 | + {:error, "function #{module}.#{function}/1 is not exported"} |
| 826 | + end |
| 827 | + end |
| 828 | + |
| 829 | + def __validate_traces_sampler__(other) do |
| 830 | + {:error, |
| 831 | + "expected :traces_sampler to be nil, a function with arity 1, or a {module, function} tuple, got: #{inspect(other)}"} |
| 832 | + end |
| 833 | + |
746 | 834 | def __validate_json_library__(nil) do
|
747 | 835 | {:error, "nil is not a valid value for the :json_library option"}
|
748 | 836 | end
|
|
0 commit comments