Skip to content

Commit f8028b1

Browse files
authored
Merge branch 'main' into docs-django-sqlcomment
2 parents f3eb2e2 + c6ae8e5 commit f8028b1

File tree

6 files changed

+26
-3
lines changed

6 files changed

+26
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3232
([#3875](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3875))
3333
- `opentelemetry-instrumentation-aws-lambda`: Fix ImportError with slash-delimited handler paths
3434
([#3894](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3894))
35+
- `opentelemetry-exporter-richconsole`: Prevent deadlock when parent span is not part of the batch
36+
([#3900](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3900))
3537

3638
## Version 1.38.0/0.59b0 (2025-10-16)
3739

exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/__init__.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,17 @@ def spans_to_tree(spans: typing.Sequence[ReadableSpan]) -> Dict[str, Tree]:
173173
trees = {}
174174
parents = {}
175175
spans = list(spans)
176+
span_ids = {s.context.span_id for s in spans}
176177
while spans:
177178
for span in spans:
178-
if not span.parent:
179+
if not span.parent or span.parent.span_id not in span_ids:
179180
trace_id = opentelemetry.trace.format_trace_id(
180181
span.context.trace_id
181182
)
182-
trees[trace_id] = Tree(label=f"Trace {trace_id}")
183-
child = trees[trace_id].add(
183+
tree = trees.setdefault(
184+
trace_id, Tree(label=f"Trace {trace_id}")
185+
)
186+
child = tree.add(
184187
label=Text.from_markup(
185188
f"[blue][{_ns_to_time(span.start_time)}][/blue] [bold]{span.name}[/bold], span {opentelemetry.trace.format_span_id(span.context.span_id)}"
186189
)

exporter/opentelemetry-exporter-richconsole/test-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pluggy==1.5.0
99
py-cpuinfo==9.0.0
1010
Pygments==2.17.2
1111
pytest==7.4.4
12+
pytest-timeout==2.3.1
1213
rich==13.7.1
1314
tomli==2.0.1
1415
typing_extensions==4.12.2

exporter/opentelemetry-exporter-richconsole/tests/test_rich_exporter.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,15 @@ def test_multiple_traces(tracer_provider):
9696
parent_2.name in child.label
9797
for child in trees[traceid_1].children[0].children
9898
)
99+
100+
101+
@pytest.mark.timeout(30)
102+
def test_no_deadlock(tracer_provider):
103+
# non-regression test for https://github.com/open-telemetry/opentelemetry-python-contrib/issues/3254
104+
105+
tracer = tracer_provider.get_tracer(__name__)
106+
with tracer.start_as_current_span("parent"):
107+
with tracer.start_as_current_span("child") as child:
108+
pass
109+
110+
RichConsoleSpanExporter.spans_to_tree((child,))

instrumentation-genai/opentelemetry-instrumentation-google-genai/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
- Minor change to check LRU cache in Completion Hook before acquiring semaphore/thread ([#3907](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3907)).
11+
1012
## Version 0.4b0 (2025-10-16)
1113

1214
- Implement the new semantic convention changes made in https://github.com/open-telemetry/semantic-conventions/pull/2179.

util/opentelemetry-util-genai/src/opentelemetry/util/genai/_upload/completion_hook.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ def done(future: Future[None]) -> None:
149149
path,
150150
contents_hashed_to_filename,
151151
), json_encodeable in upload_data.items():
152+
if contents_hashed_to_filename and path in self.lru_dict:
153+
self.lru_dict.move_to_end(path)
154+
continue
152155
# could not acquire, drop data
153156
if not self._semaphore.acquire(blocking=False): # pylint: disable=consider-using-with
154157
_logger.warning(

0 commit comments

Comments
 (0)