-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Erlang Sampler and Resource documentation (#2556)
Co-authored-by: Patrice Chalin <[email protected]> Co-authored-by: Fred Hebert <[email protected]> Co-authored-by: Maciej Szlosarczyk <[email protected]>
- Loading branch information
1 parent
3f3b9f3
commit 5df8876
Showing
4 changed files
with
328 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
--- | ||
title: Resources | ||
weight: 36 | ||
--- | ||
|
||
A [resource](/docs/reference/specification/overview/#resources) represents an | ||
entity producing telemetry as attributes. For example, an OTP Release producing | ||
telemetry that is running in a container on Kubernetes has an OTP Release name, | ||
a Pod name, a namespace, and possibly a deployment name. All four of these | ||
attributes can be included in the resource. | ||
|
||
In your observability backend, you can use resource information to better | ||
investigate interesting behavior. For example, if your trace or metrics data | ||
indicate latency in your system, you can narrow it down to a specific container, | ||
pod, or Kubernetes deployment. | ||
|
||
## Using resource detectors | ||
|
||
Resource detectors fetch resource attributes from various sources. The default | ||
detectors use the OS environment variable `OTEL_RESOURCE_ATTRIBUTES` and the | ||
`opentelemetry` OTP Application environment variable `resource`. | ||
|
||
The detectors to use is a list of module names and can be configured in the | ||
Application configuration: | ||
|
||
<!-- prettier-ignore-start --> | ||
{{< tabpane langEqualsHeader=true >}} | ||
|
||
{{< tab Erlang >}} | ||
%% sys.config | ||
{resource_detectors, [otel_resource_env_var, otel_resource_app_env]} | ||
{{< /tab >}} | ||
|
||
{{< tab Elixir >}} | ||
## runtime.exs | ||
resource_detectors: [:otel_resource_env_var, :otel_resource_app_env] | ||
{{< /tab >}} | ||
|
||
{{< /tabpane >}} | ||
<!-- prettier-ignore-end --> | ||
|
||
Or through the environment variable `OTEL_RESOURCE_DETECTORS`: | ||
|
||
```sh | ||
OTEL_RESOURCE_DETECTORS=otel_resource_env_var,otel_resource_app_env | ||
``` | ||
|
||
All resources detectors are protected with a timeout, in milliseconds, after | ||
which they return an empty value. This allows for resource detectors to do | ||
things like hit the network without potentially hanging the entire program | ||
indefinitely. The default is 5000 milliseconds and can be set with environment | ||
variable `OTEL_RESOURCE_DETECTOR_TIMEOUT` or Application variable | ||
`otel_resource_detector_timeout`. | ||
|
||
## Adding resources with OS and Application environment variables | ||
|
||
With the two default resource detectors enabled you can set resource attributes | ||
either with the OS environment variable `OTEL_RESOURCE_ATTRIBUTES`: | ||
|
||
```sh | ||
OTEL_RESOURCE_ATTRIBUTES="deployment.environment=development" | ||
``` | ||
|
||
Alternatively, use the `resource` Application environment under the | ||
`opentelemetry` Application configuration of `sys.config` or `runtime.exs`: | ||
|
||
<!-- prettier-ignore-start --> | ||
{{< tabpane langEqualsHeader=true >}} | ||
|
||
{{< tab Erlang >}} | ||
%% sys.config | ||
{resource, #{deployment => #{environment => <<"development">>}} | ||
{{< /tab >}} | ||
|
||
{{< tab Elixir >}} | ||
## runtime.exs | ||
resource: %{deployment: %{environment: "development" }} | ||
{{< /tab >}} | ||
|
||
{{< /tabpane >}} | ||
<!-- prettier-ignore-end --> | ||
|
||
Resource attributes in the `resource` Application environment variable are | ||
flattened and combined with `.`, so | ||
`#{deployment => #{environment => <<"development">> }` is the same as | ||
`#{'deployment.environment' => <<"development">>}`. | ||
|
||
## Custom resource detectors | ||
|
||
Custom resource detectors can be created by implementing the | ||
[`otel_resource_detector` behaviour](https://hexdocs.pm/opentelemetry/1.3.0/otel_resource_detector.html#callbacks) | ||
which contains a single callback `get_resource/1` that returns an | ||
[`otel_resource`](https://hexdocs.pm/opentelemetry/1.3.0/otel_resource.html). | ||
|
||
Note that there are | ||
[semantic conventions](/docs/reference/specification/resource/semantic_conventions/) | ||
defined for `resource` that should be followed if they apply when adding new | ||
resource attributes. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
--- | ||
title: Sampling | ||
weight: 37 | ||
--- | ||
|
||
[Sampling](/docs/concepts/sampling/) is a process that restricts the amount of | ||
traces that are generated by a system. The Erlang SDK offers several | ||
[head samplers](/docs/concepts/sampling#head-sampling). | ||
|
||
## Default behavior | ||
|
||
By default, all spans are sampled, and thus, 100% of traces are sampled. If you | ||
do not need to manage data volume, you do not need to configure a sampler. | ||
|
||
## ParentBasedSampler | ||
|
||
When sampling, the `ParentBasedSampler` is most often used for | ||
[head sampling](/docs/concepts/sampling/#head-sampling). It uses the sampling | ||
decision of the Span's parent, or the fact that there is no parent, to know | ||
which secondary sampler to use. | ||
|
||
The sampler can be configured with the environment variables | ||
`OTEL_TRACES_SAMPLER` and `OTEL_TRACES_SAMPLER_ARG` or using the Application | ||
configuration allows you to configure each of the 5 potential states of a Span's | ||
parent: | ||
|
||
- `root` - No parent | ||
- `remote_parent_sampled` - Parent is from a remote Span that is sampled | ||
- `remote_parent_not_sampled` - Parent is from a remote Span that is not sampled | ||
- `local_parent_sampled` - Parent is from a local Span that is sampled | ||
- `local_parent_not_sampled` - Parent is from a local Span that is not sampled | ||
|
||
### TraceIdRatioBasedSampler | ||
|
||
Within the `ParentBasedSampler` the most common is the | ||
`TraceIdRatioBasedSampler`. It deterministically samples a percentage of traces | ||
that you pass in as a parameter. | ||
|
||
#### Environment Variables | ||
|
||
You can configure the `TraceIdRatioBasedSampler` with environment variables: | ||
|
||
```shell | ||
export OTEL_TRACES_SAMPLER="parentbased_traceidratio" | ||
export OTEL_TRACES_SAMPLER_ARG="0.1" | ||
``` | ||
|
||
This tells the SDK to sample spans such that only 10% of Traces get created. | ||
|
||
#### Application configuration | ||
|
||
Example in the Application configuration with a root sampler for sampling 10% of | ||
Traces and using the parent decision in the other cases: | ||
|
||
<!-- prettier-ignore-start --> | ||
{{< tabpane langEqualsHeader=true >}} | ||
|
||
{{< tab Erlang >}} | ||
%% config/sys.config.src | ||
{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}}} | ||
{{< /tab >}} | ||
|
||
{{< tab Elixir >}} | ||
# config/runtime.exs | ||
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}} | ||
|
||
{{< /tab >}} | ||
|
||
{{< /tabpane >}} | ||
<!-- prettier-ignore-end --> | ||
|
||
### AlwaysOn and AlwaysOff Sampler | ||
|
||
The other two built-in samplers are the `AlwaysOnSampler` and the | ||
`AlwaysOffSampler`. | ||
|
||
#### Environment Variables | ||
|
||
You can configure the `ParentBasedSampler` to use either the `AlwaysOnSampler` | ||
or `AlwaysOffSampler` with the environment variable `OTEL_TRACES_SAMPLER`: | ||
|
||
```shell | ||
export OTEL_TRACES_SAMPLER="parentbased_always_on" | ||
``` | ||
|
||
And for the `AlwaysOffSampler`: | ||
|
||
```shell | ||
export OTEL_TRACES_SAMPLER="parentbased_always_off" | ||
``` | ||
|
||
#### Application configuration | ||
|
||
Here's an example in the Application configuration with a root sampler that | ||
always samples and using the parent decision in the other cases: | ||
|
||
<!-- prettier-ignore-start --> | ||
{{< tabpane langEqualsHeader=true >}} | ||
|
||
{{< tab Erlang >}} | ||
%% config/sys.config.src | ||
{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}}} | ||
{{< /tab >}} | ||
|
||
{{< tab Elixir >}} | ||
# config/runtime.exs | ||
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}} | ||
|
||
{{< /tab >}} | ||
|
||
{{< /tabpane >}} | ||
<!-- prettier-ignore-end --> | ||
|
||
## Custom Sampler | ||
|
||
Custom samplers can be created by implementing the | ||
[`otel_sampler` behaviour](https://hexdocs.pm/opentelemetry/1.3.0/otel_sampler.html#callbacks). | ||
This example sampler: | ||
|
||
<!-- prettier-ignore-start --> | ||
{{< tabpane langEqualsHeader=true >}} | ||
|
||
{{< tab Erlang >}} | ||
-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) -> | ||
case maps:intersect(Attributes, ConfigAttributes) of | ||
Map when map_size(Map) > 0 -> | ||
{?DROP, [], []}; | ||
_ -> | ||
{?RECORD_AND_SAMPLE, [], []} | ||
end. | ||
{{< /tab >}} | ||
|
||
{{< tab Elixir >}} | ||
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 | ||
case :maps.intersect(attributes, config_attributes) do | ||
map when map_size(map) > 0 -> | ||
{:drop, [], []} | ||
_ -> | ||
{:record_and_sample, [], []} | ||
end | ||
end | ||
end | ||
{{< /tab >}} | ||
|
||
{{< /tabpane >}} | ||
<!-- prettier-ignore-end --> | ||
|
||
Will sample Spans that do not have any attributes that match the attributes | ||
passed as the sampler's configuration. | ||
|
||
Example configuration to not sample any Span with an attribute specifying the | ||
URL requested is `/healthcheck`: | ||
|
||
<!-- prettier-ignore-start --> | ||
{{< tabpane langEqualsHeader=true >}} | ||
|
||
{{< tab Erlang >}} | ||
{sampler, {attributes_sampler, #{'http.target' => <<"/healthcheck">>}}} | ||
{{< /tab >}} | ||
|
||
{{< tab Elixir >}} | ||
sampler: {AttributesSampler, %{"http.target": "/healthcheck"}} | ||
{{< /tab >}} | ||
|
||
{{< /tabpane >}} | ||
<!-- prettier-ignore-end --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters