From 5df8876f11a7bb8f9b018df66854f561b9d212bf Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Tue, 18 Apr 2023 23:37:53 -0600 Subject: [PATCH] Erlang Sampler and Resource documentation (#2556) Co-authored-by: Patrice Chalin Co-authored-by: Fred Hebert Co-authored-by: Maciej Szlosarczyk --- .../instrumentation/erlang/getting-started.md | 2 +- .../docs/instrumentation/erlang/resources.md | 98 ++++++++ .../docs/instrumentation/erlang/sampling.md | 213 ++++++++++++++++++ static/refcache.json | 16 ++ 4 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 content/en/docs/instrumentation/erlang/resources.md create mode 100644 content/en/docs/instrumentation/erlang/sampling.md diff --git a/content/en/docs/instrumentation/erlang/getting-started.md b/content/en/docs/instrumentation/erlang/getting-started.md index 17e80a2313ac..a236ba24beb8 100644 --- a/content/en/docs/instrumentation/erlang/getting-started.md +++ b/content/en/docs/instrumentation/erlang/getting-started.md @@ -102,7 +102,7 @@ Configuration is done through the [Application environment](https://erlang.org/doc/design_principles/applications.html#configuring-an-application) or [OS Environment Variables]({{< relref "/docs/reference/specification/sdk-environment-variables" >}}). The SDK (`opentelemetry` -Application) uses the configuration to initialize a [Tracer Provider](https://hexdocs.pm/opentelemetry_api/otel_tracer_provider.html), +Application) uses the configuration to initialize a [Tracer Provider](https://hexdocs.pm/opentelemetry/otel_tracer_server.html), its [Span Processors](https://hexdocs.pm/opentelemetry/otel_span_processor.html) and the [Exporter](https://hexdocs.pm/opentelemetry/otel_exporter.html). diff --git a/content/en/docs/instrumentation/erlang/resources.md b/content/en/docs/instrumentation/erlang/resources.md new file mode 100644 index 000000000000..da86888998fe --- /dev/null +++ b/content/en/docs/instrumentation/erlang/resources.md @@ -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: + + +{{< 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 >}} + + +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`: + + +{{< tabpane langEqualsHeader=true >}} + +{{< tab Erlang >}} +%% sys.config +{resource, #{deployment => #{environment => <<"development">>}} +{{< /tab >}} + +{{< tab Elixir >}} +## runtime.exs +resource: %{deployment: %{environment: "development" }} +{{< /tab >}} + +{{< /tabpane >}} + + +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. diff --git a/content/en/docs/instrumentation/erlang/sampling.md b/content/en/docs/instrumentation/erlang/sampling.md new file mode 100644 index 000000000000..d620f477e36f --- /dev/null +++ b/content/en/docs/instrumentation/erlang/sampling.md @@ -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: + + +{{< 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 >}} + + +### 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: + + +{{< 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 >}} + + +## 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: + + +{{< 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 >}} + + +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`: + + +{{< tabpane langEqualsHeader=true >}} + +{{< tab Erlang >}} +{sampler, {attributes_sampler, #{'http.target' => <<"/healthcheck">>}}} +{{< /tab >}} + +{{< tab Elixir >}} +sampler: {AttributesSampler, %{"http.target": "/healthcheck"}} +{{< /tab >}} + +{{< /tabpane >}} + diff --git a/static/refcache.json b/static/refcache.json index 2f942f00d350..cee9198b358a 100644 --- a/static/refcache.json +++ b/static/refcache.json @@ -2815,6 +2815,18 @@ "StatusCode": 206, "LastSeen": "2023-02-15T21:47:40.349021-05:00" }, + "https://hexdocs.pm/opentelemetry/1.3.0/otel_resource.html": { + "StatusCode": 206, + "LastSeen": "2023-04-18T17:53:22.687849481-06:00" + }, + "https://hexdocs.pm/opentelemetry/1.3.0/otel_resource_detector.html#callbacks": { + "StatusCode": 206, + "LastSeen": "2023-04-18T17:53:22.515854627-06:00" + }, + "https://hexdocs.pm/opentelemetry/1.3.0/otel_sampler.html#callbacks": { + "StatusCode": 206, + "LastSeen": "2023-04-18T17:53:22.862761088-06:00" + }, "https://hexdocs.pm/opentelemetry/otel_exporter.html": { "StatusCode": 206, "LastSeen": "2023-02-15T21:47:34.984079-05:00" @@ -2823,6 +2835,10 @@ "StatusCode": 206, "LastSeen": "2023-02-15T21:45:24.525812-05:00" }, + "https://hexdocs.pm/opentelemetry/otel_tracer_server.html": { + "StatusCode": 206, + "LastSeen": "2023-04-18T17:53:23.082563624-06:00" + }, "https://hexdocs.pm/opentelemetry_api/otel_tracer_provider.html": { "StatusCode": 206, "LastSeen": "2023-02-15T21:47:29.620967-05:00"