Skip to content

Commit a8fe7bd

Browse files
bendruckerxrmx
authored andcommitted
botocore: document threading instrumentation for S3 multipart operations (open-telemetry#3999)
* botocore: document threading instrumentation for S3 multipart operations Document that users need to enable ThreadingInstrumentor alongside BotocoreInstrumentor for proper trace context propagation with S3 upload_file and download_file methods. * botocore: move thread context docs to module docstring only README.rst is not built into the documentation, so keep the threading context propagation docs only in __init__.py where autodoc will pick them up. * Update __init__.py * Update __init__.py --------- Co-authored-by: Riccardo Magliocchetti <riccardo.magliocchetti@gmail.com>
1 parent 61641aa commit a8fe7bd

File tree

7 files changed

+576
-6
lines changed

7 files changed

+576
-6
lines changed

instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/generate_content.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import os
2222
import time
2323
from typing import Any, AsyncIterator, Awaitable, Iterator, Optional, Union
24+
import collections.abc
2425

2526
from google.genai.models import AsyncModels, Models
2627
from google.genai.models import t as transformers
@@ -44,6 +45,7 @@
4445
_OpenTelemetryStabilitySignalType,
4546
_StabilityMode,
4647
)
48+
from opentelemetry.instrumentation.utils import is_instrumentation_enabled
4749
from opentelemetry.semconv._incubating.attributes import (
4850
code_attributes,
4951
gen_ai_attributes,
@@ -708,6 +710,11 @@ def instrumented_generate_content(
708710
config: Optional[GenerateContentConfigOrDict] = None,
709711
**kwargs: Any,
710712
) -> GenerateContentResponse:
713+
if not is_instrumentation_enabled():
714+
return wrapped_func(
715+
self, model=model, contents=contents, config=config, **kwargs
716+
)
717+
711718
candidates = []
712719
helper = _GenerateContentInstrumentationHelper(
713720
self,
@@ -783,6 +790,11 @@ def instrumented_generate_content_stream(
783790
config: Optional[GenerateContentConfigOrDict] = None,
784791
**kwargs: Any,
785792
) -> Iterator[GenerateContentResponse]:
793+
if not is_instrumentation_enabled():
794+
for resp in wrapped_func(self, model=model, contents=contents, config=config, **kwargs):
795+
yield resp
796+
return
797+
786798
candidates: list[Candidate] = []
787799
helper = _GenerateContentInstrumentationHelper(
788800
self,
@@ -858,6 +870,10 @@ async def instrumented_generate_content(
858870
config: Optional[GenerateContentConfigOrDict] = None,
859871
**kwargs: Any,
860872
) -> GenerateContentResponse:
873+
if not is_instrumentation_enabled():
874+
return await wrapped_func(
875+
self, model=model, contents=contents, config=config, **kwargs
876+
)
861877
helper = _GenerateContentInstrumentationHelper(
862878
self,
863879
otel_wrapper,
@@ -933,6 +949,9 @@ async def instrumented_generate_content_stream(
933949
config: Optional[GenerateContentConfigOrDict] = None,
934950
**kwargs: Any,
935951
) -> Awaitable[AsyncIterator[GenerateContentResponse]]: # type: ignore
952+
if not is_instrumentation_enabled():
953+
return await wrapped_func(self, model=model, contents=contents, config=config, **kwargs)
954+
936955
helper = _GenerateContentInstrumentationHelper(
937956
self,
938957
otel_wrapper,

instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/tool_call_wrapper.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
_OpenTelemetryStabilitySignalType,
3030
_StabilityMode,
3131
)
32+
from opentelemetry.instrumentation.utils import is_instrumentation_enabled
3233
from opentelemetry.semconv._incubating.attributes import (
3334
code_attributes,
3435
)
@@ -168,6 +169,9 @@ def _wrap_sync_tool_function(
168169
):
169170
@functools.wraps(tool_function)
170171
def wrapped_function(*args, **kwargs):
172+
if not is_instrumentation_enabled():
173+
return tool_function(*args, **kwargs)
174+
171175
span_name = _create_function_span_name(tool_function)
172176
attributes = _create_function_span_attributes(
173177
tool_function, args, kwargs, extra_span_attributes
@@ -193,6 +197,9 @@ def _wrap_async_tool_function(
193197
):
194198
@functools.wraps(tool_function)
195199
async def wrapped_function(*args, **kwargs):
200+
if not is_instrumentation_enabled():
201+
return await tool_function(*args, **kwargs)
202+
196203
span_name = _create_function_span_name(tool_function)
197204
attributes = _create_function_span_attributes(
198205
tool_function, args, kwargs, extra_span_attributes

instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/generate_content/nonstreaming_base.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from google.genai.types import GenerateContentConfig
2121
from pydantic import BaseModel, Field
2222

23+
from opentelemetry.instrumentation import utils
2324
from opentelemetry.instrumentation._semconv import (
2425
_OpenTelemetrySemanticConventionStability,
2526
_OpenTelemetryStabilitySignalType,
@@ -448,3 +449,14 @@ def test_records_metrics_data(self):
448449
self.otel.assert_has_metrics_data_named(
449450
"gen_ai.client.operation.duration"
450451
)
452+
453+
def test_suppress_instrumentation(self):
454+
self.configure_valid_response(text="Yep, it works!")
455+
with utils.suppress_instrumentation():
456+
response = self.generate_content(
457+
model="gemini-2.0-flash", contents="Does this work?"
458+
)
459+
self.assertEqual(response.text, "Yep, it works!")
460+
self.otel.assert_does_not_have_span_named(
461+
"generate_content gemini-2.0-flash"
462+
)

0 commit comments

Comments
 (0)