Sources, highest priority first:

#Source
1OTEL_CONFIG_FILE (YAML) — overrides everything below
2config :otel, ... in config/*.exs
3OTEL_* environment variables
4Built-in defaults

Application env

import Config

config :otel,
  trace: [
    resource: Otel.SDK.Resource.create(%{"service.name" => "my_app"}),
    sampler: :parentbased_always_on,
    exporter: :otlp,
    processor: :batch,
    span_limits: %{attribute_count_limit: 256}
  ],
  metrics: [
    resource: Otel.SDK.Resource.create(%{"service.name" => "my_app"}),
    exporter: :otlp,
    reader_config: %{export_interval_ms: 30_000}
  ],
  logs: [
    resource: Otel.SDK.Resource.create(%{"service.name" => "my_app"}),
    exporter: :otlp,
    processor: :batch
  ],
  propagators: [:tracecontext, :baggage]

OS environment

export OTEL_SERVICE_NAME=my_app
export OTEL_RESOURCE_ATTRIBUTES="deployment.environment=prod,service.version=1.2.3"
export OTEL_TRACES_SAMPLER=parentbased_always_on
export OTEL_TRACES_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=otlp
export OTEL_METRIC_EXPORT_INTERVAL=30000
export OTEL_LOGS_EXPORTER=otlp
export OTEL_PROPAGATORS=tracecontext,baggage

Declarative YAML (OTEL_CONFIG_FILE)

Schema: OpenTelemetry Configuration v1.0.0.

# /etc/otel/config.yaml
file_format: "1.0"

resource:
  attributes_list: ${OTEL_RESOURCE_ATTRIBUTES}

propagator:
  composite:
    - tracecontext:
    - baggage:

tracer_provider:
  sampler:
    parent_based:
      root:
        always_on:
  processors:
    - batch:
        exporter:
          otlp_http:
            endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318}/v1/traces

meter_provider:
  readers:
    - periodic:
        exporter:
          otlp_http:
            endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318}/v1/metrics

logger_provider:
  processors:
    - batch:
        exporter:
          otlp_http:
            endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318}/v1/logs
export OTEL_CONFIG_FILE=/etc/otel/config.yaml

${VAR} / ${VAR:-default} substitution works anywhere. More examples in test/fixtures/v1.0.0/.

Disable the SDK

OTEL_SDK_DISABLED=true makes telemetry calls no-ops. Propagator stays active.

Selectors

Module-valued options (exporter:, processor:, sampler:, items in propagators:) accept:

  • a shortcut atom (see tables below)
  • a module — same as {Module, %{}}
  • a {module, %{...}} tuple

Trace pillar

Optionconfig :otel, trace:OTEL_*Accepted valuesDefault
Samplersampler:OTEL_TRACES_SAMPLER:always_on / :always_off / :parentbased_always_on / :parentbased_always_off / :traceidratio / :parentbased_traceidratio / {:traceidratio, 0.5} / {Module, opts}:parentbased_always_on
Sampler argvia {:traceidratio, n} tupleOTEL_TRACES_SAMPLER_ARGfloat in 0.0..1.01.0
Exporterexporter:OTEL_TRACES_EXPORTER:otlp / :console / :none / Module / {Module, %{}}:otlp
Processorprocessor::batch / :simple / Module:batch
Processor listprocessors:list of {module, config}inferred
Batch schedule delayprocessor_config: %{scheduled_delay_ms: _}OTEL_BSP_SCHEDULE_DELAYnon-negative integer (ms)5000
Batch export timeoutprocessor_config: %{export_timeout_ms: _}OTEL_BSP_EXPORT_TIMEOUTinteger (ms); 0:infinity30000
Batch queue sizeprocessor_config: %{max_queue_size: _}OTEL_BSP_MAX_QUEUE_SIZEpositive integer2048
Batch export batch sizeprocessor_config: %{max_export_batch_size: _}OTEL_BSP_MAX_EXPORT_BATCH_SIZEpositive integer512
Span attribute countspan_limits: %{attribute_count_limit: _}OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT (or OTEL_ATTRIBUTE_COUNT_LIMIT)non-negative integer128
Span attribute value lengthspan_limits: %{attribute_value_length_limit: _}OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT (or OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT)non-negative integer or :infinity:infinity
Event countspan_limits: %{event_count_limit: _}OTEL_SPAN_EVENT_COUNT_LIMITnon-negative integer128
Link countspan_limits: %{link_count_limit: _}OTEL_SPAN_LINK_COUNT_LIMITnon-negative integer128
Per-event attribute countspan_limits: %{attribute_per_event_limit: _}OTEL_EVENT_ATTRIBUTE_COUNT_LIMITnon-negative integer128
Per-link attribute countspan_limits: %{attribute_per_link_limit: _}OTEL_LINK_ATTRIBUTE_COUNT_LIMITnon-negative integer128
Resourceresource:OTEL_RESOURCE_ATTRIBUTES, OTEL_SERVICE_NAME%Otel.SDK.Resource{}telemetry.sdk.* attributes
ID generatorid_generator:moduleOtel.SDK.Trace.IdGenerator.Default

Metrics pillar

Optionconfig :otel, metrics:OTEL_*Accepted valuesDefault
Exporterexporter:OTEL_METRICS_EXPORTER:otlp / :console / :none / Module / {Module, %{}}:otlp
Reader listreaders:list of {module, config}inferred from exporter:
Reader export intervalreader_config: %{export_interval_ms: _}OTEL_METRIC_EXPORT_INTERVALnon-negative integer (ms)60000
Reader export timeoutreader_config: %{export_timeout_ms: _}OTEL_METRIC_EXPORT_TIMEOUTinteger (ms); 0:infinity30000
Exemplar filterexemplar_filter:OTEL_METRICS_EXEMPLAR_FILTER:always_on / :always_off / :trace_based:trace_based
Viewsviews:list of Otel.SDK.Metrics.View.t()[]
Resourceresource:OTEL_RESOURCE_ATTRIBUTES, OTEL_SERVICE_NAME%Otel.SDK.Resource{}telemetry.sdk.* attributes

Logs pillar

Optionconfig :otel, logs:OTEL_*Accepted valuesDefault
Exporterexporter:OTEL_LOGS_EXPORTER:otlp / :console / :none / Module / {Module, %{}}:otlp
Processorprocessor::batch / :simple / Module:batch
Processor listprocessors:list of {module, config}inferred
Batch schedule delayprocessor_config: %{scheduled_delay_ms: _}OTEL_BLRP_SCHEDULE_DELAYnon-negative integer (ms)1000
Batch export timeoutprocessor_config: %{export_timeout_ms: _}OTEL_BLRP_EXPORT_TIMEOUTinteger (ms); 0:infinity30000
Batch queue sizeprocessor_config: %{max_queue_size: _}OTEL_BLRP_MAX_QUEUE_SIZEpositive integer2048
Batch export batch sizeprocessor_config: %{max_export_batch_size: _}OTEL_BLRP_MAX_EXPORT_BATCH_SIZEpositive integer512
LogRecord attribute countlog_record_limits: %{attribute_count_limit: _}OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT (or OTEL_ATTRIBUTE_COUNT_LIMIT)non-negative integer128
LogRecord attribute value lengthlog_record_limits: %{attribute_value_length_limit: _}OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT (or OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT)non-negative integer or :infinity:infinity
Resourceresource:OTEL_RESOURCE_ATTRIBUTES, OTEL_SERVICE_NAME%Otel.SDK.Resource{}telemetry.sdk.* attributes

Propagators

Optionconfig :otel,OTEL_*Accepted valuesDefault
Propagatorspropagators:OTEL_PROPAGATORSlist of :tracecontext / :baggage / :none (or custom modules)[:tracecontext, :baggage]

Deduplicated. [:none] or [] → Noop. :b3 / :b3multi / :jaeger / :xray / :ottrace raise; supply a custom module instead.

OTLP HTTP — SSL / TLS

The OTLP HTTP exporter uses Erlang's :httpc. For https:// endpoints, certificate verification is enabled by default using system CA certificates (:public_key.cacerts_get/0).

To override the defaults — custom CA bundle, mutual TLS, etc. — pass the exporter explicitly with an ssl_options: keyword list:

config :otel,
  trace: [
    exporter:
      {Otel.OTLP.Trace.SpanExporter.HTTP,
       %{
         endpoint: "https://collector.example.com:4318/v1/traces",
         ssl_options: [
           verify: :verify_peer,
           cacertfile: "/etc/ssl/certs/ca.crt"
         ]
       }}
  ]

ssl_options: accepts any Erlang :ssl client_option. Common patterns:

PatternOptions
Custom CA bundleverify: :verify_peer, cacertfile: "ca.crt"
Mutual TLSadd certfile: "client.crt", keyfile: "client.key"
Disable verification (dev only)verify: :verify_none

The same {Module, opts} shape works for metrics: (Otel.OTLP.Metrics.MetricExporter.HTTP) and logs: (Otel.OTLP.Logs.LogRecordExporter.HTTP).