open-telemetry / open-telemetry/opentelemetry-python
Multiple `metric_readers` causes deadlock
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.6k
- Forks
- 1k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 19
Description
Summary
Setting up multiple metrics readers like this:
mprovider = MeterProvider(resource=resource, metric_readers=[console_metric_reader, otlp_metric_reader])
causes a deadlock.
Caveat
It happens rarely, so this may not be tremendously high priority - but I'm reporting so if someone else hits this, they may add to the body of evidence pointing to the underlying issue.
Environment
Python 3.11.6 on macOS Sonoma v14.1.1
Steps to reproduce
1. Run a simple Flask web server with otel instrumentation:
console_metric_reader = PeriodicExportingMetricReader(ConsoleMetricExporter())
otlp_metric_reader = PeriodicExportingMetricReader(OTLPMetricExporter(endpoint=OTLP_ENDPOINT))
mprovider = MeterProvider(resource=resource, metric_readers=[console_metric_reader, otlp_metric_reader])
metrics.set_meter_provider(mprovider)
meter = metrics.get_meter("demo-meter")
2. Send requests to the endpoint
while true
curl localhost:8080
sleep 1
end
3. Wait for the deadlock
Unfortunately, it is not always reproducible. Sometimes the app must be running for >5 minutes. Sometimes it happens immediately.
Expected behavior
- Console exporter prints metrics to stdout
- OTLP exporter errors out print to stdout
What is the actual behavior?
When the deadlock occurs, the traceback looks like this:
...
File "/opt/homebrew/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 1123, in join
self._wait_for_tstate_lock(timeout=max(timeout, 0))
File "/opt/homebrew/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 1139, in _wait_for_tstate_lock
if lock.acquire(block, timeout):
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Use the MeterProvider configuration with two PeriodicExportingMetricReader instances as the entry point; first run the Flask/curl reproduction and inspect the threading.join traceback. Done means multiple readers can run without the reported deadlock while preserving console output and OTLP error behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- observability-sre
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100