From f1b46719320a83bcadd3b5dc1956e9ffc4aa589c Mon Sep 17 00:00:00 2001 From: Philip Meier Date: Mon, 27 Oct 2025 23:27:56 +0100 Subject: [PATCH] add option to suppress resource information with RichConsoleExporter --- CHANGELOG.md | 4 +++ .../exporter/richconsole/__init__.py | 18 +++++++------ .../tests/test_rich_exporter.py | 26 +++++++++++++++++++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 024990c91d..df6dcba5fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- `opentelemetry-instrumentation-richconsole`: Add support for suppressing resource information + ## Version 1.38.0/0.59b0 (2025-10-16) ### Fixed diff --git a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/__init__.py b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/__init__.py index 59415e2bd8..88041a8db4 100644 --- a/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/__init__.py +++ b/exporter/opentelemetry-exporter-richconsole/src/opentelemetry/exporter/richconsole/__init__.py @@ -76,12 +76,12 @@ def _ns_to_time(nanoseconds): return ts.strftime("%H:%M:%S.%f") -def _child_to_tree(child: Tree, span: ReadableSpan): +def _child_to_tree(child: Tree, span: ReadableSpan, *, suppress_resource: bool): child.add( Text.from_markup(f"[bold cyan]Kind :[/bold cyan] {span.kind.name}") ) _add_status(child, span) - _child_add_optional_attributes(child, span) + _child_add_optional_attributes(child, span, suppress_resource=suppress_resource) def _add_status(child: Tree, span: ReadableSpan): @@ -106,7 +106,7 @@ def _add_status(child: Tree, span: ReadableSpan): ) -def _child_add_optional_attributes(child: Tree, span: ReadableSpan): +def _child_add_optional_attributes(child: Tree, span: ReadableSpan, *, suppress_resource: bool): if span.events: events = child.add( label=Text.from_markup("[bold cyan]Events :[/bold cyan] ") @@ -133,7 +133,7 @@ def _child_add_optional_attributes(child: Tree, span: ReadableSpan): f"[bold cyan]{attribute} :[/bold cyan] {span.attributes[attribute]}" ) ) - if span.resource: + if span.resource and not suppress_resource: resources = child.add( label=Text.from_markup("[bold cyan]Resources :[/bold cyan] ") ) @@ -155,21 +155,23 @@ class RichConsoleSpanExporter(SpanExporter): def __init__( self, service_name: Optional[str] = None, + suppress_resource: bool = False, ): self.service_name = service_name + self.suppress_resource = suppress_resource self.console = Console() def export(self, spans: typing.Sequence[ReadableSpan]) -> SpanExportResult: if not spans: return SpanExportResult.SUCCESS - for tree in self.spans_to_tree(spans).values(): + for tree in self.spans_to_tree(spans, suppress_resource=self.suppress_resource).values(): self.console.print(tree) return SpanExportResult.SUCCESS @staticmethod - def spans_to_tree(spans: typing.Sequence[ReadableSpan]) -> Dict[str, Tree]: + def spans_to_tree(spans: typing.Sequence[ReadableSpan], *, suppress_resource: bool = False) -> Dict[str, Tree]: trees = {} parents = {} spans = list(spans) @@ -186,7 +188,7 @@ def spans_to_tree(spans: typing.Sequence[ReadableSpan]) -> Dict[str, Tree]: ) ) parents[span.context.span_id] = child - _child_to_tree(child, span) + _child_to_tree(child, span, suppress_resource=suppress_resource) spans.remove(span) elif span.parent and span.parent.span_id in parents: child = parents[span.parent.span_id].add( @@ -195,6 +197,6 @@ def spans_to_tree(spans: typing.Sequence[ReadableSpan]) -> Dict[str, Tree]: ) ) parents[span.context.span_id] = child - _child_to_tree(child, span) + _child_to_tree(child, span, suppress_resource=suppress_resource) spans.remove(span) return trees diff --git a/exporter/opentelemetry-exporter-richconsole/tests/test_rich_exporter.py b/exporter/opentelemetry-exporter-richconsole/tests/test_rich_exporter.py index f4dcd49fe9..1a1056b032 100644 --- a/exporter/opentelemetry-exporter-richconsole/tests/test_rich_exporter.py +++ b/exporter/opentelemetry-exporter-richconsole/tests/test_rich_exporter.py @@ -13,12 +13,14 @@ # limitations under the License. import pytest +from rich.text import Text from rich.tree import Tree import opentelemetry.trace from opentelemetry.exporter.richconsole import RichConsoleSpanExporter from opentelemetry.sdk import trace from opentelemetry.sdk.trace.export import BatchSpanProcessor +from opentelemetry.sdk.resources import Resource @pytest.fixture(name="span_processor") @@ -96,3 +98,27 @@ def test_multiple_traces(tracer_provider): parent_2.name in child.label for child in trees[traceid_1].children[0].children ) + +def test_suppress_resource(span_processor): + attributes = {"resource.key": "resource.value"} + resource = Resource(attributes) + tracer_provider = trace.TracerProvider(resource=resource) + tracer_provider.add_span_processor(span_processor) + tracer = tracer_provider.get_tracer(__name__) + + with tracer.start_as_current_span("parent") as parent: + with tracer.start_as_current_span("child") as child: + pass + + trees = RichConsoleSpanExporter.spans_to_tree((parent, child), suppress_resource=True) + assert len(trees) == 1 + + nodes = [next(t for t in trees.values())] + for node in nodes: + label = node.label + if isinstance(label, Text): + label = label.plain + + assert "resource" not in label.lower() + + nodes.extend(node.children)