Skip to content

Resource Configuration Inconsistency in Processor vs Global Configuration #850

Open
@georgeguimaraes

Description

@georgeguimaraes

There appears to be an inconsistency between the documented/implied behavior and actual implementation regarding resource configuration in OpenTelemetry Erlang, specifically with respect to processor-specific resource configurations.

Observed Behavior

When configuring a resource at the processor level like this:

  config :opentelemetry,
    processors: [
      otel_batch_processor: %{
        resource: %{
          "service.name" => "my_service",
          "custom.attribute" => "value"
        },
        exporter: {...}
      }
    ]

The processor initialization code in otel_batch_processor.erl appears to handle this configuration:

  Resource = case maps:find(resource, Args) of
                 {ok, R} ->
                     R;
                 error ->
                     otel_resource_detector:get_resource()
                end,

However, when spans are exported, this processor-specific resource is not used. Instead, the export function in otel_exporter_traces_otlp.erl uses the global resource passed to it:

  export(Tab, Resource, #state{...}) ->
      case otel_otlp_traces:to_proto(Tab, Resource) of
          ...

Attempting to use processor-specific resources leads to errors like:

  [info] span exporter threw exception: exporter=:opentelemetry_exporter exception error: no function clause matching
                   otel_attributes:dropped(undefined) (src/otel_attributes.erl, line 92)
    in function  otel_otlp_traces:to_proto/2 (.../deps/opentelemetry_exporter/src/otel_otlp_traces.erl, line 39)

This occurs because while the processor initialization accepts a resource configuration, this resource is never passed to the export function.

Expected Behavior

One of the following should be true:

  1. If processor-specific resources are intended to be supported, then the processor-specific resource should be passed to the export function and merged with or override the global resource.
  2. If processor-specific resources are not intended to be supported, then the configuration option should either be removed from the processor initialization or clearly documented as not functioning.

Questions

  1. Is it intentional that processor-specific resources don't affect the exported spans?
  2. Should users always configure resources at the global level (config :opentelemetry, resource: %{...}) instead of at the processor level?
  3. If processor-specific resources are intended to be supported, is there a bug in how they're passed to the export function?

Environment

  • Erlang/OTP: 26.1
  • Elixir: 1.18.3
  • opentelemetry: 1.5.0
  • opentelemetry_api: 1.4.0
  • opentelemetry_exporter: 1.8.0

Workaround

The current workaround is to always configure resources at the global level:

  config :opentelemetry,
    resource: %{
      "service.name" => "my_service",
      "custom.attribute" => "value"
    },
    processors: [
      otel_batch_processor: %{
        exporter: {...}
      }
    ]

This ensures that all resources are properly included in exported spans. However, we may not want this if using multiple processors.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions