open-telemetry / open-telemetry/opentelemetry-python-contrib

`requests` instrumentation should not modify the custom headers dictionary

Open
#1,729 3 comments 1 reaction 1 assignee View on GitHub

@avzis is already working on this.

Since Mar 28, 2023.

bug
Dominant language
Python
Stars
1.1k
Forks
1.1k
Avg merge
4d 15h
Merged PRs (30d)
16

Description

Describe your environment
Using python 3.10 and

opentelemetry-api==1.16.0
opentelemetry-distro==0.37b0
opentelemetry-exporter-otlp-proto-http==1.15.0
opentelemetry-instrumentation==0.37b0
opentelemetry-instrumentation-botocore==0.37b0
opentelemetry-instrumentation-requests==0.37b0
opentelemetry-proto==1.15.0
opentelemetry-sdk==1.16.0
opentelemetry-semantic-conventions==0.37b0
opentelemetry-util-http==0.37b0
requests==2.28.1

Steps to reproduce
When you pass a custom header dictionary to requests, e.g. requests.get("http://example.com", headers=myheaders), opentelemetry instrumentation code injects tracing headers into it. However it should create a copy of the dict instead of modifying it directly. It leads to subtle bugs when the header dictionary is a variable that is long lived and used elsewhere in the user code.

Running the code below illustrates the problem.

# Setup OTEL
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter
from opentelemetry.sdk.resources import SERVICE_NAME, Resource

resource = Resource(attributes={
    SERVICE_NAME: "your-service-name"
})

provider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(ConsoleSpanExporter(out=open('/dev/null', 'w')))
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)

# Set up requests instrumentation
import requests
from opentelemetry.instrumentation.requests import RequestsInstrumentor
RequestsInstrumentor().instrument()

# Try to use requests
HEADERS = {}
print("Headers before", HEADERS)
requests.get('http://example.com', headers=HEADERS)
print("Headers after", HEADERS)

What is the expected behavior?
Instrumentation should not modify the dictionary. The code above should print

Headers before {}
Headers after {}

What is the actual behavior?
Instead, the dictionary is modified and the code above prints something like

Headers before {}
Headers after {'traceparent': '00-3fa34759485cfd649023710bd9841f85-bf965377dfd3846d-01'}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.