ddtrace 3.11.0rc1__cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl → 3.11.0rc2__cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ddtrace/_logger.py +5 -6
- ddtrace/_trace/product.py +1 -1
- ddtrace/_trace/trace_handlers.py +3 -1
- ddtrace/_version.py +2 -2
- ddtrace/appsec/_asm_request_context.py +3 -1
- ddtrace/appsec/_iast/_listener.py +12 -2
- ddtrace/contrib/integration_registry/registry.yaml +10 -0
- ddtrace/contrib/internal/avro/__init__.py +17 -0
- ddtrace/contrib/internal/azure_functions/patch.py +23 -12
- ddtrace/contrib/internal/azure_functions/utils.py +14 -0
- ddtrace/contrib/internal/botocore/__init__.py +153 -0
- ddtrace/contrib/{_freezegun.py → internal/freezegun/__init__.py} +1 -1
- ddtrace/contrib/internal/langchain/patch.py +11 -443
- ddtrace/contrib/internal/langchain/utils.py +0 -26
- ddtrace/contrib/internal/logbook/patch.py +1 -2
- ddtrace/contrib/internal/logging/patch.py +4 -7
- ddtrace/contrib/internal/loguru/patch.py +1 -3
- ddtrace/contrib/internal/protobuf/__init__.py +17 -0
- ddtrace/contrib/internal/pytest/__init__.py +62 -0
- ddtrace/contrib/internal/pytest/_plugin_v2.py +12 -3
- ddtrace/contrib/internal/pytest_bdd/__init__.py +23 -0
- ddtrace/contrib/internal/pytest_benchmark/__init__.py +3 -0
- ddtrace/contrib/internal/structlog/patch.py +2 -4
- ddtrace/contrib/internal/unittest/__init__.py +36 -0
- ddtrace/internal/_encoding.cpython-312-i386-linux-gnu.so +0 -0
- ddtrace/internal/_encoding.pyi +1 -1
- ddtrace/internal/ci_visibility/encoder.py +18 -12
- ddtrace/internal/ci_visibility/utils.py +4 -4
- ddtrace/internal/core/__init__.py +5 -2
- ddtrace/internal/test_visibility/coverage_lines.py +4 -4
- ddtrace/internal/writer/writer.py +24 -11
- ddtrace/llmobs/_constants.py +2 -0
- ddtrace/llmobs/_experiment.py +69 -10
- ddtrace/llmobs/_integrations/bedrock.py +4 -0
- ddtrace/llmobs/_integrations/bedrock_agents.py +5 -1
- ddtrace/llmobs/_integrations/langchain.py +29 -20
- ddtrace/llmobs/_llmobs.py +78 -13
- ddtrace/llmobs/_telemetry.py +20 -5
- ddtrace/llmobs/_utils.py +6 -0
- ddtrace/settings/_config.py +1 -2
- ddtrace/settings/profiling.py +0 -9
- {ddtrace-3.11.0rc1.dist-info → ddtrace-3.11.0rc2.dist-info}/METADATA +1 -1
- {ddtrace-3.11.0rc1.dist-info → ddtrace-3.11.0rc2.dist-info}/RECORD +126 -133
- ddtrace/contrib/_avro.py +0 -17
- ddtrace/contrib/_botocore.py +0 -153
- ddtrace/contrib/_protobuf.py +0 -17
- ddtrace/contrib/_pytest.py +0 -62
- ddtrace/contrib/_pytest_bdd.py +0 -23
- ddtrace/contrib/_pytest_benchmark.py +0 -3
- ddtrace/contrib/_unittest.py +0 -36
- /ddtrace/contrib/{_aiobotocore.py → internal/aiobotocore/__init__.py} +0 -0
- /ddtrace/contrib/{_aiohttp_jinja2.py → internal/aiohttp_jinja2/__init__.py} +0 -0
- /ddtrace/contrib/{_aiomysql.py → internal/aiomysql/__init__.py} +0 -0
- /ddtrace/contrib/{_aiopg.py → internal/aiopg/__init__.py} +0 -0
- /ddtrace/contrib/{_aioredis.py → internal/aioredis/__init__.py} +0 -0
- /ddtrace/contrib/{_algoliasearch.py → internal/algoliasearch/__init__.py} +0 -0
- /ddtrace/contrib/{_anthropic.py → internal/anthropic/__init__.py} +0 -0
- /ddtrace/contrib/{_aredis.py → internal/aredis/__init__.py} +0 -0
- /ddtrace/contrib/{_asyncio.py → internal/asyncio/__init__.py} +0 -0
- /ddtrace/contrib/{_asyncpg.py → internal/asyncpg/__init__.py} +0 -0
- /ddtrace/contrib/{_aws_lambda.py → internal/aws_lambda/__init__.py} +0 -0
- /ddtrace/contrib/{_azure_functions.py → internal/azure_functions/__init__.py} +0 -0
- /ddtrace/contrib/{_azure_servicebus.py → internal/azure_servicebus/__init__.py} +0 -0
- /ddtrace/contrib/{_boto.py → internal/boto/__init__.py} +0 -0
- /ddtrace/contrib/{_cassandra.py → internal/cassandra/__init__.py} +0 -0
- /ddtrace/contrib/{_consul.py → internal/consul/__init__.py} +0 -0
- /ddtrace/contrib/{_coverage.py → internal/coverage/__init__.py} +0 -0
- /ddtrace/contrib/{_crewai.py → internal/crewai/__init__.py} +0 -0
- /ddtrace/contrib/{_django.py → internal/django/__init__.py} +0 -0
- /ddtrace/contrib/{_dogpile_cache.py → internal/dogpile_cache/__init__.py} +0 -0
- /ddtrace/contrib/{_dramatiq.py → internal/dramatiq/__init__.py} +0 -0
- /ddtrace/contrib/{_elasticsearch.py → internal/elasticsearch/__init__.py} +0 -0
- /ddtrace/contrib/{_fastapi.py → internal/fastapi/__init__.py} +0 -0
- /ddtrace/contrib/{_flask.py → internal/flask/__init__.py} +0 -0
- /ddtrace/contrib/{_futures.py → internal/futures/__init__.py} +0 -0
- /ddtrace/contrib/{_gevent.py → internal/gevent/__init__.py} +0 -0
- /ddtrace/contrib/{_google_genai.py → internal/google_genai/__init__.py} +0 -0
- /ddtrace/contrib/{_google_generativeai.py → internal/google_generativeai/__init__.py} +0 -0
- /ddtrace/contrib/{_graphql.py → internal/graphql/__init__.py} +0 -0
- /ddtrace/contrib/{_grpc.py → internal/grpc/__init__.py} +0 -0
- /ddtrace/contrib/{_gunicorn.py → internal/gunicorn/__init__.py} +0 -0
- /ddtrace/contrib/{_httplib.py → internal/httplib/__init__.py} +0 -0
- /ddtrace/contrib/{_httpx.py → internal/httpx/__init__.py} +0 -0
- /ddtrace/contrib/{_jinja2.py → internal/jinja2/__init__.py} +0 -0
- /ddtrace/contrib/{_kafka.py → internal/kafka/__init__.py} +0 -0
- /ddtrace/contrib/{_kombu.py → internal/kombu/__init__.py} +0 -0
- /ddtrace/contrib/{_langchain.py → internal/langchain/__init__.py} +0 -0
- /ddtrace/contrib/{_langgraph.py → internal/langgraph/__init__.py} +0 -0
- /ddtrace/contrib/{_litellm.py → internal/litellm/__init__.py} +0 -0
- /ddtrace/contrib/{_logbook.py → internal/logbook/__init__.py} +0 -0
- /ddtrace/contrib/{_logging.py → internal/logging/__init__.py} +0 -0
- /ddtrace/contrib/{_loguru.py → internal/loguru/__init__.py} +0 -0
- /ddtrace/contrib/{_mako.py → internal/mako/__init__.py} +0 -0
- /ddtrace/contrib/{_mariadb.py → internal/mariadb/__init__.py} +0 -0
- /ddtrace/contrib/{_mcp.py → internal/mcp/__init__.py} +0 -0
- /ddtrace/contrib/{_molten.py → internal/molten/__init__.py} +0 -0
- /ddtrace/contrib/{_mongoengine.py → internal/mongoengine/__init__.py} +0 -0
- /ddtrace/contrib/{_mysql.py → internal/mysql/__init__.py} +0 -0
- /ddtrace/contrib/{_mysqldb.py → internal/mysqldb/__init__.py} +0 -0
- /ddtrace/contrib/{_openai.py → internal/openai/__init__.py} +0 -0
- /ddtrace/contrib/{_openai_agents.py → internal/openai_agents/__init__.py} +0 -0
- /ddtrace/contrib/{_psycopg.py → internal/psycopg/__init__.py} +0 -0
- /ddtrace/contrib/{_pydantic_ai.py → internal/pydantic_ai/__init__.py} +0 -0
- /ddtrace/contrib/{_pymemcache.py → internal/pymemcache/__init__.py} +0 -0
- /ddtrace/contrib/{_pymongo.py → internal/pymongo/__init__.py} +0 -0
- /ddtrace/contrib/{_pymysql.py → internal/pymysql/__init__.py} +0 -0
- /ddtrace/contrib/{_pynamodb.py → internal/pynamodb/__init__.py} +0 -0
- /ddtrace/contrib/{_pyodbc.py → internal/pyodbc/__init__.py} +0 -0
- /ddtrace/contrib/{_redis.py → internal/redis/__init__.py} +0 -0
- /ddtrace/contrib/{_rediscluster.py → internal/rediscluster/__init__.py} +0 -0
- /ddtrace/contrib/{_rq.py → internal/rq/__init__.py} +0 -0
- /ddtrace/contrib/{_sanic.py → internal/sanic/__init__.py} +0 -0
- /ddtrace/contrib/{_selenium.py → internal/selenium/__init__.py} +0 -0
- /ddtrace/contrib/{_snowflake.py → internal/snowflake/__init__.py} +0 -0
- /ddtrace/contrib/{_sqlite3.py → internal/sqlite3/__init__.py} +0 -0
- /ddtrace/contrib/{_starlette.py → internal/starlette/__init__.py} +0 -0
- /ddtrace/contrib/{_structlog.py → internal/structlog/__init__.py} +0 -0
- /ddtrace/contrib/{_subprocess.py → internal/subprocess/__init__.py} +0 -0
- /ddtrace/contrib/{_urllib.py → internal/urllib/__init__.py} +0 -0
- /ddtrace/contrib/{_urllib3.py → internal/urllib3/__init__.py} +0 -0
- /ddtrace/contrib/{_vertexai.py → internal/vertexai/__init__.py} +0 -0
- /ddtrace/contrib/{_vertica.py → internal/vertica/__init__.py} +0 -0
- /ddtrace/contrib/{_webbrowser.py → internal/webbrowser/__init__.py} +0 -0
- /ddtrace/contrib/{_yaaredis.py → internal/yaaredis/__init__.py} +0 -0
- {ddtrace-3.11.0rc1.dist-info → ddtrace-3.11.0rc2.dist-info}/WHEEL +0 -0
- {ddtrace-3.11.0rc1.dist-info → ddtrace-3.11.0rc2.dist-info}/entry_points.txt +0 -0
- {ddtrace-3.11.0rc1.dist-info → ddtrace-3.11.0rc2.dist-info}/licenses/LICENSE +0 -0
- {ddtrace-3.11.0rc1.dist-info → ddtrace-3.11.0rc2.dist-info}/licenses/LICENSE.Apache +0 -0
- {ddtrace-3.11.0rc1.dist-info → ddtrace-3.11.0rc2.dist-info}/licenses/LICENSE.BSD3 +0 -0
- {ddtrace-3.11.0rc1.dist-info → ddtrace-3.11.0rc2.dist-info}/licenses/NOTICE +0 -0
- {ddtrace-3.11.0rc1.dist-info → ddtrace-3.11.0rc2.dist-info}/top_level.txt +0 -0
ddtrace/_logger.py
CHANGED
@@ -20,6 +20,7 @@ class LogInjectionState(object):
|
|
20
20
|
# Log injection is enabled, but not yet configured
|
21
21
|
ENABLED = "true"
|
22
22
|
# Log injection is enabled and configured for structured logging
|
23
|
+
# This value is deprecated, but kept for backwards compatibility
|
23
24
|
STRUCTURED = "structured"
|
24
25
|
|
25
26
|
|
@@ -108,17 +109,15 @@ def set_log_formatting():
|
|
108
109
|
handler.setFormatter(logging.Formatter(DD_LOG_FORMAT))
|
109
110
|
|
110
111
|
|
111
|
-
def get_log_injection_state(raw_config: Optional[str]) ->
|
112
|
+
def get_log_injection_state(raw_config: Optional[str]) -> bool:
|
112
113
|
"""Returns the current log injection state."""
|
113
114
|
if raw_config:
|
114
115
|
normalized = raw_config.lower().strip()
|
115
|
-
if normalized == LogInjectionState.STRUCTURED:
|
116
|
-
return
|
117
|
-
elif normalized in ("true", "1"):
|
118
|
-
return LogInjectionState.ENABLED
|
116
|
+
if normalized == LogInjectionState.STRUCTURED or normalized in ("true", "1"):
|
117
|
+
return True
|
119
118
|
elif normalized not in ("false", "0"):
|
120
119
|
logging.warning(
|
121
120
|
"Invalid log injection state '%s'. Expected 'true', 'false', or 'structured'. Defaulting to 'false'.",
|
122
121
|
normalized,
|
123
122
|
)
|
124
|
-
return
|
123
|
+
return False
|
ddtrace/_trace/product.py
CHANGED
@@ -215,7 +215,7 @@ def apm_tracing_rc(lib_config, dd_config):
|
|
215
215
|
new_rc_configs["_trace_sampling_rules"] = trace_sampling_rules
|
216
216
|
|
217
217
|
if "log_injection_enabled" in lib_config:
|
218
|
-
new_rc_configs["_logs_injection"] =
|
218
|
+
new_rc_configs["_logs_injection"] = lib_config["log_injection_enabled"]
|
219
219
|
|
220
220
|
if "tracing_tags" in lib_config:
|
221
221
|
tags = lib_config["tracing_tags"]
|
ddtrace/_trace/trace_handlers.py
CHANGED
@@ -872,10 +872,12 @@ def _on_azure_functions_service_bus_trigger_span_modifier(
|
|
872
872
|
span = ctx.span
|
873
873
|
_set_azure_function_tags(span, azure_functions_config, function_name, trigger, span_kind)
|
874
874
|
span.set_tag_str(MESSAGING_DESTINATION_NAME, entity_name)
|
875
|
-
span.set_tag_str(MESSAGING_MESSAGE_ID, message_id)
|
876
875
|
span.set_tag_str(MESSAGING_OPERATION, "receive")
|
877
876
|
span.set_tag_str(MESSAGING_SYSTEM, azure_servicebusx.SERVICE)
|
878
877
|
|
878
|
+
if message_id is not None:
|
879
|
+
span.set_tag_str(MESSAGING_MESSAGE_ID, message_id)
|
880
|
+
|
879
881
|
|
880
882
|
def _on_azure_servicebus_send_message_modifier(ctx, azure_servicebus_config, entity_name, fully_qualified_namespace):
|
881
883
|
span = ctx.span
|
ddtrace/_version.py
CHANGED
@@ -17,5 +17,5 @@ __version__: str
|
|
17
17
|
__version_tuple__: VERSION_TUPLE
|
18
18
|
version_tuple: VERSION_TUPLE
|
19
19
|
|
20
|
-
__version__ = version = '3.11.
|
21
|
-
__version_tuple__ = version_tuple = (3, 11, 0, '
|
20
|
+
__version__ = version = '3.11.0rc2'
|
21
|
+
__version_tuple__ = version_tuple = (3, 11, 0, 'rc2')
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import functools
|
2
2
|
import json
|
3
3
|
import re
|
4
|
+
from types import TracebackType
|
4
5
|
from typing import Any
|
5
6
|
from typing import Callable
|
6
7
|
from typing import Dict
|
@@ -8,6 +9,7 @@ from typing import List
|
|
8
9
|
from typing import Literal
|
9
10
|
from typing import Optional
|
10
11
|
from typing import Set
|
12
|
+
from typing import Tuple
|
11
13
|
from typing import Union
|
12
14
|
from urllib import parse
|
13
15
|
|
@@ -534,7 +536,7 @@ def end_context(span: Span):
|
|
534
536
|
finalize_asm_env(env)
|
535
537
|
|
536
538
|
|
537
|
-
def _on_context_ended(ctx):
|
539
|
+
def _on_context_ended(ctx, _exc_info: Tuple[Optional[type], Optional[BaseException], Optional[TracebackType]]):
|
538
540
|
env = ctx.get_local_item(_ASM_CONTEXT)
|
539
541
|
if env is not None:
|
540
542
|
finalize_asm_env(env)
|
@@ -1,3 +1,7 @@
|
|
1
|
+
from types import TracebackType
|
2
|
+
from typing import Optional
|
3
|
+
from typing import Tuple
|
4
|
+
|
1
5
|
from ddtrace.appsec._iast._handlers import _iast_on_wrapped_view
|
2
6
|
from ddtrace.appsec._iast._handlers import _on_asgi_finalize_response
|
3
7
|
from ddtrace.appsec._iast._handlers import _on_django_finalize_response_pre
|
@@ -19,6 +23,12 @@ from ddtrace.internal import core
|
|
19
23
|
|
20
24
|
|
21
25
|
def iast_listen():
|
26
|
+
def _iast_context_end(
|
27
|
+
ctx: core.ExecutionContext,
|
28
|
+
_exc_info: Tuple[Optional[type], Optional[BaseException], Optional[TracebackType]],
|
29
|
+
):
|
30
|
+
_iast_end_request(ctx)
|
31
|
+
|
22
32
|
core.on("grpc.client.response.message", _on_grpc_response)
|
23
33
|
core.on("grpc.server.response.message", _on_grpc_server_response)
|
24
34
|
|
@@ -37,8 +47,8 @@ def iast_listen():
|
|
37
47
|
core.on("flask.finalize_request.post", _on_flask_finalize_request_post)
|
38
48
|
core.on("werkzeug.render_debugger_html", _on_werkzeug_render_debugger_html)
|
39
49
|
|
40
|
-
core.on("context.ended.wsgi.__call__",
|
41
|
-
core.on("context.ended.asgi.__call__",
|
50
|
+
core.on("context.ended.wsgi.__call__", _iast_context_end)
|
51
|
+
core.on("context.ended.asgi.__call__", _iast_context_end)
|
42
52
|
|
43
53
|
# Sink points
|
44
54
|
core.on("db_query_check", _on_report_sqli)
|
@@ -393,6 +393,16 @@ integrations:
|
|
393
393
|
min: 20.12.1
|
394
394
|
max: 24.11.1
|
395
395
|
|
396
|
+
- integration_name: gunicorn
|
397
|
+
is_external_package: true
|
398
|
+
is_tested: true
|
399
|
+
dependency_names:
|
400
|
+
- gunicorn
|
401
|
+
tested_versions_by_dependency:
|
402
|
+
gunicorn:
|
403
|
+
min: 20.0.4
|
404
|
+
max: 23.0.0
|
405
|
+
|
396
406
|
- integration_name: google_genai
|
397
407
|
is_external_package: true
|
398
408
|
is_tested: true
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"""
|
2
|
+
The Avro integration will trace all Avro read / write calls made with the ``avro``
|
3
|
+
library. This integration is enabled by default.
|
4
|
+
|
5
|
+
Enabling
|
6
|
+
~~~~~~~~
|
7
|
+
|
8
|
+
The avro integration is enabled by default. Use
|
9
|
+
:func:`patch()<ddtrace.patch>` to enable the integration::
|
10
|
+
|
11
|
+
from ddtrace import patch
|
12
|
+
patch(avro=True)
|
13
|
+
|
14
|
+
Configuration
|
15
|
+
~~~~~~~~~~~~~
|
16
|
+
|
17
|
+
"""
|
@@ -12,6 +12,7 @@ from ddtrace.internal.utils.formats import asbool
|
|
12
12
|
from ddtrace.trace import Pin
|
13
13
|
|
14
14
|
from .utils import create_context
|
15
|
+
from .utils import message_list_has_single_context
|
15
16
|
from .utils import wrap_function_with_tracing
|
16
17
|
|
17
18
|
|
@@ -97,24 +98,34 @@ def _wrap_service_bus_trigger(pin, func, function_name, trigger_arg_name, trigge
|
|
97
98
|
def context_factory(kwargs):
|
98
99
|
resource_name = f"{trigger_type} {function_name}"
|
99
100
|
msg = kwargs.get(trigger_arg_name)
|
100
|
-
|
101
|
-
|
102
|
-
)
|
101
|
+
|
102
|
+
# Reparent trace if single message or list of messages all with same context
|
103
|
+
if isinstance(msg, azure_functions.ServiceBusMessage):
|
104
|
+
application_properties = msg.application_properties
|
105
|
+
elif (
|
106
|
+
isinstance(msg, list)
|
107
|
+
and msg
|
108
|
+
and isinstance(msg[0], azure_functions.ServiceBusMessage)
|
109
|
+
and message_list_has_single_context(msg)
|
110
|
+
):
|
111
|
+
application_properties = msg[0].application_properties
|
112
|
+
else:
|
113
|
+
application_properties = None
|
114
|
+
|
115
|
+
return create_context("azure.functions.patched_service_bus", pin, resource_name, headers=application_properties)
|
103
116
|
|
104
117
|
def pre_dispatch(ctx, kwargs):
|
105
118
|
msg = kwargs.get(trigger_arg_name)
|
119
|
+
|
120
|
+
if isinstance(msg, azure_functions.ServiceBusMessage):
|
121
|
+
message_id = msg.message_id
|
122
|
+
else:
|
123
|
+
message_id = None
|
124
|
+
|
106
125
|
entity_name = trigger_details.get("topicName") or trigger_details.get("queueName")
|
107
126
|
return (
|
108
127
|
"azure.functions.service_bus_trigger_modifier",
|
109
|
-
(
|
110
|
-
ctx,
|
111
|
-
config.azure_functions,
|
112
|
-
function_name,
|
113
|
-
trigger_type,
|
114
|
-
SpanKind.CONSUMER,
|
115
|
-
entity_name,
|
116
|
-
msg.message_id,
|
117
|
-
),
|
128
|
+
(ctx, config.azure_functions, function_name, trigger_type, SpanKind.CONSUMER, entity_name, message_id),
|
118
129
|
)
|
119
130
|
|
120
131
|
return wrap_function_with_tracing(func, context_factory, pre_dispatch=pre_dispatch)
|
@@ -1,11 +1,15 @@
|
|
1
1
|
import functools
|
2
2
|
import inspect
|
3
|
+
from typing import List
|
4
|
+
|
5
|
+
import azure.functions as azure_functions
|
3
6
|
|
4
7
|
from ddtrace import config
|
5
8
|
from ddtrace.contrib.internal.trace_utils import int_service
|
6
9
|
from ddtrace.ext import SpanTypes
|
7
10
|
from ddtrace.internal import core
|
8
11
|
from ddtrace.internal.schema import schematize_cloud_faas_operation
|
12
|
+
from ddtrace.propagation.http import HTTPPropagator
|
9
13
|
|
10
14
|
|
11
15
|
def create_context(context_name, pin, resource=None, headers=None):
|
@@ -59,3 +63,13 @@ def wrap_function_with_tracing(func, context_factory, pre_dispatch=None, post_di
|
|
59
63
|
core.dispatch(*post_dispatch(ctx, res))
|
60
64
|
|
61
65
|
return wrapper
|
66
|
+
|
67
|
+
|
68
|
+
def message_list_has_single_context(msg_list: List[azure_functions.ServiceBusMessage]):
|
69
|
+
first_context = HTTPPropagator.extract(msg_list[0].application_properties)
|
70
|
+
for message in msg_list[1:]:
|
71
|
+
context = HTTPPropagator.extract(message.application_properties)
|
72
|
+
if first_context != context:
|
73
|
+
return False
|
74
|
+
|
75
|
+
return True
|
@@ -0,0 +1,153 @@
|
|
1
|
+
"""
|
2
|
+
The Botocore integration will trace all AWS calls made with the botocore
|
3
|
+
library. Libraries like Boto3 that use Botocore will also be patched.
|
4
|
+
|
5
|
+
Enabling
|
6
|
+
~~~~~~~~
|
7
|
+
|
8
|
+
The botocore integration is enabled automatically when using
|
9
|
+
:ref:`ddtrace-run<ddtracerun>` or :ref:`import ddtrace.auto<ddtraceauto>`.
|
10
|
+
|
11
|
+
Or use :func:`patch()<ddtrace.patch>` to manually enable the integration::
|
12
|
+
|
13
|
+
from ddtrace import patch
|
14
|
+
patch(botocore=True)
|
15
|
+
|
16
|
+
To patch only specific botocore modules, pass a list of the module names instead::
|
17
|
+
|
18
|
+
from ddtrace import patch
|
19
|
+
patch(botocore=['s3', 'sns'])
|
20
|
+
|
21
|
+
Configuration
|
22
|
+
~~~~~~~~~~~~~
|
23
|
+
|
24
|
+
.. py:data:: ddtrace.config.botocore['distributed_tracing']
|
25
|
+
|
26
|
+
Whether to inject distributed tracing data to requests in SQS, SNS, EventBridge, Kinesis Streams and Lambda.
|
27
|
+
|
28
|
+
Can also be enabled with the ``DD_BOTOCORE_DISTRIBUTED_TRACING`` environment variable.
|
29
|
+
|
30
|
+
Example::
|
31
|
+
|
32
|
+
from ddtrace import config
|
33
|
+
|
34
|
+
# Enable distributed tracing
|
35
|
+
config.botocore['distributed_tracing'] = True
|
36
|
+
|
37
|
+
|
38
|
+
Default: ``True``
|
39
|
+
|
40
|
+
|
41
|
+
.. py:data:: ddtrace.config.botocore['invoke_with_legacy_context']
|
42
|
+
|
43
|
+
This preserves legacy behavior when tracing directly invoked Python and Node Lambda
|
44
|
+
functions instrumented with datadog-lambda-python < v41 or datadog-lambda-js < v3.58.0.
|
45
|
+
|
46
|
+
Legacy support for older libraries is available with
|
47
|
+
``ddtrace.config.botocore.invoke_with_legacy_context = True`` or by setting the environment
|
48
|
+
variable ``DD_BOTOCORE_INVOKE_WITH_LEGACY_CONTEXT=true``.
|
49
|
+
|
50
|
+
|
51
|
+
Default: ``False``
|
52
|
+
|
53
|
+
|
54
|
+
.. py:data:: ddtrace.config.botocore['operations'][<operation>].error_statuses = "<error statuses>"
|
55
|
+
|
56
|
+
Definition of which HTTP status codes to consider for making a span as an error span.
|
57
|
+
|
58
|
+
By default response status codes of ``'500-599'`` are considered as errors for all endpoints.
|
59
|
+
|
60
|
+
Example marking 404, and 5xx as errors for ``s3.headobject`` API calls::
|
61
|
+
|
62
|
+
from ddtrace import config
|
63
|
+
|
64
|
+
config.botocore['operations']['s3.headobject'].error_statuses = '404,500-599'
|
65
|
+
|
66
|
+
|
67
|
+
See :ref:`HTTP - Custom Error Codes<http-custom-error>` documentation for more examples.
|
68
|
+
|
69
|
+
.. py:data:: ddtrace.config.botocore['tag_no_params']
|
70
|
+
|
71
|
+
This opts out of the default behavior of collecting a narrow set of API parameters as span tags.
|
72
|
+
|
73
|
+
To not collect any API parameters, ``ddtrace.config.botocore.tag_no_params = True`` or by setting the environment
|
74
|
+
variable ``DD_AWS_TAG_NO_PARAMS=true``.
|
75
|
+
|
76
|
+
|
77
|
+
Default: ``False``
|
78
|
+
|
79
|
+
|
80
|
+
.. py:data:: ddtrace.config.botocore['instrument_internals']
|
81
|
+
|
82
|
+
This opts into collecting spans for some internal functions, including ``parsers.ResponseParser.parse``.
|
83
|
+
|
84
|
+
Can also be enabled with the ``DD_BOTOCORE_INSTRUMENT_INTERNALS`` environment variable.
|
85
|
+
|
86
|
+
Default: ``False``
|
87
|
+
|
88
|
+
|
89
|
+
.. py:data:: ddtrace.config.botocore['span_prompt_completion_sample_rate']
|
90
|
+
|
91
|
+
Configure the sample rate for the collection of bedrock prompts and completions as span tags.
|
92
|
+
|
93
|
+
Alternatively, you can set this option with the ``DD_BEDROCK_SPAN_PROMPT_COMPLETION_SAMPLE_RATE`` environment
|
94
|
+
variable.
|
95
|
+
|
96
|
+
Default: ``1.0``
|
97
|
+
|
98
|
+
|
99
|
+
.. py:data:: (beta) ddtrace.config.botocore["span_char_limit"]
|
100
|
+
|
101
|
+
Configure the maximum number of characters for bedrock span tags for prompt/response text.
|
102
|
+
|
103
|
+
Text exceeding the maximum number of characters is truncated to the character limit
|
104
|
+
and has ``...`` appended to the end.
|
105
|
+
|
106
|
+
Alternatively, you can set this option with the ``DD_BEDROCK_SPAN_CHAR_LIMIT`` environment
|
107
|
+
variable.
|
108
|
+
|
109
|
+
Default: ``128``
|
110
|
+
|
111
|
+
|
112
|
+
.. py:data:: ddtrace.config.botocore['dynamodb_primary_key_names_for_tables']
|
113
|
+
|
114
|
+
This enables DynamoDB API calls to be instrumented with span pointers. Many
|
115
|
+
DynamoDB API calls do not include the Item's Primary Key fields as separate
|
116
|
+
values, so they need to be provided to the tracer separately. This field
|
117
|
+
should be structured as a ``dict`` keyed by the table names as ``str``.
|
118
|
+
Each value should be the ``set`` of primary key field names (as ``str``)
|
119
|
+
for the associated table. The set may have exactly one or two elements,
|
120
|
+
depending on the Table's Primary Key schema.
|
121
|
+
|
122
|
+
In python this would look like::
|
123
|
+
|
124
|
+
ddtrace.config.botocore['dynamodb_primary_key_names_for_tables'] = {
|
125
|
+
'table_name': {'key1', 'key2'},
|
126
|
+
'other_table': {'other_key'},
|
127
|
+
}
|
128
|
+
|
129
|
+
Can also be enabled with the ``DD_BOTOCORE_DYNAMODB_TABLE_PRIMARY_KEYS``
|
130
|
+
environment variable which is parsed as a JSON object with strings for keys
|
131
|
+
and lists of strings for values.
|
132
|
+
|
133
|
+
This would look something like::
|
134
|
+
|
135
|
+
export DD_BOTOCORE_DYNAMODB_TABLE_PRIMARY_KEYS='{
|
136
|
+
"table_name": ["key1", "key2"],
|
137
|
+
"other_table": ["other_key"]
|
138
|
+
}'
|
139
|
+
|
140
|
+
Default: ``{}``
|
141
|
+
|
142
|
+
|
143
|
+
.. py:data:: ddtrace.config.botocore['add_span_pointers']
|
144
|
+
|
145
|
+
This enables the addition of span pointers to spans associated with
|
146
|
+
successful AWS API calls.
|
147
|
+
|
148
|
+
Alternatively, you can set this option with the
|
149
|
+
``DD_BOTOCORE_ADD_SPAN_POINTERS`` environment variable.
|
150
|
+
|
151
|
+
Default: ``True``
|
152
|
+
|
153
|
+
"""
|