Skip to content

Commit 6ca7d7d

Browse files
committed
Create per-extension tracers if there's an extension available
1 parent c0bc2c9 commit 6ca7d7d

File tree

4 files changed

+47
-12
lines changed

4 files changed

+47
-12
lines changed
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
boto3~=1.35.99
22

3-
opentelemetry-sdk~=1.29.0
4-
opentelemetry-exporter-otlp-proto-grpc~=1.29.0
5-
opentelemetry-distro~=0.50b0
6-
opentelemetry-instrumentation-botocore~=0.50b0
3+
opentelemetry-sdk~=1.30.0
4+
opentelemetry-exporter-otlp-proto-grpc~=1.30.0
5+
opentelemetry-distro~=0.51b0
6+
opentelemetry-instrumentation-botocore~=0.51b0

instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,13 @@ def response_hook(span, service_name, operation_name, result):
8686
from botocore.exceptions import ClientError
8787
from wrapt import wrap_function_wrapper
8888

89-
from opentelemetry.instrumentation.botocore.extensions import _find_extension
89+
from opentelemetry.instrumentation.botocore.extensions import (
90+
_find_extension,
91+
_has_extension,
92+
)
9093
from opentelemetry.instrumentation.botocore.extensions.types import (
9194
_AwsSdkCallContext,
95+
_AwsSdkExtension,
9296
)
9397
from opentelemetry.instrumentation.botocore.package import _instruments
9498
from opentelemetry.instrumentation.botocore.version import __version__
@@ -123,12 +127,9 @@ def instrumentation_dependencies(self) -> Collection[str]:
123127

124128
def _instrument(self, **kwargs):
125129
# pylint: disable=attribute-defined-outside-init
126-
self._tracer = get_tracer(
127-
__name__,
128-
__version__,
129-
kwargs.get("tracer_provider"),
130-
schema_url="https://opentelemetry.io/schemas/1.11.0",
131-
)
130+
131+
# tracers are lazy initialized per-extension in _get_tracer
132+
self._tracers = {}
132133

133134
self.request_hook = kwargs.get("request_hook")
134135
self.response_hook = kwargs.get("response_hook")
@@ -137,6 +138,8 @@ def _instrument(self, **kwargs):
137138
if propagator is not None:
138139
self.propagator = propagator
139140

141+
self.tracer_provider = kwargs.get("tracer_provider")
142+
140143
wrap_function_wrapper(
141144
"botocore.client",
142145
"BaseClient._make_api_call",
@@ -149,6 +152,29 @@ def _instrument(self, **kwargs):
149152
self._patched_endpoint_prepare_request,
150153
)
151154

155+
def _get_tracer(self, extension: _AwsSdkExtension):
156+
"""This is a multiplexer in order to have a tracer per extension"""
157+
158+
has_extension = _has_extension(extension._call_context)
159+
instrumentation_name = (
160+
f"botocore.{extension._call_context.service}"
161+
if has_extension
162+
else __name__
163+
)
164+
165+
tracer = self._tracers.get(instrumentation_name)
166+
if tracer:
167+
return tracer
168+
169+
schema_version = extension.tracer_schema_version()
170+
self._tracers[instrumentation_name] = get_tracer(
171+
instrumentation_name,
172+
__version__,
173+
self.tracer_provider,
174+
schema_url=f"https://opentelemetry.io/schemas/{schema_version}",
175+
)
176+
return self._tracers[instrumentation_name]
177+
152178
def _uninstrument(self, **kwargs):
153179
unwrap(BaseClient, "_make_api_call")
154180
unwrap(Endpoint, "prepare_request")
@@ -190,7 +216,8 @@ def _patched_api_call(self, original_func, instance, args, kwargs):
190216
_safe_invoke(extension.extract_attributes, attributes)
191217
end_span_on_exit = extension.should_end_span_on_exit()
192218

193-
with self._tracer.start_as_current_span(
219+
tracer = self._get_tracer(extension)
220+
with tracer.start_as_current_span(
194221
call_context.span_name,
195222
kind=call_context.span_kind,
196223
attributes=attributes,

instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ def loader():
4040
}
4141

4242

43+
def _has_extension(call_context: _AwsSdkCallContext) -> bool:
44+
return call_context.service in _KNOWN_EXTENSIONS
45+
46+
4347
def _find_extension(call_context: _AwsSdkCallContext) -> _AwsSdkExtension:
4448
try:
4549
loader = _KNOWN_EXTENSIONS.get(call_context.service)

instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/types.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ class _AwsSdkExtension:
9393
def __init__(self, call_context: _AwsSdkCallContext):
9494
self._call_context = call_context
9595

96+
def tracer_schema_version(self) -> str:
97+
"""Returns the tracer OTel schema version the extension is following"""
98+
return "1.11.0"
99+
96100
def should_trace_service_call(self) -> bool: # pylint:disable=no-self-use
97101
"""Returns if the AWS SDK service call should be traced or not
98102

0 commit comments

Comments
 (0)