From b9c9efd25dbbb96df84eece13763dc801b792105 Mon Sep 17 00:00:00 2001 From: Yun Kim <35776586+Yun-Kim@users.noreply.github.com> Date: Tue, 5 Sep 2023 16:28:58 -0400 Subject: [PATCH] chore: remove deprecated items (#6580) This PR adds a note to upgrade to 2.x in `upgrading.rst` and removes all deprecated items slated for removal in 2.0.0. This includes: - `DD_GEVENT_PATCH_ALL`: no special configuration is now necessary to make `ddtrace-run` work with gevent. - `DD_AWS_TAG_ALL_PARAMS`: the boto/botocore/aiobotocore integrations no longer collect all API parameters by default. - `DD_REMOTECONFIG_POLL_SECONDS`: replaced by `DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS` - ASM deprecated constants including ``APPSEC_ENABLED``, ``APPSEC_JSON``, ``APPSEC_EVENT_RULE_VERSION``, ``APPSEC_EVENT_RULE_ERRORS``, ``APPSEC_EVENT_RULE_LOADED``, ``APPSEC_EVENT_RULE_ERROR_COUNT``, ``APPSEC_WAF_DURATION``, ``APPSEC_WAF_DURATION_EXT``, ``APPSEC_WAF_TIMEOUTS``, ``APPSEC_WAF_VERSION``, ``APPSEC_ORIGIN_VALUE``, ``APPSEC_BLOCKED``, ``IAST_JSON``, ``IAST_ENABLED``, ``IAST_CONTEXT_KEY``. These constants were meant for private use only and should not affect existing code. - ``ddtrace.contrib.grpc.constants.GRPC_PORT_KEY``: replaced by `ddtrace.ext.net.TARGET_PORT` - ``ddtrace.ext.cassandra.ROW_COUNT``, ``ddtrace.ext.mongo.ROW_COUNT``, ``ddtrace.ext.sql.ROW_COUNT``: replaced by `ddtrace.ext.db.ROWCOUNT` - `ddtrace.filters.TraceCiVisibilityFilter`: removed as this was for private use only and does not affect existing code. - `ddtrace.contrib.starlette.get_resource` and `ddtrace.contrib.starlette.span_modifier` and `ddtrace.contrib.fastapi.span_modifier`: the fastapi and starlette integrations now provide the full route and not just mounted route for sub-applications by default. - `ddtrace.contrib.starlette.config['aggregate_resources']` and `ddtrace.contrib.fastapi.config['aggregate_resources']`: the starlette and fastapi integrations no longer have the option to aggregate resources as this occurs by default now. - `DD_TRACE_OBFUSCATION_QUERY_STRING_PATTERN`: replaced by `DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP`. Additionally, the `pep562` dependency and references to it have been removed as it is no longer needed after dropping support for Python < 3.7. Note that `DD_CALL_BASIC_CONFIG` and `DD_LOG_FORMAT` are removed in - [x] Change(s) are motivated and described in the PR description. - [x] Testing strategy is described if automated tests are not included in the PR. - [x] Risk is outlined (performance impact, potential for breakage, maintainability, etc). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] [Library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) are followed. If no release note is required, add label `changelog/no-changelog`. - [x] Documentation is included (in-code, generated user docs, [public corp docs](https://github.com/DataDog/documentation/)). - [x] Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) - [x] Title is accurate. - [x] No unnecessary changes are introduced. - [x] Description motivates each change. - [x] Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [x] Testing strategy adequately addresses listed risk(s). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] Release note makes sense to a user of the library. - [x] Reviewer has explicitly acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment. - [x] Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) --- ddtrace/_logger.py | 24 +- ddtrace/bootstrap/sitecustomize.py | 34 +- ddtrace/constants.py | 35 - ddtrace/contrib/aiobotocore/__init__.py | 15 - ddtrace/contrib/aiobotocore/patch.py | 12 - ddtrace/contrib/boto/__init__.py | 16 - ddtrace/contrib/boto/patch.py | 15 - ddtrace/contrib/botocore/__init__.py | 15 - ddtrace/contrib/botocore/patch.py | 11 - ddtrace/contrib/fastapi/patch.py | 11 - ddtrace/contrib/grpc/constants.py | 21 - ddtrace/contrib/starlette/patch.py | 35 - ddtrace/ext/aws.py | 30 - ddtrace/ext/cassandra.py | 22 - ddtrace/ext/mongo.py | 23 - ddtrace/ext/sql.py | 20 - ddtrace/filters.py | 24 - ddtrace/internal/compat.py | 16 - ddtrace/internal/remoteconfig/utils.py | 9 - ddtrace/internal/telemetry/constants.py | 1 - ddtrace/internal/telemetry/writer.py | 4 +- ddtrace/settings/config.py | 33 +- ddtrace/tracer.py | 38 - docs/conf.py | 2 +- docs/configuration.rst | 7 +- docs/spelling_wordlist.txt | 1 + docs/upgrading.rst | 37 +- lib-injection/docker-compose.yml | 1 - pyproject.toml | 1 - .../notes/release-2.0-3af0045e2261bd02.yaml | 18 +- ...deprecated-items-2.0-89eac06472c59554.yaml | 118 ++ riotfile.py | 38 +- scripts/get-target-milestone.py | 8 +- tests/appsec/iast/test_env_var.py | 1 - tests/appsec/test_constants.py | 88 - tests/commands/ddtrace_run_logs_injection.py | 5 +- tests/commands/test_runner.py | 23 +- tests/contrib/aiobotocore/test.py | 10 - tests/contrib/boto/test.py | 15 - tests/contrib/botocore/test.py | 1716 +++++++---------- tests/contrib/cherrypy/test_middleware.py | 4 +- tests/contrib/fastapi/test_fastapi.py | 9 - tests/contrib/grpc/test_constants.py | 16 - tests/contrib/logging/test_tracer_logging.py | 47 +- tests/contrib/starlette/test_starlette.py | 32 - tests/integration/test_debug.py | 12 +- tests/integration/test_integration.py | 41 +- .../remoteconfig/test_remoteconfig.py | 27 - .../django_app.py | 3 + .../django_app.py | 3 + .../django_app.py | 3 + .../django_app.py | 3 + .../django_app.py | 3 + .../django_app.py | 3 + tests/pep562_test/__init__.py | 10 - ..._schematization[service_schema0]_rest.json | 5 +- ..._schematization[service_schema1]_rest.json | 5 +- ..._schematization[service_schema2]_rest.json | 5 +- ..._schematization[service_schema3]_rest.json | 5 +- ..._schematization[service_schema4]_rest.json | 5 +- ..._schematization[service_schema5]_rest.json | 5 +- tests/telemetry/test_writer.py | 3 - tests/tracer/test_compat.py | 11 - tests/tracer/test_global_config.py | 9 - tests/tracer/test_propagation.py | 12 - 65 files changed, 968 insertions(+), 1866 deletions(-) create mode 100644 releasenotes/notes/remove-deprecated-items-2.0-89eac06472c59554.yaml delete mode 100644 tests/pep562_test/__init__.py diff --git a/ddtrace/_logger.py b/ddtrace/_logger.py index 24a58f29b23..a9b877ad3b3 100644 --- a/ddtrace/_logger.py +++ b/ddtrace/_logger.py @@ -5,6 +5,11 @@ from ddtrace.internal.utils.formats import asbool +DD_LOG_FORMAT = "%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] {}- %(message)s".format( + "[dd.service=%(dd.service)s dd.env=%(dd.env)s dd.version=%(dd.version)s" + " dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s] " +) + DEFAULT_FILE_SIZE_BYTES = 15 << 20 # 15 MB @@ -32,14 +37,13 @@ def configure_ddtrace_logger(): """ ddtrace_logger = logging.getLogger("ddtrace") - + ddtrace_logger.addHandler(logging.StreamHandler()) _configure_ddtrace_debug_logger(ddtrace_logger) _configure_ddtrace_file_logger(ddtrace_logger) def _configure_ddtrace_debug_logger(logger): - debug_enabled = asbool(os.environ.get("DD_TRACE_DEBUG", "false")) - if debug_enabled: + if asbool(os.environ.get("DD_TRACE_DEBUG", "false")): logger.setLevel(logging.DEBUG) logger.debug("debug mode has been enabled for the ddtrace logger") @@ -62,11 +66,21 @@ def _configure_ddtrace_file_logger(logger): ddtrace_file_handler = RotatingFileHandler( filename=log_path, mode="a", maxBytes=max_file_bytes, backupCount=num_backup ) - log_format = "%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] - %(message)s" log_formatter = logging.Formatter(log_format) - ddtrace_file_handler.setLevel(file_log_level_value) ddtrace_file_handler.setFormatter(log_formatter) logger.addHandler(ddtrace_file_handler) logger.debug("ddtrace logs will be routed to %s", log_path) + + +def _configure_log_injection(): + """ + Ensures that logging is patched before we inject trace information into logs. + """ + from ddtrace import patch + + patch(logging=True) + ddtrace_logger = logging.getLogger("ddtrace") + for handler in ddtrace_logger.handlers: + handler.setFormatter(logging.Formatter(DD_LOG_FORMAT)) diff --git a/ddtrace/bootstrap/sitecustomize.py b/ddtrace/bootstrap/sitecustomize.py index 29f1d83a20b..8536ff85ce5 100644 --- a/ddtrace/bootstrap/sitecustomize.py +++ b/ddtrace/bootstrap/sitecustomize.py @@ -10,6 +10,7 @@ import warnings # noqa from ddtrace import config # noqa +from ddtrace._logger import _configure_log_injection from ddtrace.debugging._config import di_config # noqa from ddtrace.debugging._config import ed_config # noqa from ddtrace.internal.compat import PY2 # noqa @@ -19,43 +20,16 @@ from ddtrace.internal.runtime.runtime_metrics import RuntimeWorker # noqa from ddtrace.internal.utils.formats import asbool # noqa from ddtrace.internal.utils.formats import parse_tags_str # noqa -from ddtrace.tracer import DD_LOG_FORMAT # noqa -from ddtrace.vendor.debtcollector import deprecate # noqa +# Debug mode from the tracer will do the same here, so only need to do this otherwise. if config.logs_injection: - # immediately patch logging if trace id injected - from ddtrace import patch - - patch(logging=True) - - -# DEV: Once basicConfig is called here, future calls to it cannot be used to -# change the formatter since it applies the formatter to the root handler only -# upon initializing it the first time. -# See https://github.com/python/cpython/blob/112e4afd582515fcdcc0cde5012a4866e5cfda12/Lib/logging/__init__.py#L1550 -# Debug mode from the tracer will do a basicConfig so only need to do this otherwise -if not config._debug_mode and config._call_basic_config: - deprecate( - "ddtrace.tracer.logging.basicConfig", - message="`logging.basicConfig()` should be called in a user's application.", - removal_version="2.0.0", - ) - if config.logs_injection: - logging.basicConfig(format=DD_LOG_FORMAT) - else: - logging.basicConfig() + _configure_log_injection() + log = get_logger(__name__) -if os.environ.get("DD_GEVENT_PATCH_ALL") is not None: - deprecate( - "The environment variable DD_GEVENT_PATCH_ALL is deprecated and will be removed in a future version. ", - postfix="There is no special configuration necessary to make ddtrace work with gevent if using ddtrace-run. " - "If not using ddtrace-run, import ddtrace.auto before calling gevent.monkey.patch_all().", - removal_version="2.0.0", - ) if "gevent" in sys.modules or "gevent.monkey" in sys.modules: import gevent.monkey # noqa diff --git a/ddtrace/constants.py b/ddtrace/constants.py index dea0d63555f..ee1a024f56f 100644 --- a/ddtrace/constants.py +++ b/ddtrace/constants.py @@ -1,36 +1,3 @@ -from ddtrace.internal.compat import ensure_pep562 -from ddtrace.vendor.debtcollector import deprecate - - -deprecated_names = { - "APPSEC_ENABLED": "_dd.appsec.enabled", - "APPSEC_JSON": "_dd.appsec.json", - "APPSEC_EVENT_RULE_VERSION": "_dd.appsec.event_rules.version", - "APPSEC_EVENT_RULE_ERRORS": "_dd.appsec.event_rules.errors", - "APPSEC_EVENT_RULE_LOADED": "_dd.appsec.event_rules.loaded", - "APPSEC_EVENT_RULE_ERROR_COUNT": "_dd.appsec.event_rules.error_count", - "APPSEC_WAF_DURATION": "_dd.appsec.waf.duration", - "APPSEC_WAF_DURATION_EXT": "_dd.appsec.waf.duration_ext", - "APPSEC_WAF_TIMEOUTS": "_dd.appsec.waf.timeouts", - "APPSEC_WAF_VERSION": "_dd.appsec.waf.version", - "APPSEC_ORIGIN_VALUE": "appsec", - "APPSEC_BLOCKED": "appsec.blocked", - "IAST_JSON": "_dd.iast.json", - "IAST_ENABLED": "_dd.iast.enabled", - "IAST_CONTEXT_KEY": "_iast_data", -} - - -def __getattr__(name): - if name in deprecated_names: - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - removal_version="2.0.0", - ) - return deprecated_names[name] - raise AttributeError("'%s' has no attribute '%s'", __name__, name) - - SAMPLE_RATE_METRIC_KEY = "_sample_rate" SAMPLING_PRIORITY_KEY = "_sampling_priority_v1" ANALYTICS_SAMPLE_RATE_KEY = "_dd1.sr.eausr" @@ -77,5 +44,3 @@ def __getattr__(name): AUTO_KEEP = 1 # Use this to explicitly inform the backend that a trace should be kept and stored. USER_KEEP = 2 - -ensure_pep562(__name__) diff --git a/ddtrace/contrib/aiobotocore/__init__.py b/ddtrace/contrib/aiobotocore/__init__.py index 7a7b757030b..5930f54e7f5 100644 --- a/ddtrace/contrib/aiobotocore/__init__.py +++ b/ddtrace/contrib/aiobotocore/__init__.py @@ -24,21 +24,6 @@ Default: ``False`` -.. py:data:: ddtrace.config.aiobotocore['tag_all_params'] - - **Deprecated**: This retains the deprecated behavior of adding span tags for - all API parameters that are not explicitly excluded by the integration. - These deprecated span tags will be added along with the API parameters - enabled by default. - - This configuration is ignored if ``tag_no_parms`` (``DD_AWS_TAG_NO_PARAMS``) - is set to ``True``. - - To collect all API parameters, ``ddtrace.config.botocore.tag_all_params = - True`` or by setting the environment variable ``DD_AWS_TAG_ALL_PARAMS=true``. - - - Default: ``False`` """ from ...internal.utils.importlib import require_modules diff --git a/ddtrace/contrib/aiobotocore/patch.py b/ddtrace/contrib/aiobotocore/patch.py index 7e02ff45cbb..9e52417947a 100644 --- a/ddtrace/contrib/aiobotocore/patch.py +++ b/ddtrace/contrib/aiobotocore/patch.py @@ -5,7 +5,6 @@ from ddtrace import config from ddtrace.internal.constants import COMPONENT from ddtrace.internal.utils.version import parse_version -from ddtrace.vendor import debtcollector from ddtrace.vendor import wrapt from ...constants import ANALYTICS_SAMPLE_RATE_KEY @@ -40,18 +39,10 @@ TRACED_ARGS = {"params", "path", "verb"} -if os.getenv("DD_AWS_TAG_ALL_PARAMS") is not None: - debtcollector.deprecate( - "Using environment variable 'DD_AWS_TAG_ALL_PARAMS' is deprecated", - message="The aiobotocore integration no longer includes all API parameters by default.", - removal_version="2.0.0", - ) - config._add( "aiobotocore", { "tag_no_params": asbool(os.getenv("DD_AWS_TAG_NO_PARAMS", default=False)), - "tag_all_params": asbool(os.getenv("DD_AWS_TAG_ALL_PARAMS", default=False)), }, ) @@ -152,9 +143,6 @@ async def _wrapped_api_call(original_func, instance, args, kwargs): operation = None span.resource = endpoint_name - if not config.aiobotocore["tag_no_params"] and config.aiobotocore["tag_all_params"]: - aws.add_span_arg_tags(span, endpoint_name, args, ARGS_NAME, TRACED_ARGS) - region_name = deep_getattr(instance, "meta.region_name") meta = { diff --git a/ddtrace/contrib/boto/__init__.py b/ddtrace/contrib/boto/__init__.py index a50a97a92c2..9879b42768e 100644 --- a/ddtrace/contrib/boto/__init__.py +++ b/ddtrace/contrib/boto/__init__.py @@ -24,22 +24,6 @@ True`` or by setting the environment variable ``DD_AWS_TAG_NO_PARAMS=true``. - Default: ``False`` - -.. py:data:: ddtrace.config.boto['tag_all_params'] - - **Deprecated**: This retains the deprecated behavior of adding span tags for - all API parameters that are not explicitly excluded by the integration. - These deprecated span tags will be added along with the API parameters - enabled by default. - - This configuration is ignored if ``tag_no_parms`` (``DD_AWS_TAG_NO_PARAMS``) - is set to ``True``. - - To collect all API parameters, ``ddtrace.config.botocore.tag_all_params = - True`` or by setting the environment variable ``DD_AWS_TAG_ALL_PARAMS=true``. - - Default: ``False`` """ diff --git a/ddtrace/contrib/boto/patch.py b/ddtrace/contrib/boto/patch.py index ca9c89546a3..4db66fbb6b2 100644 --- a/ddtrace/contrib/boto/patch.py +++ b/ddtrace/contrib/boto/patch.py @@ -15,7 +15,6 @@ from ddtrace.internal.constants import COMPONENT from ddtrace.internal.utils.wrappers import unwrap from ddtrace.pin import Pin -from ddtrace.vendor import debtcollector from ddtrace.vendor import wrapt from ...internal.schema import schematize_cloud_api_operation @@ -41,18 +40,10 @@ AWS_AUTH_TRACED_ARGS = {"path", "data", "host"} -if os.getenv("DD_AWS_TAG_ALL_PARAMS") is not None: - debtcollector.deprecate( - "Using environment variable 'DD_AWS_TAG_ALL_PARAMS' is deprecated", - message="The boto integration no longer includes all API parameters by default.", - removal_version="2.0.0", - ) - config._add( "boto", { "tag_no_params": asbool(os.getenv("DD_AWS_TAG_NO_PARAMS", default=False)), - "tag_all_params": asbool(os.getenv("DD_AWS_TAG_ALL_PARAMS", default=False)), }, ) @@ -117,9 +108,6 @@ def patched_query_request(original_func, instance, args, kwargs): else: span.resource = endpoint_name - if not config.boto["tag_no_params"] and config.boto["tag_all_params"]: - aws.add_span_arg_tags(span, endpoint_name, args, AWS_QUERY_ARGS_NAME, AWS_QUERY_TRACED_ARGS) - # Obtaining region name region_name = _get_instance_region_name(instance) @@ -184,9 +172,6 @@ def patched_auth_request(original_func, instance, args, kwargs): else: span.resource = endpoint_name - if not config.boto["tag_no_params"] and config.boto["tag_all_params"]: - aws.add_span_arg_tags(span, endpoint_name, args, AWS_AUTH_ARGS_NAME, AWS_AUTH_TRACED_ARGS) - # Obtaining region name region_name = _get_instance_region_name(instance) diff --git a/ddtrace/contrib/botocore/__init__.py b/ddtrace/contrib/botocore/__init__.py index 38c6b61ad3b..e32390d7cda 100644 --- a/ddtrace/contrib/botocore/__init__.py +++ b/ddtrace/contrib/botocore/__init__.py @@ -67,21 +67,6 @@ Default: ``False`` -.. py:data:: ddtrace.config.botocore['tag_all_params'] - - **Deprecated**: This retains the deprecated behavior of adding span tags for - all API parameters that are not explicitly excluded by the integration. - These deprecated span tags will be added along with the API parameters - enabled by default. - - This configuration is ignored if ``tag_no_parms`` (``DD_AWS_TAG_NO_PARAMS``) - is set to ``True``. - - To collect all API parameters, ``ddtrace.config.botocore.tag_all_params = - True`` or by setting the environment variable ``DD_AWS_TAG_ALL_PARAMS=true``. - - - Default: ``False`` .. py:data:: ddtrace.config.botocore['instrument_internals'] diff --git a/ddtrace/contrib/botocore/patch.py b/ddtrace/contrib/botocore/patch.py index d3bd7575b18..b068e37d268 100644 --- a/ddtrace/contrib/botocore/patch.py +++ b/ddtrace/contrib/botocore/patch.py @@ -22,7 +22,6 @@ from ddtrace import config from ddtrace.internal.schema.span_attribute_schema import SpanDirection from ddtrace.settings.config import Config -from ddtrace.vendor import debtcollector from ddtrace.vendor import wrapt from ...constants import ANALYTICS_SAMPLE_RATE_KEY @@ -66,12 +65,6 @@ log = get_logger(__name__) -if os.getenv("DD_AWS_TAG_ALL_PARAMS") is not None: - debtcollector.deprecate( - "Using environment variable 'DD_AWS_TAG_ALL_PARAMS' is deprecated", - message="The botocore integration no longer includes all API parameters by default.", - removal_version="2.0.0", - ) # Botocore default settings config._add( @@ -81,7 +74,6 @@ "invoke_with_legacy_context": asbool(os.getenv("DD_BOTOCORE_INVOKE_WITH_LEGACY_CONTEXT", default=False)), "operations": collections.defaultdict(Config._HTTPServerConfig), "tag_no_params": asbool(os.getenv("DD_AWS_TAG_NO_PARAMS", default=False)), - "tag_all_params": asbool(os.getenv("DD_AWS_TAG_ALL_PARAMS", default=False)), "instrument_internals": asbool(os.getenv("DD_BOTOCORE_INSTRUMENT_INTERNALS", default=False)), }, ) @@ -595,9 +587,6 @@ def patched_api_call(original_func, instance, args, kwargs): else: span.resource = endpoint_name - if not config.botocore["tag_no_params"] and config.botocore["tag_all_params"]: - aws.add_span_arg_tags(span, endpoint_name, args, ARGS_NAME, TRACED_ARGS) - region_name = deep_getattr(instance, "meta.region_name") span.set_tag_str("aws.agent", "botocore") diff --git a/ddtrace/contrib/fastapi/patch.py b/ddtrace/contrib/fastapi/patch.py index 92886686e78..89fb7813586 100644 --- a/ddtrace/contrib/fastapi/patch.py +++ b/ddtrace/contrib/fastapi/patch.py @@ -4,13 +4,10 @@ from ddtrace import Pin from ddtrace import config from ddtrace.contrib.asgi.middleware import TraceMiddleware -from ddtrace.contrib.starlette.patch import get_resource from ddtrace.contrib.starlette.patch import traced_handler from ddtrace.internal.logger import get_logger from ddtrace.internal.schema import schematize_service_name -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning from ddtrace.internal.utils.wrappers import unwrap as _u -from ddtrace.vendor.debtcollector import removals from ddtrace.vendor.wrapt import ObjectProxy from ddtrace.vendor.wrapt import wrap_function_wrapper as _w @@ -23,7 +20,6 @@ _default_service=schematize_service_name("fastapi"), request_span_name="fastapi.request", distributed_tracing=True, - aggregate_resources=True, ), ) @@ -33,13 +29,6 @@ def get_version(): return getattr(fastapi, "__version__", "") -@removals.remove(removal_version="2.0.0", category=DDTraceDeprecationWarning) -def span_modifier(span, scope): - resource = get_resource(scope) - if config.fastapi["aggregate_resources"] and resource: - span.resource = "{} {}".format(scope["method"], resource) - - def wrap_middleware_stack(wrapped, instance, args, kwargs): return TraceMiddleware(app=wrapped(*args, **kwargs), integration_config=config.fastapi) diff --git a/ddtrace/contrib/grpc/constants.py b/ddtrace/contrib/grpc/constants.py index 59b53d2843e..232c709de72 100644 --- a/ddtrace/contrib/grpc/constants.py +++ b/ddtrace/contrib/grpc/constants.py @@ -1,8 +1,5 @@ import grpc -from ddtrace.internal.compat import ensure_pep562 -from ddtrace.vendor.debtcollector import deprecate - GRPC_PIN_MODULE_SERVER = grpc.Server GRPC_PIN_MODULE_CLIENT = grpc.Channel @@ -27,21 +24,3 @@ GRPC_AIO_SERVICE_SERVER = "grpc-aio-server" GRPC_SERVICE_CLIENT = "grpc-client" GRPC_AIO_SERVICE_CLIENT = "grpc-aio-client" - - -def __getattr__(name): - if name == "GRPC_PORT_KEY": - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - postfix=". Use ddtrace.ext.net.TARGET_PORT instead.", - removal_version="2.0.0", - ) - return "grpc.port" - - if name in globals(): - return globals()[name] - - raise AttributeError("'%s' has no attribute '%s'", __name__, name) - - -ensure_pep562(__name__) diff --git a/ddtrace/contrib/starlette/patch.py b/ddtrace/contrib/starlette/patch.py index 2d1c7d7d5da..55c5cf74f2d 100644 --- a/ddtrace/contrib/starlette/patch.py +++ b/ddtrace/contrib/starlette/patch.py @@ -5,7 +5,6 @@ import starlette from starlette.middleware import Middleware -from starlette.routing import Match from ddtrace import config from ddtrace.contrib.asgi.middleware import TraceMiddleware @@ -13,11 +12,8 @@ from ddtrace.internal.logger import get_logger from ddtrace.internal.schema import schematize_service_name from ddtrace.internal.utils import get_argument_value -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning from ddtrace.internal.utils.wrappers import unwrap as _u from ddtrace.span import Span -from ddtrace.vendor.debtcollector import deprecate -from ddtrace.vendor.debtcollector import removals from ddtrace.vendor.wrapt import ObjectProxy from ddtrace.vendor.wrapt import wrap_function_wrapper as _w @@ -30,7 +26,6 @@ _default_service=schematize_service_name("starlette"), request_span_name="starlette.request", distributed_tracing=True, - aggregate_resources=True, ), ) @@ -40,27 +35,6 @@ def get_version(): return getattr(starlette, "__version__", "") -@removals.remove(removal_version="2.0.0", category=DDTraceDeprecationWarning) -def get_resource(scope): - path = None - routes = scope["app"].routes - for route in routes: - match, _ = route.matches(scope) - if match == Match.FULL: - path = route.path - break - elif match == Match.PARTIAL and path is None: - path = route.path - return path - - -@removals.remove(removal_version="2.0.0", category=DDTraceDeprecationWarning) -def span_modifier(span, scope): - resource = get_resource(scope) - if config.starlette["aggregate_resources"] and resource: - span.resource = "{} {}".format(scope["method"], resource) - - def traced_init(wrapped, instance, args, kwargs): mw = kwargs.pop("middleware", []) mw.insert(0, Middleware(TraceMiddleware, integration_config=config.starlette)) @@ -101,15 +75,6 @@ def unpatch(): def traced_handler(wrapped, instance, args, kwargs): - if config.starlette.get("aggregate_resources") is False or config.fastapi.get("aggregate_resources") is False: - deprecate( - "ddtrace.contrib.starlette.patch", - message="`aggregate_resources` is deprecated and will be removed in tracer version 2.0.0", - category=DDTraceDeprecationWarning, - ) - - return wrapped(*args, **kwargs) - # Since handle can be called multiple times for one request, we take the path of each instance # Then combine them at the end to get the correct resource names scope = get_argument_value(args, kwargs, 0, "scope") # type: Optional[Dict[str, Any]] diff --git a/ddtrace/ext/aws.py b/ddtrace/ext/aws.py index 15281806f8b..ef7f343af59 100644 --- a/ddtrace/ext/aws.py +++ b/ddtrace/ext/aws.py @@ -1,24 +1,12 @@ from typing import Any from typing import Dict -from typing import FrozenSet -from typing import Set from typing import TYPE_CHECKING -from typing import Tuple - -from ddtrace.contrib.trace_utils import set_flattened_tags if TYPE_CHECKING: # pragma: no cover from ddtrace.span import Span -EXCLUDED_ENDPOINT = frozenset({"kms", "sts", "sns", "kinesis", "events"}) -EXCLUDED_ENDPOINT_TAGS = { - "firehose": frozenset({"params.Records"}), - "secretsmanager": frozenset({"params.SecretString", "params.SecretBinary"}), -} - - def truncate_arg_value(value, max_len=1024): # type: (Any, int) -> Any """Truncate values which are bytes and greater than `max_len`. @@ -30,24 +18,6 @@ def truncate_arg_value(value, max_len=1024): return value -def add_span_arg_tags( - span, # type: Span - endpoint_name, # type: str - args, # type: Tuple[Any] - args_names, # type: Tuple[str] - args_traced, # type: Set[str] -): - # type: (...) -> None - if endpoint_name not in EXCLUDED_ENDPOINT: - exclude_set = EXCLUDED_ENDPOINT_TAGS.get(endpoint_name, frozenset()) # type: FrozenSet[str] - set_flattened_tags( - span, - items=((name, value) for (name, value) in zip(args_names, args) if name in args_traced), - exclude_policy=lambda tag: tag in exclude_set or tag.endswith("Body"), - processor=truncate_arg_value, - ) - - def _add_api_param_span_tags(span, endpoint_name, params): # type: (Span, str, Dict[str, Any]) -> None # Note: Only some boto3 requests will supply these params diff --git a/ddtrace/ext/cassandra.py b/ddtrace/ext/cassandra.py index 49b6826b7b7..d510897d12d 100644 --- a/ddtrace/ext/cassandra.py +++ b/ddtrace/ext/cassandra.py @@ -1,28 +1,6 @@ -from ddtrace.internal.compat import ensure_pep562 -from ddtrace.vendor.debtcollector import deprecate - - # tags CLUSTER = "cassandra.cluster" KEYSPACE = "cassandra.keyspace" CONSISTENCY_LEVEL = "cassandra.consistency_level" PAGINATED = "cassandra.paginated" PAGE_NUMBER = "cassandra.page_number" - - -def __getattr__(name): - if name == "ROW_COUNT": - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - postfix=". Use ddtrace.ext.db.ROWCOUNT instead.", - removal_version="2.0.0", - ) - return "cassandra.row_count" - - if name in globals(): - return globals()[name] - - raise AttributeError("'%s' has no attribute '%s'", __name__, name) - - -ensure_pep562(__name__) diff --git a/ddtrace/ext/mongo.py b/ddtrace/ext/mongo.py index b1fcb729ff2..d27d97d8862 100644 --- a/ddtrace/ext/mongo.py +++ b/ddtrace/ext/mongo.py @@ -1,27 +1,4 @@ -from ddtrace.internal.compat import ensure_pep562 -from ddtrace.vendor.debtcollector import deprecate - - SERVICE = "mongodb" COLLECTION = "mongodb.collection" DB = "mongodb.db" -ROWS = "mongodb.rows" QUERY = "mongodb.query" - - -def __getattr__(name): - if name == "ROWS": - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - postfix=". Use ddtrace.ext.db.ROWCOUNT instead.", - removal_version="2.0.0", - ) - return "mongodb.rows" - - if name in globals(): - return globals()[name] - - raise AttributeError("'%s' has no attribute '%s'", __name__, name) - - -ensure_pep562(__name__) diff --git a/ddtrace/ext/sql.py b/ddtrace/ext/sql.py index d54d47ebc13..d856383b64e 100644 --- a/ddtrace/ext/sql.py +++ b/ddtrace/ext/sql.py @@ -1,9 +1,7 @@ from typing import Dict -from ddtrace.internal.compat import ensure_pep562 from ddtrace.internal.logger import get_logger from ddtrace.internal.module import ModuleWatchdog -from ddtrace.vendor.debtcollector import deprecate log = get_logger(__name__) @@ -76,21 +74,3 @@ def use_psycopg3_parse_dsn(psycopg_module): except ImportError: # Best effort, we'll use our own parser: _dd_parse_pg_dsn pass - - -def __getattr__(name): - if name == "ROWS": - deprecate( - ("%s.%s is deprecated" % (__name__, name)), - postfix=". Use ddtrace.ext.db.ROWCOUNT instead.", - removal_version="2.0.0", - ) - return "sql.rows" - - if name in globals(): - return globals()[name] - - raise AttributeError("'%s' has no attribute '%s'", __name__, name) - - -ensure_pep562(__name__) diff --git a/ddtrace/filters.py b/ddtrace/filters.py index 584680d806a..ae42a9ec4d1 100644 --- a/ddtrace/filters.py +++ b/ddtrace/filters.py @@ -4,12 +4,8 @@ from typing import Optional from typing import TYPE_CHECKING -import ddtrace -from ddtrace.ext import SpanTypes -from ddtrace.ext import ci from ddtrace.ext import http from ddtrace.internal.processor.trace import TraceProcessor -from ddtrace.vendor.debtcollector import removals if TYPE_CHECKING: # pragma: no cover @@ -73,23 +69,3 @@ def process_trace(self, trace): if regexp.match(url): return None return trace - - -@removals.removed_class( - "TraceCiVisibilityFilter", - message="TraceCiVisibilityFilter is deprecated and will be removed from the public API.", - removal_version="2.0.0", -) -class TraceCiVisibilityFilter(TraceFilter): - def process_trace(self, trace): - # type: (List[Span]) -> Optional[List[Span]] - if not trace: - return trace - - local_root = trace[0]._local_root - if not local_root or local_root.span_type != SpanTypes.TEST: - return None - - # DEV: it might not be necessary to add library_version when using agentless mode - local_root.set_tag_str(ci.LIBRARY_VERSION, ddtrace.__version__) - return trace diff --git a/ddtrace/internal/compat.py b/ddtrace/internal/compat.py index fc1c58750ff..6feae9534df 100644 --- a/ddtrace/internal/compat.py +++ b/ddtrace/internal/compat.py @@ -278,22 +278,6 @@ def get_connection_response( CONTEXTVARS_IS_AVAILABLE = True -try: - from pep562 import Pep562 # noqa - - def ensure_pep562(module_name): - # type: (str) -> None - if sys.version_info < (3, 7): - Pep562(module_name) - - -except ImportError: - - def ensure_pep562(module_name): - # type: (str) -> None - pass - - try: from collections.abc import Iterable # noqa except ImportError: diff --git a/ddtrace/internal/remoteconfig/utils.py b/ddtrace/internal/remoteconfig/utils.py index cc7c460c8d0..0b228cff8d1 100644 --- a/ddtrace/internal/remoteconfig/utils.py +++ b/ddtrace/internal/remoteconfig/utils.py @@ -1,15 +1,6 @@ -import os - from ddtrace import config -from ddtrace.vendor.debtcollector import deprecate def get_poll_interval_seconds(): # type:() -> float - if os.getenv("DD_REMOTECONFIG_POLL_SECONDS"): - deprecate( - "Using environment variable 'DD_REMOTECONFIG_POLL_SECONDS' is deprecated", - message="Please use DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS instead.", - removal_version="2.0.0", - ) return config._remote_config_poll_interval diff --git a/ddtrace/internal/telemetry/constants.py b/ddtrace/internal/telemetry/constants.py index 12a243b9b5a..b38bed69ae3 100644 --- a/ddtrace/internal/telemetry/constants.py +++ b/ddtrace/internal/telemetry/constants.py @@ -20,7 +20,6 @@ TELEMETRY_TRACE_DEBUG = "DD_TRACE_DEBUG" TELEMETRY_ANALYTICS_ENABLED = "DD_TRACE_ANALYTICS_ENABLED" -TELEMETRY_CALL_BASIC_CONFIG = "DD_CALL_BASIC_CONFIG" TELEMETRY_STARTUP_LOGS_ENABLED = "DD_TRACE_STARTUP_LOGS" TELEMETRY_CLIENT_IP_ENABLED = "DD_TRACE_CLIENT_IP_ENABLED" TELEMETRY_LOGS_INJECTION_ENABLED = "DD_LOGS_INJECTION" diff --git a/ddtrace/internal/telemetry/writer.py b/ddtrace/internal/telemetry/writer.py index e7d312c9fb9..119e22ab3e5 100644 --- a/ddtrace/internal/telemetry/writer.py +++ b/ddtrace/internal/telemetry/writer.py @@ -37,7 +37,6 @@ from .constants import TELEMETRY_128_BIT_TRACEID_LOGGING_ENABLED from .constants import TELEMETRY_ANALYTICS_ENABLED from .constants import TELEMETRY_ASM_ENABLED -from .constants import TELEMETRY_CALL_BASIC_CONFIG from .constants import TELEMETRY_CLIENT_IP_ENABLED from .constants import TELEMETRY_DSM_ENABLED from .constants import TELEMETRY_DYNAMIC_INSTRUMENTATION_ENABLED @@ -293,8 +292,7 @@ def _app_started_event(self): self.add_configurations( [ (TELEMETRY_TRACING_ENABLED, config._tracing_enabled, "unknown"), - (TELEMETRY_CALL_BASIC_CONFIG, config._call_basic_config, "unknown"), - (TELEMETRY_STARTUP_LOGS_ENABLED, config._call_basic_config, "unknown"), + (TELEMETRY_STARTUP_LOGS_ENABLED, config._startup_logs_enabled, "unknown"), (TELEMETRY_DSM_ENABLED, config._data_streams_enabled, "unknown"), (TELEMETRY_ASM_ENABLED, config._appsec_enabled, "unknown"), (TELEMETRY_PROFILING_ENABLED, profiling_config.enabled, "unknown"), diff --git a/ddtrace/settings/config.py b/ddtrace/settings/config.py index 54128aa2664..889b953c882 100644 --- a/ddtrace/settings/config.py +++ b/ddtrace/settings/config.py @@ -13,8 +13,6 @@ from ddtrace.internal.serverless import in_azure_function_consumption_plan from ddtrace.internal.serverless import in_gcp_function from ddtrace.internal.utils.cache import cachedmethod -from ddtrace.internal.utils.deprecations import DDTraceDeprecationWarning -from ddtrace.vendor.debtcollector import deprecate from ..internal import gitmetadata from ..internal.constants import DEFAULT_BUFFER_SIZE @@ -23,7 +21,6 @@ from ..internal.constants import DEFAULT_REUSE_CONNECTIONS from ..internal.constants import DEFAULT_SAMPLING_RATE_LIMIT from ..internal.constants import PROPAGATION_STYLE_ALL -from ..internal.constants import PROPAGATION_STYLE_B3 from ..internal.constants import _PROPAGATION_STYLE_DEFAULT from ..internal.logger import get_logger from ..internal.schema import DEFAULT_SPAN_SERVICE_NAME @@ -122,14 +119,6 @@ def _parse_propagation_styles(name, default): return None for style in envvar.split(","): style = style.strip().lower() - if style == "b3": - deprecate( - 'Using DD_TRACE_PROPAGATION_STYLE="b3" is deprecated', - message="Please use 'DD_TRACE_PROPAGATION_STYLE=\"b3multi\"' instead", - removal_version="2.0.0", - category=DDTraceDeprecationWarning, - ) - style = PROPAGATION_STYLE_B3 if not style: continue if style not in PROPAGATION_STYLE_ALL: @@ -233,13 +222,6 @@ def __init__(self): self._debug_mode = asbool(os.getenv("DD_TRACE_DEBUG", default=False)) self._startup_logs_enabled = asbool(os.getenv("DD_TRACE_STARTUP_LOGS", False)) - self._call_basic_config = asbool(os.environ.get("DD_CALL_BASIC_CONFIG", "false")) - if self._call_basic_config: - deprecate( - "`DD_CALL_BASIC_CONFIG` is deprecated and will be removed in the next major version.", - message="Call `logging.basicConfig()` to configure logging in your application", - removal_version="2.0.0", - ) self._trace_sample_rate = os.getenv("DD_TRACE_SAMPLE_RATE") self._trace_rate_limit = int(os.getenv("DD_TRACE_RATE_LIMIT", default=DEFAULT_SAMPLING_RATE_LIMIT)) @@ -373,18 +355,9 @@ def __init__(self): except (TypeError, ValueError): pass - if "DD_TRACE_OBFUSCATION_QUERY_STRING_PATTERN" in os.environ: - deprecate( - "`DD_TRACE_OBFUSCATION_QUERY_STRING_PATTERN` is deprecated " - "and will be removed in the next major version.", - message="use `DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP` instead", - removal_version="2.0.0", - ) - dd_trace_obfuscation_query_string_regexp = os.getenv("DD_TRACE_OBFUSCATION_QUERY_STRING_PATTERN") - else: - dd_trace_obfuscation_query_string_regexp = os.getenv( - "DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP", DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP_DEFAULT - ) + dd_trace_obfuscation_query_string_regexp = os.getenv( + "DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP", DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP_DEFAULT + ) self.global_query_string_obfuscation_disabled = True # If empty obfuscation pattern self._obfuscation_query_string_pattern = None self.http_tag_query_string = True # Default behaviour of query string tagging in http.url diff --git a/ddtrace/tracer.py b/ddtrace/tracer.py index 499c9b569e6..15b529a25f9 100644 --- a/ddtrace/tracer.py +++ b/ddtrace/tracer.py @@ -11,16 +11,13 @@ from ddtrace import config from ddtrace.filters import TraceFilter -from ddtrace.internal.compat import ensure_pep562 from ddtrace.internal.processor.endpoint_call_counter import EndpointCallCounterProcessor from ddtrace.internal.sampling import SpanSamplingRule from ddtrace.internal.sampling import get_span_sampling_rules from ddtrace.internal.utils import _get_metas_to_propagate from ddtrace.settings.peer_service import _ps_config -from ddtrace.vendor import debtcollector from . import _hooks -from ._monkey import patch from .constants import ENV_KEY from .constants import HOSTNAME_KEY from .constants import PID @@ -81,24 +78,6 @@ log = get_logger(__name__) -DD_LOG_FORMAT = "%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] {}- %(message)s".format( - "[dd.service=%(dd.service)s dd.env=%(dd.env)s dd.version=%(dd.version)s" - " dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s] " -) -if config._debug_mode and not hasHandlers(log) and config._call_basic_config: - debtcollector.deprecate( - "ddtrace.tracer.logging.basicConfig", - message="`logging.basicConfig()` should be called in a user's application.", - removal_version="2.0.0", - ) - if config.logs_injection: - # We need to ensure logging is patched in case the tracer logs during initialization - patch(logging=True) - logging.basicConfig(level=logging.DEBUG, format=DD_LOG_FORMAT) - else: - logging.basicConfig(level=logging.DEBUG) - - _INTERNAL_APPLICATION_SPAN_TYPES = {"custom", "template", "web", "worker"} @@ -1081,20 +1060,3 @@ def _use_sync_mode(): @staticmethod def _is_span_internal(span): return not span.span_type or span.span_type in _INTERNAL_APPLICATION_SPAN_TYPES - - -def __getattr__(name): - if name == "DD_LOG_FORMAT": - debtcollector.deprecate( - ("%s.%s is deprecated." % (__name__, name)), - removal_version="2.0.0", - ) - return DD_LOG_FORMAT - - if name in globals(): - return globals()[name] - - raise AttributeError("'%s' has no attribute '%s'", __name__, name) - - -ensure_pep562(__name__) diff --git a/docs/conf.py b/docs/conf.py index 21f7ea9aa63..d7de7ebc376 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -557,7 +557,7 @@ def _get_report_max_version(self, max_commits=50): versions = set() # set[Version] # For release branches we want to set the max to the next minor, e.g. 1.2 -> 1.3.0 - # For dev branches we want to set the max to the next major, e.g. 1.x -> 2.0.0 + # For dev branches we want to set the max to the next major, e.g. 2.x -> 3.0.0 for origin in origins: if self._release_branch_pattern.match(origin): v = Version(origin) diff --git a/docs/configuration.rst b/docs/configuration.rst index a5bc4482d80..e5f0a420ed8 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -87,7 +87,7 @@ The following environment variables for the tracer are supported: type: Boolean default: False description: | - Enables debug logging in the tracer. Setting this flag will cause the library to create a root logging handler if one does not already exist. + Enables debug logging in the tracer. Can be used with `DD_TRACE_LOG_FILE` to route logs to a file. version_added: @@ -136,11 +136,6 @@ The following environment variables for the tracer are supported: default: False description: Enables :ref:`Logs Injection`. - DD_CALL_BASIC_CONFIG: - type: Boolean - default: False - description: Controls whether ``logging.basicConfig`` is called in ``ddtrace-run`` or when debug mode is enabled. - DD_AGENT_HOST: type: String default: | diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index 933fdbea724..88d3462969f 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -206,6 +206,7 @@ sqlite stacktrace starlette statsd +stdout stringable subclass subdirectory diff --git a/docs/upgrading.rst b/docs/upgrading.rst index b0247f813ad..d9601ac99ff 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -1,17 +1,12 @@ Upgrading --------- -.. _upgrade-0.x: - -Upgrade 0.x -^^^^^^^^^^^ - .. _`Upgrading and deprecation warnings`: Deprecation warnings ******************** -As of v0.60.0, the library provides `Python +As of v0.60.0, the ddtrace library provides `Python warnings `_ for deprecations with an additional warning category ``ddtrace.DDTraceDeprecationWarning``. @@ -34,8 +29,14 @@ Before v0.60.0, you must enable all deprecation warnings and filter the applicat $ PYTHONWARNINGS=all python app.py + +.. _upgrade-0.x: + +Upgrade to 1.x +************** + Environment variables -********************* +^^^^^^^^^^^^^^^^^^^^^ Use the following patterns to identify the deprecated environment variables in a code base:: @@ -46,3 +47,25 @@ Use the following patterns to identify the deprecated environment variables in a -e "DD_SERVICE_NAME" \ -e "DD_TRACER_PARTIAL_FLUSH_ENABLED" \ -e "DD_TRACER_PARTIAL_FLUSH_MIN_SPANS" + + +.. _upgrade-1.x: + +Upgrade to 2.x +************** + +Environment variables +^^^^^^^^^^^^^^^^^^^^^ + +Use the following patterns to identify the deprecated environment variables in a code base:: + + git grep -e "DD_GEVENT_PATCH_ALL" \ + -e "DD_AWS_TAG_ALL_PARAMS" \ + -e "DD_REMOTECONFIG_POLL_SECONDS" \ + -e "DD_CALL_BASIC_CONFIG" \ + + +Legacy tracing interfaces +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Reference the :ref:`2.x release note ` to identify and remove the deprecated legacy tracing interfaces in a code base. diff --git a/lib-injection/docker-compose.yml b/lib-injection/docker-compose.yml index d20db96f623..d7159d7c673 100644 --- a/lib-injection/docker-compose.yml +++ b/lib-injection/docker-compose.yml @@ -45,6 +45,5 @@ services: - PYTHONPATH=/datadog-lib - DD_TRACE_AGENT_URL=http://testagent:8126 - DD_TRACE_DEBUG=1 - - DD_CALL_BASIC_CONFIG=1 volumes: - ${TEMP_DIR:-/tmp/ddtrace_test}:/datadog-lib diff --git a/pyproject.toml b/pyproject.toml index 01e5ecacf5b..18675abb6d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,7 +42,6 @@ dependencies = [ "ipaddress; python_version<'3.7'", "opentelemetry-api>=1; python_version>='3.7'", "pathlib2; python_version<'3.5'", - "pep562; python_version<'3.7'", "protobuf>=3,<3.18; python_version<'3.6'", "protobuf>=3,<4.0; python_version=='3.6'", "protobuf>=3; python_version>='3.7'", diff --git a/releasenotes/notes/release-2.0-3af0045e2261bd02.yaml b/releasenotes/notes/release-2.0-3af0045e2261bd02.yaml index 4d58152435d..9b42a5fc422 100644 --- a/releasenotes/notes/release-2.0-3af0045e2261bd02.yaml +++ b/releasenotes/notes/release-2.0-3af0045e2261bd02.yaml @@ -1,21 +1,21 @@ --- prelude: > - The Datadog APM Python team is happy to announce the release of v2.0.0 of - ddtrace. This release introduces a formal :ref:`support policy< - introduces a formal :ref:`versioning support policy` for the major - versions of the ddtrace library, drops support for Python 2.7, 3.5, and 3.6, and - adds support for Python 3.12. + The Datadog APM Python team is happy to announce the release of v2.0.0 of ddtrace. + This release introduces a formal :ref:`versioning support policy` for the major + versions of the ddtrace library, drops support for Python 2.7, 3.5, and 3.6, and adds support for Python 3.12. + .. important:: ddtrace v2.0.0 drops support for Python 2.7, 3.5, and 3.6. Users running these unsupported Python versions should consider upgrading their Python version or continue using ddtrace v1 of the ddtrace library, which is now in maintenance mode and will only receive bug fixes. - + Before upgrading to v2.0.0, we recommend users install ``ddtrace>=1.18.0,<2.0.0`` and enable deprecation warnings. All removals to the library interface and environment variables were deprecated on the 1.x branch. + .. note:: The changes to environment variables apply only to the configuration of the ddtrace library and not the Datadog Agent. @@ -35,7 +35,6 @@ prelude: > has been removed and the ddtrace logger will log to stdout by default, or a log file as specified using ``DD_TRACE_LOG_FILE``. - Setting the environment variable ``DD_TRACE_PROPAGATION_STYLE='b3'`` has been removed. Please use `DD_TRACE_PROPAGATION_STYLE='b3multi'`` instead. @@ -68,7 +67,12 @@ prelude: > * - ``DD_CALL_BASIC_CONFIG`` - None - :ref:`📝` + * - ``DD_TRACE_OBFUSCATION_QUERY_STRING_PATERN`` + - ``DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP`` + - :ref:`📝` + + .. _removed-2.0-tracing-interfaces: Removed legacy tracing interfaces diff --git a/releasenotes/notes/remove-deprecated-items-2.0-89eac06472c59554.yaml b/releasenotes/notes/remove-deprecated-items-2.0-89eac06472c59554.yaml new file mode 100644 index 00000000000..1ac724f2856 --- /dev/null +++ b/releasenotes/notes/remove-deprecated-items-2.0-89eac06472c59554.yaml @@ -0,0 +1,118 @@ +--- +upgrade: + - ".. _remove-dd-gevent-patch-all: + + + ``DD_GEVENT_PATCH_ALL`` is removed. + There is no special configuration necessary to make ddtrace work with gevent if using ddtrace-run. + + + " + - ".. _remove-aws-tag-all-params: + + + ``DD_AWS_TAG_ALL_PARAMS`` is removed. + The boto/botocore/aiobotocore integrations no longer collect all API parameters by default. + + " + - ".. _rename-remote-config-poll-seconds: + + + ``DD_REMOTECONFIG_POLL_SECONDS`` is removed. + Use the environment variable ``DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS`` instead. + + " + - ".. _remove-appsec-private-constants: + + + ``APPSEC_ENABLED``, ``APPSEC_JSON``, ``APPSEC_EVENT_RULE_VERSION``, ``APPSEC_EVENT_RULE_ERRORS``, + ``APPSEC_EVENT_RULE_LOADED``, ``APPSEC_EVENT_RULE_ERROR_COUNT``, ``APPSEC_WAF_DURATION``, ``APPSEC_WAF_DURATION_EXT``, + ``APPSEC_WAF_TIMEOUTS``, ``APPSEC_WAF_VERSION``, ``APPSEC_ORIGIN_VALUE``, ``APPSEC_BLOCKED``, + ``IAST_JSON``, ``IAST_ENABLED``, ``IAST_CONTEXT_KEY`` are removed. + This should not affect existing code as these deprecated ASM constants were meant for private use only. + + " + - ".. _remove-fastapi-starlette-span-modifier: + + + ``ddtrace.contrib.starlette.get_resource``, ``ddtrace.contrib.starlette.span_modifier``, and + ``ddtrace.contrib.fastapi.span_modifier`` are removed. + The starlette and fastapi integrations now provide the full route and not just the mounted route for sub-applications. + + + " + - ".. _remove-fastapi-starlette-aggregate-resources: + + + ``ddtrace.contrib.starlette.config['aggregate_resources']`` and ``ddtrace.contrib.fastapi.config['aggregate_resources']`` + are removed. + The starlette and fastapi integrations no longer have the option to ``aggregate_resources``, as it + now occurs by default. + + + " + - ".. _remove-grpc-port-key: + + + ``ddtrace.contrib.grpc.constants.GRPC_PORT_KEY`` is removed. + Use ``ddtrace.ext.net.TARGET_PORT`` instead. + + + " + - ".. _remove-cassandra-row-count: + + + ``ddtrace.ext.cassandra.ROW_COUNT`` is removed. + Use ``ddtrace.ext.db.ROWCOUNT`` instead. + + + " + - ".. _remove-mongo-row-count: + + + ``ddtrace.ext.mongo.ROW_COUNT`` is removed. + Use ``ddtrace.ext.db.ROWCOUNT`` instead. + + + " + - ".. _remove-sql-row-count: + + + ``ddtrace.ext.sql.ROW_COUNT`` is removed. + Use ``ddtrace.ext.db.ROWCOUNT`` instead. + + + " + - ".. _remove-trace-ci-visibility-filter: + + + ``ddtrace.filters.TraceCiVisibilityFilter`` is removed. + + + " + - ".. _remove-dd-log-format: + + + ``ddtrace.tracer.DD_LOG_FORMAT`` is removed. + As an alternative, please follow the log injection formatting as provided in the + `log injection docs `_. + + + " + - ".. _remove-basic-config: + + + ``DD_CALL_BASIC_CONFIG`` is removed. + There is no special configuration necessary to replace ``DD_CALL_BASIC_CONFIG``. + The ddtrace logger will log to stdout by default or additionally to a file specified by ``DD_TRACE_LOG_FILE``. + + + " + - ".. _remove-trace-obfuscation-query-string-pattern: + + + ``DD_TRACE_OBFUSCATION_QUERY_STRING_PATTERN`` is removed. + Use ``DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP`` instead. + + + " diff --git a/riotfile.py b/riotfile.py index 6ab8d7dc90d..6ed4425dee3 100644 --- a/riotfile.py +++ b/riotfile.py @@ -1321,25 +1321,6 @@ def select_pys(min_version=MIN_PYTHON_VERSION, max_version=MAX_PYTHON_VERSION): ), ], ), - Venv( - name="pytest-benchmark", - command="pytest {cmdargs} tests/contrib/pytest_benchmark/", - pkgs={"msgpack": latest}, - venvs=[ - Venv( - venvs=[ - Venv( - pys=select_pys(min_version="3.7", max_version="3.10"), - pkgs={ - "pytest-benchmark": [ - ">=3.1.0,<=4.0.0", - ] - }, - ) - ], - ), - ], - ), Venv( name="pytest-bdd", command="pytest --no-ddtrace {cmdargs} tests/contrib/pytest_bdd/", @@ -1370,6 +1351,25 @@ def select_pys(min_version=MIN_PYTHON_VERSION, max_version=MAX_PYTHON_VERSION): ), ], ), + Venv( + name="pytest-benchmark", + command="pytest {cmdargs} tests/contrib/pytest_benchmark/", + pkgs={"msgpack": latest}, + venvs=[ + Venv( + venvs=[ + Venv( + pys=select_pys(min_version="3.7", max_version="3.10"), + pkgs={ + "pytest-benchmark": [ + ">=3.1.0,<=4.0.0", + ] + }, + ) + ], + ), + ], + ), Venv( name="grpc", command="python -m pytest {cmdargs} tests/contrib/grpc", diff --git a/scripts/get-target-milestone.py b/scripts/get-target-milestone.py index 57fc3f79f7b..87ee3432319 100755 --- a/scripts/get-target-milestone.py +++ b/scripts/get-target-milestone.py @@ -127,8 +127,8 @@ def get_next_minor_version(branch): ... ]) >>> get_next_minor_version("1.x") 'v1.21.0' - >>> get_next_minor_version("2.x") # doesn't exist - 'v2.0.0' + >>> get_next_minor_version("3.x") # doesn't exist + 'v3.0.0' >>> get_next_minor_version("0.x") 'v0.52.0' >>> get_next_minor_version("6.x") @@ -159,8 +159,8 @@ def get_next_patch_version(branch): ... ]) >>> get_next_patch_version("1.4") 'v1.4.7' - >>> get_next_patch_version("2.0") # doesn't exist - 'v2.0.0' + >>> get_next_patch_version("3.0") # doesn't exist + 'v3.0.0' >>> get_next_patch_version("0.51") # don't increment if most recent is an rc 'v0.51.0' >>> get_next_patch_version("6.0") diff --git a/tests/appsec/iast/test_env_var.py b/tests/appsec/iast/test_env_var.py index 9d6489bf479..ff9405ee269 100644 --- a/tests/appsec/iast/test_env_var.py +++ b/tests/appsec/iast/test_env_var.py @@ -86,7 +86,6 @@ def test_env_var_iast_enabled_gevent_patch_all_true(capfd): # type: (...) -> None env = os.environ.copy() env["DD_IAST_ENABLED"] = "true" - env["DD_GEVENT_PATCH_ALL"] = "true" _run_python_file(filename="main_gevent.py", env=env) captured = capfd.readouterr() assert "IAST enabled" in captured.err diff --git a/tests/appsec/test_constants.py b/tests/appsec/test_constants.py index 7b88869d1b3..53efd38d54d 100644 --- a/tests/appsec/test_constants.py +++ b/tests/appsec/test_constants.py @@ -3,94 +3,6 @@ import pytest -def test_deprecated(): - import ddtrace.constants - - message = " is deprecated and will be removed in version '2.0.0'" - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter("always") - assert ddtrace.constants.APPSEC_ENABLED - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.APPSEC_ENABLED" + message == str(warn.message) - - assert ddtrace.constants.APPSEC_JSON - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.APPSEC_JSON" + message == str(warn.message) - - assert ddtrace.constants.APPSEC_ENABLED - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.APPSEC_ENABLED" + message == str(warn.message) - - assert ddtrace.constants.APPSEC_EVENT_RULE_VERSION - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.APPSEC_EVENT_RULE_VERSION" + message == str(warn.message) - - assert ddtrace.constants.APPSEC_EVENT_RULE_ERRORS - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.APPSEC_EVENT_RULE_ERRORS" + message == str(warn.message) - - assert ddtrace.constants.APPSEC_EVENT_RULE_LOADED - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.APPSEC_EVENT_RULE_LOADED" + message == str(warn.message) - - assert ddtrace.constants.APPSEC_EVENT_RULE_ERROR_COUNT - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.APPSEC_EVENT_RULE_ERROR_COUNT" + message == str(warn.message) - - assert ddtrace.constants.APPSEC_WAF_DURATION - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.APPSEC_WAF_DURATION" + message == str(warn.message) - - assert ddtrace.constants.APPSEC_WAF_DURATION_EXT - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.APPSEC_WAF_DURATION_EXT" + message == str(warn.message) - - assert ddtrace.constants.APPSEC_WAF_TIMEOUTS - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.APPSEC_WAF_TIMEOUTS" + message == str(warn.message) - - assert ddtrace.constants.APPSEC_WAF_VERSION - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.APPSEC_WAF_VERSION" + message == str(warn.message) - - assert ddtrace.constants.APPSEC_ORIGIN_VALUE - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.APPSEC_ORIGIN_VALUE" + message == str(warn.message) - - assert ddtrace.constants.APPSEC_BLOCKED - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.APPSEC_BLOCKED" + message == str(warn.message) - - assert ddtrace.constants.IAST_JSON - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.IAST_JSON" + message == str(warn.message) - - assert ddtrace.constants.IAST_ENABLED - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.IAST_ENABLED" + message == str(warn.message) - - assert ddtrace.constants.IAST_CONTEXT_KEY - warn = warns.pop() - assert issubclass(warn.category, DeprecationWarning) - assert "ddtrace.constants.IAST_CONTEXT_KEY" + message == str(warn.message) - - def test_not_deprecated(): import ddtrace.constants diff --git a/tests/commands/ddtrace_run_logs_injection.py b/tests/commands/ddtrace_run_logs_injection.py index 69ea98ce0ef..3a08ba3736d 100644 --- a/tests/commands/ddtrace_run_logs_injection.py +++ b/tests/commands/ddtrace_run_logs_injection.py @@ -3,14 +3,15 @@ if __name__ == "__main__": # Ensure if module is patched then default log formatter is set up for logs + ddtrace_logger = logging.getLogger("ddtrace") if logging._datadog_patch: assert ( "[dd.service=%(dd.service)s dd.env=%(dd.env)s dd.version=%(dd.version)s" - " dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s]" in logging.root.handlers[0].formatter._fmt + " dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s]" in ddtrace_logger.handlers[0].formatter._fmt ) else: assert ( "[dd.service=%(dd.service)s dd.env=%(dd.env)s dd.version=%(dd.version)s" - " dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s]" not in logging.root.handlers[0].formatter._fmt + " dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s]" not in ddtrace_logger.handlers[0].formatter._fmt ) print("Test success") diff --git a/tests/commands/test_runner.py b/tests/commands/test_runner.py index 5fd3edb1697..152c84cb6ab 100644 --- a/tests/commands/test_runner.py +++ b/tests/commands/test_runner.py @@ -74,7 +74,7 @@ def test_debug_enabling(self): assert b"Test success" in out assert b"DATADOG TRACER CONFIGURATION" not in out - with self.override_env(dict(DD_TRACE_DEBUG="true", DD_CALL_BASIC_CONFIG="true")): + with self.override_env(dict(DD_TRACE_DEBUG="true")): out = subprocess.check_output( ["ddtrace-run", "python", "tests/commands/ddtrace_run_debug.py"], stderr=subprocess.STDOUT, @@ -223,22 +223,21 @@ def test_global_trace_tags(self): def test_logs_injection(self): """Ensure logs injection works""" - with self.override_env(dict(DD_LOGS_INJECTION="true", DD_CALL_BASIC_CONFIG="true")): + with self.override_env(dict(DD_LOGS_INJECTION="true")): out = subprocess.check_output(["ddtrace-run", "python", "tests/commands/ddtrace_run_logs_injection.py"]) assert out.startswith(b"Test success"), out.decode() def test_debug_mode(self): - with self.override_env(dict(DD_CALL_BASIC_CONFIG="true")): - p = subprocess.Popen( - ["ddtrace-run", "--debug", "python", "-c", "''"], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) + p = subprocess.Popen( + ["ddtrace-run", "--debug", "python", "-c", "''"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) - p.wait() - assert p.returncode == 0 - assert p.stdout.read() == six.b("") - assert six.b("ddtrace.sampler") in p.stderr.read() + p.wait() + assert p.returncode == 0 + assert p.stdout.read() == six.b("") + assert six.b("debug mode has been enabled for the ddtrace logger") in p.stderr.read() @pytest.mark.skipif(sys.version_info >= (3, 11, 0), reason="Profiler not yet compatible with Python 3.11") diff --git a/tests/contrib/aiobotocore/test.py b/tests/contrib/aiobotocore/test.py index cade6961566..6a54257dfeb 100644 --- a/tests/contrib/aiobotocore/test.py +++ b/tests/contrib/aiobotocore/test.py @@ -127,16 +127,6 @@ async def test_s3_put_no_params(tracer): assert span.get_tag("component") == "aiobotocore" -@pytest.mark.asyncio -async def test_s3_put_all_params(tracer): - with override_config("aiobotocore", dict(tag_all_params=True)): - span = await _test_s3_put(tracer) - assert span.get_tag("params.Key") == "foo" - assert span.get_tag("params.Bucket") == "mybucket" - assert span.get_tag("params.Body") is None - assert span.get_tag("component") == "aiobotocore" - - @pytest.mark.asyncio async def test_s3_client_error(tracer): async with aiobotocore_client("s3", tracer) as s3: diff --git a/tests/contrib/boto/test.py b/tests/contrib/boto/test.py index 92b9ac615fc..5d97db501cf 100644 --- a/tests/contrib/boto/test.py +++ b/tests/contrib/boto/test.py @@ -435,21 +435,6 @@ def test_s3_client_no_params(self): self.assertIsNone(span.get_tag("aws.s3.bucket_name")) self.assertIsNone(span.get_tag("bucketname")) - @mock_s3 - def test_s3_client_all_params(self): - with self.override_config("boto", dict(tag_all_params=True)): - span = self._test_s3_client() - self.assertEqual(span.get_tag("path"), "/") - - @mock_s3 - def test_s3_client_no_params_all_params(self): - # DEV: Test no params overrides all params - with self.override_config("boto", dict(tag_no_params=True, tag_all_params=True)): - span = self._test_s3_client() - self.assertIsNone(span.get_tag("aws.s3.bucket_name")) - self.assertIsNone(span.get_tag("bucketname")) - self.assertIsNone(span.get_tag("path")) - @mock_s3 def test_s3_put(self): s3 = boto.s3.connect_to_region("us-east-1") diff --git a/tests/contrib/botocore/test.py b/tests/contrib/botocore/test.py index e743a36bd48..46a738f326a 100644 --- a/tests/contrib/botocore/test.py +++ b/tests/contrib/botocore/test.py @@ -414,28 +414,6 @@ def test_s3_put_no_params(self): assert span.get_tag("params.Body") is None assert span.get_tag("component") == "botocore" - @mock_s3 - def test_s3_put_all_params(self): - with self.override_config("botocore", dict(tag_all_params=True)): - span = self._test_s3_put() - assert span.get_tag("params.Key") == "foo" - assert span.get_tag("params.Bucket") == "mybucket" - # confirm blacklisted - assert span.get_tag("params.Body") is None - assert span.get_tag("component") == "botocore" - - @mock_s3 - def test_s3_put_no_params_all_params(self): - # DEV: Test no params overrides all params - with self.override_config("botocore", dict(tag_no_params=True, tag_all_params=True)): - span = self._test_s3_put() - assert span.get_tag("aws.s3.bucket_name") is None - assert span.get_tag("bucketname") is None - assert span.get_tag("params.Key") is None - assert span.get_tag("params.Bucket") is None - assert span.get_tag("params.Body") is None - assert span.get_tag("component") == "botocore" - @mock_s3 @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_SERVICE="mysvc")) def test_schematized_s3_client_default(self): @@ -557,66 +535,21 @@ def test_sqs_client_no_params(self): assert span.get_tag("queuename") is None assert span.get_tag("params.MessageBody") is None - @mock_sqs - def test_sqs_client_all_params(self): - with self.override_config("botocore", dict(tag_all_params=True)): - span = self._test_sqs_client() - assert span.get_tag("params.MessageBody") is None - assert span.get_tag("component") == "botocore" - - @mock_sqs - def test_sqs_send_message_trace_injection_with_no_message_attributes(self): - # DEV: Only test deprecated behavior because this inspect span tags for MessageAttributes - with self.override_config("botocore", dict(tag_all_params=True)): - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) - - self.sqs_client.send_message(QueueUrl=self.sqs_test_queue["QueueUrl"], MessageBody="world") - spans = self.get_spans() - assert spans - span = spans[0] - assert len(spans) == 1 - assert span.get_tag("aws.region") == "us-east-1" - assert span.get_tag("region") == "us-east-1" - assert span.get_tag("aws.operation") == "SendMessage" - assert span.get_tag("params.MessageBody") is None - assert span.get_tag("component") == "botocore" - assert span.get_tag("span.kind"), "client" - assert_is_measured(span) - assert_span_http_status_code(span, 200) - assert span.service == "test-botocore-tracing.sqs" - assert span.resource == "sqs.sendmessage" - trace_json = span.get_tag("params.MessageAttributes._datadog.StringValue") - trace_data_injected = json.loads(trace_json) - assert trace_data_injected[HTTP_HEADER_TRACE_ID] == str(span.trace_id) - assert trace_data_injected[HTTP_HEADER_PARENT_ID] == str(span.span_id) - response = self.sqs_client.receive_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], - MessageAttributeNames=["_datadog"], - WaitTimeSeconds=2, - ) - assert len(response["Messages"]) == 1 - trace_json_message = response["Messages"][0]["MessageAttributes"]["_datadog"]["StringValue"] - trace_data_in_message = json.loads(trace_json_message) - assert trace_data_in_message[HTTP_HEADER_TRACE_ID] == str(span.trace_id) - assert trace_data_in_message[HTTP_HEADER_PARENT_ID] == str(span.span_id) - @mock_sqs def test_sqs_send_message_non_url_queue(self): - with self.override_config("botocore", dict(tag_all_params=True)): - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) - self.sqs_client.send_message(QueueUrl="Test", MessageBody="world") - spans = self.get_spans() - assert spans - span = spans[0] - assert len(spans) == 1 - assert span.get_tag("aws.operation") == "SendMessage" - assert span.resource == "sqs.sendmessage" + self.sqs_client.send_message(QueueUrl="Test", MessageBody="world") + spans = self.get_spans() + assert spans + span = spans[0] + assert len(spans) == 1 + assert span.get_tag("aws.operation") == "SendMessage" + assert span.resource == "sqs.sendmessage" @mock_sqs def test_sqs_send_message_distributed_tracing_off(self): - # DEV: Only test deprecated behavior because this inspect span tags for MessageAttributes - with self.override_config("botocore", dict(distributed_tracing=False, tag_all_params=True)): + with self.override_config("botocore", dict(distributed_tracing=False)): Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) self.sqs_client.send_message(QueueUrl=self.sqs_test_queue["QueueUrl"], MessageBody="world") @@ -644,184 +577,130 @@ def test_sqs_send_message_distributed_tracing_off(self): trace_in_message = "MessageAttributes" in response["Messages"][0] assert trace_in_message is False - @mock_sqs - def test_sqs_send_message_trace_injection_with_message_attributes(self): - # DEV: Only test deprecated behavior because this inspect span tags for MessageAttributes - with self.override_config("botocore", dict(tag_all_params=True)): - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) - message_attributes = { - "one": {"DataType": "String", "StringValue": "one"}, - "two": {"DataType": "String", "StringValue": "two"}, - "three": {"DataType": "String", "StringValue": "three"}, - "four": {"DataType": "String", "StringValue": "four"}, - "five": {"DataType": "String", "StringValue": "five"}, - "six": {"DataType": "String", "StringValue": "six"}, - "seven": {"DataType": "String", "StringValue": "seven"}, - "eight": {"DataType": "String", "StringValue": "eight"}, - "nine": {"DataType": "String", "StringValue": "nine"}, - } - self.sqs_client.send_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], MessageBody="world", MessageAttributes=message_attributes - ) - spans = self.get_spans() - assert spans - span = spans[0] - assert len(spans) == 1 - assert span.get_tag("aws.region") == "us-east-1" - assert span.get_tag("region") == "us-east-1" - assert span.get_tag("aws.operation") == "SendMessage" - assert span.get_tag("params.MessageBody") is None - assert span.get_tag("component") == "botocore" - assert span.get_tag("span.kind"), "client" - assert_is_measured(span) - assert_span_http_status_code(span, 200) - assert span.service == "test-botocore-tracing.sqs" - assert span.resource == "sqs.sendmessage" - trace_json = span.get_tag("params.MessageAttributes._datadog.StringValue") - trace_data_injected = json.loads(trace_json) - assert trace_data_injected[HTTP_HEADER_TRACE_ID] == str(span.trace_id) - assert trace_data_injected[HTTP_HEADER_PARENT_ID] == str(span.span_id) - response = self.sqs_client.receive_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], - MessageAttributeNames=["_datadog"], - WaitTimeSeconds=2, - ) - assert len(response["Messages"]) == 1 - trace_json_message = response["Messages"][0]["MessageAttributes"]["_datadog"]["StringValue"] - trace_data_in_message = json.loads(trace_json_message) - assert trace_data_in_message[HTTP_HEADER_TRACE_ID] == str(span.trace_id) - assert trace_data_in_message[HTTP_HEADER_PARENT_ID] == str(span.span_id) - @mock_sqs def test_sqs_send_message_trace_injection_with_max_message_attributes(self): - # DEV: Only test deprecated behavior where MessageBody would be excluded - with self.override_config("botocore", dict(tag_all_params=True)): - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) - message_attributes = { - "one": {"DataType": "String", "StringValue": "one"}, - "two": {"DataType": "String", "StringValue": "two"}, - "three": {"DataType": "String", "StringValue": "three"}, - "four": {"DataType": "String", "StringValue": "four"}, - "five": {"DataType": "String", "StringValue": "five"}, - "six": {"DataType": "String", "StringValue": "six"}, - "seven": {"DataType": "String", "StringValue": "seven"}, - "eight": {"DataType": "String", "StringValue": "eight"}, - "nine": {"DataType": "String", "StringValue": "nine"}, - "ten": {"DataType": "String", "StringValue": "ten"}, - } - self.sqs_client.send_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], MessageBody="world", MessageAttributes=message_attributes - ) - spans = self.get_spans() - assert spans - span = spans[0] - assert len(spans) == 1 - assert span.get_tag("aws.region") == "us-east-1" - assert span.get_tag("region") == "us-east-1" - assert span.get_tag("aws.operation") == "SendMessage" - assert span.get_tag("params.MessageBody") is None - assert span.get_tag("component") == "botocore" - assert span.get_tag("span.kind"), "client" - assert_is_measured(span) - assert_span_http_status_code(span, 200) - assert span.service == "test-botocore-tracing.sqs" - assert span.resource == "sqs.sendmessage" - trace_json = span.get_tag("params.MessageAttributes._datadog.StringValue") - assert trace_json is None - response = self.sqs_client.receive_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], - MessageAttributeNames=["_datadog"], - WaitTimeSeconds=2, - ) - assert len(response["Messages"]) == 1 - trace_in_message = "MessageAttributes" in response["Messages"][0] - assert trace_in_message is False + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) + message_attributes = { + "one": {"DataType": "String", "StringValue": "one"}, + "two": {"DataType": "String", "StringValue": "two"}, + "three": {"DataType": "String", "StringValue": "three"}, + "four": {"DataType": "String", "StringValue": "four"}, + "five": {"DataType": "String", "StringValue": "five"}, + "six": {"DataType": "String", "StringValue": "six"}, + "seven": {"DataType": "String", "StringValue": "seven"}, + "eight": {"DataType": "String", "StringValue": "eight"}, + "nine": {"DataType": "String", "StringValue": "nine"}, + "ten": {"DataType": "String", "StringValue": "ten"}, + } + self.sqs_client.send_message( + QueueUrl=self.sqs_test_queue["QueueUrl"], MessageBody="world", MessageAttributes=message_attributes + ) + spans = self.get_spans() + assert spans + span = spans[0] + assert len(spans) == 1 + assert span.get_tag("aws.region") == "us-east-1" + assert span.get_tag("region") == "us-east-1" + assert span.get_tag("aws.operation") == "SendMessage" + assert span.get_tag("params.MessageBody") is None + assert span.get_tag("component") == "botocore" + assert span.get_tag("span.kind"), "client" + assert_is_measured(span) + assert_span_http_status_code(span, 200) + assert span.service == "test-botocore-tracing.sqs" + assert span.resource == "sqs.sendmessage" + trace_json = span.get_tag("params.MessageAttributes._datadog.StringValue") + assert trace_json is None + response = self.sqs_client.receive_message( + QueueUrl=self.sqs_test_queue["QueueUrl"], + MessageAttributeNames=["_datadog"], + WaitTimeSeconds=2, + ) + assert len(response["Messages"]) == 1 + trace_in_message = "MessageAttributes" in response["Messages"][0] + assert trace_in_message is False @mock_sqs def test_sqs_send_message_batch_trace_injection_with_no_message_attributes(self): - # DEV: Only test deprecated behavior where MessageBody would be excluded - with self.override_config("botocore", dict(tag_all_params=True)): - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) - entries = [ - { - "Id": "1", - "MessageBody": "ironmaiden", - } - ] - self.sqs_client.send_message_batch(QueueUrl=self.sqs_test_queue["QueueUrl"], Entries=entries) - spans = self.get_spans() - assert spans - span = spans[0] - assert len(spans) == 1 - assert span.get_tag("aws.region") == "us-east-1" - assert span.get_tag("region") == "us-east-1" - assert span.get_tag("aws.operation") == "SendMessageBatch" - assert span.get_tag("params.MessageBody") is None - assert span.get_tag("component") == "botocore" - assert span.get_tag("span.kind"), "client" - assert_is_measured(span) - assert_span_http_status_code(span, 200) - assert span.service == "test-botocore-tracing.sqs" - assert span.resource == "sqs.sendmessagebatch" - response = self.sqs_client.receive_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], - MessageAttributeNames=["_datadog"], - WaitTimeSeconds=2, - ) - assert len(response["Messages"]) == 1 - trace_json_message = response["Messages"][0]["MessageAttributes"]["_datadog"]["StringValue"] - trace_data_in_message = json.loads(trace_json_message) - assert trace_data_in_message[HTTP_HEADER_TRACE_ID] == str(span.trace_id) - assert trace_data_in_message[HTTP_HEADER_PARENT_ID] == str(span.span_id) + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) + entries = [ + { + "Id": "1", + "MessageBody": "ironmaiden", + } + ] + self.sqs_client.send_message_batch(QueueUrl=self.sqs_test_queue["QueueUrl"], Entries=entries) + spans = self.get_spans() + assert spans + span = spans[0] + assert len(spans) == 1 + assert span.get_tag("aws.region") == "us-east-1" + assert span.get_tag("region") == "us-east-1" + assert span.get_tag("aws.operation") == "SendMessageBatch" + assert span.get_tag("params.MessageBody") is None + assert span.get_tag("component") == "botocore" + assert span.get_tag("span.kind"), "client" + assert_is_measured(span) + assert_span_http_status_code(span, 200) + assert span.service == "test-botocore-tracing.sqs" + assert span.resource == "sqs.sendmessagebatch" + response = self.sqs_client.receive_message( + QueueUrl=self.sqs_test_queue["QueueUrl"], + MessageAttributeNames=["_datadog"], + WaitTimeSeconds=2, + ) + assert len(response["Messages"]) == 1 + trace_json_message = response["Messages"][0]["MessageAttributes"]["_datadog"]["StringValue"] + trace_data_in_message = json.loads(trace_json_message) + assert trace_data_in_message[HTTP_HEADER_TRACE_ID] == str(span.trace_id) + assert trace_data_in_message[HTTP_HEADER_PARENT_ID] == str(span.span_id) @mock_sqs def test_sqs_send_message_batch_trace_injection_with_message_attributes(self): - # DEV: Only test deprecated behavior where MessageBody would be excluded - with self.override_config("botocore", dict(tag_all_params=True)): - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) - entries = [ - { - "Id": "1", - "MessageBody": "ironmaiden", - "MessageAttributes": { - "one": {"DataType": "String", "StringValue": "one"}, - "two": {"DataType": "String", "StringValue": "two"}, - "three": {"DataType": "String", "StringValue": "three"}, - "four": {"DataType": "String", "StringValue": "four"}, - "five": {"DataType": "String", "StringValue": "five"}, - "six": {"DataType": "String", "StringValue": "six"}, - "seven": {"DataType": "String", "StringValue": "seven"}, - "eight": {"DataType": "String", "StringValue": "eight"}, - "nine": {"DataType": "String", "StringValue": "nine"}, - }, - } - ] + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) + entries = [ + { + "Id": "1", + "MessageBody": "ironmaiden", + "MessageAttributes": { + "one": {"DataType": "String", "StringValue": "one"}, + "two": {"DataType": "String", "StringValue": "two"}, + "three": {"DataType": "String", "StringValue": "three"}, + "four": {"DataType": "String", "StringValue": "four"}, + "five": {"DataType": "String", "StringValue": "five"}, + "six": {"DataType": "String", "StringValue": "six"}, + "seven": {"DataType": "String", "StringValue": "seven"}, + "eight": {"DataType": "String", "StringValue": "eight"}, + "nine": {"DataType": "String", "StringValue": "nine"}, + }, + } + ] - self.sqs_client.send_message_batch(QueueUrl=self.sqs_test_queue["QueueUrl"], Entries=entries) - spans = self.get_spans() - assert spans - span = spans[0] - assert len(spans) == 1 - assert span.get_tag("aws.region") == "us-east-1" - assert span.get_tag("region") == "us-east-1" - assert span.get_tag("aws.operation") == "SendMessageBatch" - assert span.get_tag("params.MessageBody") is None - assert span.get_tag("component") == "botocore" - assert span.get_tag("span.kind"), "client" - assert_is_measured(span) - assert_span_http_status_code(span, 200) - assert span.service == "test-botocore-tracing.sqs" - assert span.resource == "sqs.sendmessagebatch" - response = self.sqs_client.receive_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], - MessageAttributeNames=["_datadog"], - WaitTimeSeconds=2, - ) - assert len(response["Messages"]) == 1 - trace_json_message = response["Messages"][0]["MessageAttributes"]["_datadog"]["StringValue"] - trace_data_in_message = json.loads(trace_json_message) - assert trace_data_in_message[HTTP_HEADER_TRACE_ID] == str(span.trace_id) - assert trace_data_in_message[HTTP_HEADER_PARENT_ID] == str(span.span_id) + self.sqs_client.send_message_batch(QueueUrl=self.sqs_test_queue["QueueUrl"], Entries=entries) + spans = self.get_spans() + assert spans + span = spans[0] + assert len(spans) == 1 + assert span.get_tag("aws.region") == "us-east-1" + assert span.get_tag("region") == "us-east-1" + assert span.get_tag("aws.operation") == "SendMessageBatch" + assert span.get_tag("params.MessageBody") is None + assert span.get_tag("component") == "botocore" + assert span.get_tag("span.kind"), "client" + assert_is_measured(span) + assert_span_http_status_code(span, 200) + assert span.service == "test-botocore-tracing.sqs" + assert span.resource == "sqs.sendmessagebatch" + response = self.sqs_client.receive_message( + QueueUrl=self.sqs_test_queue["QueueUrl"], + MessageAttributeNames=["_datadog"], + WaitTimeSeconds=2, + ) + assert len(response["Messages"]) == 1 + trace_json_message = response["Messages"][0]["MessageAttributes"]["_datadog"]["StringValue"] + trace_data_in_message = json.loads(trace_json_message) + assert trace_data_in_message[HTTP_HEADER_TRACE_ID] == str(span.trace_id) + assert trace_data_in_message[HTTP_HEADER_PARENT_ID] == str(span.span_id) @mock_sqs def test_sqs_send_message_batch_trace_injection_with_max_message_attributes(self): @@ -1115,74 +994,73 @@ def _test_data_streams_sns_to_sqs(self, use_raw_delivery): with mock.patch("time.time") as mt: mt.return_value = 1642544540 - with self.override_config("botocore", dict(tag_all_params=True)): - sns = self.session.create_client("sns", region_name="us-east-1", endpoint_url="http://localhost:4566") - - topic = sns.create_topic(Name="testTopic") + sns = self.session.create_client("sns", region_name="us-east-1", endpoint_url="http://localhost:4566") - topic_arn = topic["TopicArn"] - sqs_url = self.sqs_test_queue["QueueUrl"] - url_parts = sqs_url.split("/") - sqs_arn = "arn:aws:sqs:{}:{}:{}".format("us-east-1", url_parts[-2], url_parts[-1]) - subscription = sns.subscribe(TopicArn=topic_arn, Protocol="sqs", Endpoint=sqs_arn) + topic = sns.create_topic(Name="testTopic") - if use_raw_delivery: - sns.set_subscription_attributes( - SubscriptionArn=subscription["SubscriptionArn"], - AttributeName="RawMessageDelivery", - AttributeValue="true", - ) + topic_arn = topic["TopicArn"] + sqs_url = self.sqs_test_queue["QueueUrl"] + url_parts = sqs_url.split("/") + sqs_arn = "arn:aws:sqs:{}:{}:{}".format("us-east-1", url_parts[-2], url_parts[-1]) + subscription = sns.subscribe(TopicArn=topic_arn, Protocol="sqs", Endpoint=sqs_arn) - Pin.get_from(sns).clone(tracer=self.tracer).onto(sns) - Pin.get_from(self.sqs_client).clone(tracer=self.tracer).onto(self.sqs_client) + if use_raw_delivery: + sns.set_subscription_attributes( + SubscriptionArn=subscription["SubscriptionArn"], + AttributeName="RawMessageDelivery", + AttributeValue="true", + ) - sns.publish(TopicArn=topic_arn, Message="test") + Pin.get_from(sns).clone(tracer=self.tracer).onto(sns) + Pin.get_from(self.sqs_client).clone(tracer=self.tracer).onto(self.sqs_client) - self.get_spans() + sns.publish(TopicArn=topic_arn, Message="test") - # get SNS messages via SQS - self.sqs_client.receive_message(QueueUrl=self.sqs_test_queue["QueueUrl"], WaitTimeSeconds=2) + self.get_spans() - # clean up resources - sns.delete_topic(TopicArn=topic_arn) + # get SNS messages via SQS + self.sqs_client.receive_message(QueueUrl=self.sqs_test_queue["QueueUrl"], WaitTimeSeconds=2) - pin = Pin.get_from(sns) - buckets = pin.tracer.data_streams_processor._buckets - assert len(buckets) == 1, "Expected 1 bucket but found {}".format(len(buckets)) - first = list(buckets.values())[0].pathway_stats + # clean up resources + sns.delete_topic(TopicArn=topic_arn) - assert ( - first[ - ( - "direction:out,topic:arn:aws:sns:us-east-1:000000000000:testTopic,type:sns", - 3337976778666780987, - 0, - ) - ].full_pathway_latency._count - >= 1 - ) - assert ( - first[ - ( - "direction:out,topic:arn:aws:sns:us-east-1:000000000000:testTopic,type:sns", - 3337976778666780987, - 0, - ) - ].edge_latency._count - >= 1 - ) - assert ( - first[ - ("direction:in,topic:Test,type:sqs", 13854213076663332654, 3337976778666780987) - ].full_pathway_latency._count - >= 1 - ) - assert ( - first[ - ("direction:in,topic:Test,type:sqs", 13854213076663332654, 3337976778666780987) - ].edge_latency._count - >= 1 - ) + pin = Pin.get_from(sns) + buckets = pin.tracer.data_streams_processor._buckets + assert len(buckets) == 1, "Expected 1 bucket but found {}".format(len(buckets)) + first = list(buckets.values())[0].pathway_stats + + assert ( + first[ + ( + "direction:out,topic:arn:aws:sns:us-east-1:000000000000:testTopic,type:sns", + 3337976778666780987, + 0, + ) + ].full_pathway_latency._count + >= 1 + ) + assert ( + first[ + ( + "direction:out,topic:arn:aws:sns:us-east-1:000000000000:testTopic,type:sns", + 3337976778666780987, + 0, + ) + ].edge_latency._count + >= 1 + ) + assert ( + first[ + ("direction:in,topic:Test,type:sqs", 13854213076663332654, 3337976778666780987) + ].full_pathway_latency._count + >= 1 + ) + assert ( + first[ + ("direction:in,topic:Test,type:sqs", 13854213076663332654, 3337976778666780987) + ].edge_latency._count + >= 1 + ) @mock_sqs @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_DATA_STREAMS_ENABLED="True")) @@ -1191,52 +1069,50 @@ def test_data_streams_sqs(self): with mock.patch("time.time") as mt: mt.return_value = 1642544540 - with self.override_config("botocore", dict(tag_all_params=True)): - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) - message_attributes = { - "one": {"DataType": "String", "StringValue": "one"}, - "two": {"DataType": "String", "StringValue": "two"}, - "three": {"DataType": "String", "StringValue": "three"}, - "four": {"DataType": "String", "StringValue": "four"}, - "five": {"DataType": "String", "StringValue": "five"}, - "six": {"DataType": "String", "StringValue": "six"}, - "seven": {"DataType": "String", "StringValue": "seven"}, - "eight": {"DataType": "String", "StringValue": "eight"}, - "nine": {"DataType": "String", "StringValue": "nine"}, - } + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) + message_attributes = { + "one": {"DataType": "String", "StringValue": "one"}, + "two": {"DataType": "String", "StringValue": "two"}, + "three": {"DataType": "String", "StringValue": "three"}, + "four": {"DataType": "String", "StringValue": "four"}, + "five": {"DataType": "String", "StringValue": "five"}, + "six": {"DataType": "String", "StringValue": "six"}, + "seven": {"DataType": "String", "StringValue": "seven"}, + "eight": {"DataType": "String", "StringValue": "eight"}, + "nine": {"DataType": "String", "StringValue": "nine"}, + } - self.sqs_client.send_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], MessageBody="world", MessageAttributes=message_attributes - ) + self.sqs_client.send_message( + QueueUrl=self.sqs_test_queue["QueueUrl"], MessageBody="world", MessageAttributes=message_attributes + ) - self.sqs_client.receive_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], - MessageAttributeNames=["_datadog"], - WaitTimeSeconds=2, - ) + self.sqs_client.receive_message( + QueueUrl=self.sqs_test_queue["QueueUrl"], + MessageAttributeNames=["_datadog"], + WaitTimeSeconds=2, + ) - pin = Pin.get_from(self.sqs_client) - buckets = pin.tracer.data_streams_processor._buckets - assert len(buckets) == 1 - first = list(buckets.values())[0].pathway_stats + pin = Pin.get_from(self.sqs_client) + buckets = pin.tracer.data_streams_processor._buckets + assert len(buckets) == 1 + first = list(buckets.values())[0].pathway_stats - assert ( - first[("direction:out,topic:Test,type:sqs", 15309751356108160802, 0)].full_pathway_latency._count - >= 1 - ) - assert first[("direction:out,topic:Test,type:sqs", 15309751356108160802, 0)].edge_latency._count >= 1 - assert ( - first[ - ("direction:in,topic:Test,type:sqs", 15625264005677082004, 15309751356108160802) - ].full_pathway_latency._count - >= 1 - ) - assert ( - first[ - ("direction:in,topic:Test,type:sqs", 15625264005677082004, 15309751356108160802) - ].edge_latency._count - >= 1 - ) + assert ( + first[("direction:out,topic:Test,type:sqs", 15309751356108160802, 0)].full_pathway_latency._count >= 1 + ) + assert first[("direction:out,topic:Test,type:sqs", 15309751356108160802, 0)].edge_latency._count >= 1 + assert ( + first[ + ("direction:in,topic:Test,type:sqs", 15625264005677082004, 15309751356108160802) + ].full_pathway_latency._count + >= 1 + ) + assert ( + first[ + ("direction:in,topic:Test,type:sqs", 15625264005677082004, 15309751356108160802) + ].edge_latency._count + >= 1 + ) @mock_sqs @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_DATA_STREAMS_ENABLED="True")) @@ -1245,72 +1121,69 @@ def test_data_streams_sqs_batch(self): with mock.patch("time.time") as mt: mt.return_value = 1642544540 - with self.override_config("botocore", dict(tag_all_params=True)): - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) - message_attributes = { - "one": {"DataType": "String", "StringValue": "one"}, - "two": {"DataType": "String", "StringValue": "two"}, - "three": {"DataType": "String", "StringValue": "three"}, - "four": {"DataType": "String", "StringValue": "four"}, - "five": {"DataType": "String", "StringValue": "five"}, - "six": {"DataType": "String", "StringValue": "six"}, - "seven": {"DataType": "String", "StringValue": "seven"}, - "eight": {"DataType": "String", "StringValue": "eight"}, - "nine": {"DataType": "String", "StringValue": "nine"}, - } + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) + message_attributes = { + "one": {"DataType": "String", "StringValue": "one"}, + "two": {"DataType": "String", "StringValue": "two"}, + "three": {"DataType": "String", "StringValue": "three"}, + "four": {"DataType": "String", "StringValue": "four"}, + "five": {"DataType": "String", "StringValue": "five"}, + "six": {"DataType": "String", "StringValue": "six"}, + "seven": {"DataType": "String", "StringValue": "seven"}, + "eight": {"DataType": "String", "StringValue": "eight"}, + "nine": {"DataType": "String", "StringValue": "nine"}, + } - entries = [ - {"Id": "1", "MessageBody": "Message No. 1", "MessageAttributes": message_attributes}, - {"Id": "2", "MessageBody": "Message No. 2", "MessageAttributes": message_attributes}, - {"Id": "3", "MessageBody": "Message No. 3", "MessageAttributes": message_attributes}, - ] + entries = [ + {"Id": "1", "MessageBody": "Message No. 1", "MessageAttributes": message_attributes}, + {"Id": "2", "MessageBody": "Message No. 2", "MessageAttributes": message_attributes}, + {"Id": "3", "MessageBody": "Message No. 3", "MessageAttributes": message_attributes}, + ] - self.sqs_client.send_message_batch(QueueUrl=self.sqs_test_queue["QueueUrl"], Entries=entries) + self.sqs_client.send_message_batch(QueueUrl=self.sqs_test_queue["QueueUrl"], Entries=entries) - self.sqs_client.receive_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], - MaxNumberOfMessages=3, - MessageAttributeNames=["_datadog"], - WaitTimeSeconds=2, - ) + self.sqs_client.receive_message( + QueueUrl=self.sqs_test_queue["QueueUrl"], + MaxNumberOfMessages=3, + MessageAttributeNames=["_datadog"], + WaitTimeSeconds=2, + ) - pin = Pin.get_from(self.sqs_client) - buckets = pin.tracer.data_streams_processor._buckets - assert len(buckets) == 1 - first = list(buckets.values())[0].pathway_stats + pin = Pin.get_from(self.sqs_client) + buckets = pin.tracer.data_streams_processor._buckets + assert len(buckets) == 1 + first = list(buckets.values())[0].pathway_stats - assert ( - first[("direction:out,topic:Test,type:sqs", 15309751356108160802, 0)].full_pathway_latency._count - >= 3 - ) - assert first[("direction:out,topic:Test,type:sqs", 15309751356108160802, 0)].edge_latency._count >= 3 - assert ( - first[ - ("direction:in,topic:Test,type:sqs", 15625264005677082004, 15309751356108160802) - ].full_pathway_latency._count - >= 3 - ) - assert ( - first[ - ("direction:in,topic:Test,type:sqs", 15625264005677082004, 15309751356108160802) - ].edge_latency._count - >= 3 - ) + assert ( + first[("direction:out,topic:Test,type:sqs", 15309751356108160802, 0)].full_pathway_latency._count >= 3 + ) + assert first[("direction:out,topic:Test,type:sqs", 15309751356108160802, 0)].edge_latency._count >= 3 + assert ( + first[ + ("direction:in,topic:Test,type:sqs", 15625264005677082004, 15309751356108160802) + ].full_pathway_latency._count + >= 3 + ) + assert ( + first[ + ("direction:in,topic:Test,type:sqs", 15625264005677082004, 15309751356108160802) + ].edge_latency._count + >= 3 + ) @mock_sqs @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_DATA_STREAMS_ENABLED="True")) def test_data_streams_sqs_header_information(self): - with self.override_config("botocore", dict(tag_all_params=True)): - self.sqs_client.send_message(QueueUrl=self.sqs_test_queue["QueueUrl"], MessageBody="world") - response = self.sqs_client.receive_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], - MaxNumberOfMessages=1, - WaitTimeSeconds=2, - AttributeNames=[ - "All", - ], - ) - assert "_datadog" in response["Messages"][0]["MessageAttributes"] + self.sqs_client.send_message(QueueUrl=self.sqs_test_queue["QueueUrl"], MessageBody="world") + response = self.sqs_client.receive_message( + QueueUrl=self.sqs_test_queue["QueueUrl"], + MaxNumberOfMessages=1, + WaitTimeSeconds=2, + AttributeNames=[ + "All", + ], + ) + assert "_datadog" in response["Messages"][0]["MessageAttributes"] @mock_sqs @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_DATA_STREAMS_ENABLED="True")) @@ -1319,45 +1192,41 @@ def test_data_streams_sqs_no_header(self): with mock.patch("time.time") as mt: mt.return_value = 1642544540 - with self.override_config("botocore", dict(tag_all_params=True)): - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) - message_attributes = { - "one": {"DataType": "String", "StringValue": "one"}, - "two": {"DataType": "String", "StringValue": "two"}, - "three": {"DataType": "String", "StringValue": "three"}, - "four": {"DataType": "String", "StringValue": "four"}, - "five": {"DataType": "String", "StringValue": "five"}, - "six": {"DataType": "String", "StringValue": "six"}, - "seven": {"DataType": "String", "StringValue": "seven"}, - "eight": {"DataType": "String", "StringValue": "eight"}, - "nine": {"DataType": "String", "StringValue": "nine"}, - "ten": {"DataType": "String", "StringValue": "ten"}, - } + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(self.sqs_client) + message_attributes = { + "one": {"DataType": "String", "StringValue": "one"}, + "two": {"DataType": "String", "StringValue": "two"}, + "three": {"DataType": "String", "StringValue": "three"}, + "four": {"DataType": "String", "StringValue": "four"}, + "five": {"DataType": "String", "StringValue": "five"}, + "six": {"DataType": "String", "StringValue": "six"}, + "seven": {"DataType": "String", "StringValue": "seven"}, + "eight": {"DataType": "String", "StringValue": "eight"}, + "nine": {"DataType": "String", "StringValue": "nine"}, + "ten": {"DataType": "String", "StringValue": "ten"}, + } - self.sqs_client.send_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], MessageBody="world", MessageAttributes=message_attributes - ) + self.sqs_client.send_message( + QueueUrl=self.sqs_test_queue["QueueUrl"], MessageBody="world", MessageAttributes=message_attributes + ) - self.sqs_client.receive_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], - MessageAttributeNames=["_datadog"], - WaitTimeSeconds=2, - ) + self.sqs_client.receive_message( + QueueUrl=self.sqs_test_queue["QueueUrl"], + MessageAttributeNames=["_datadog"], + WaitTimeSeconds=2, + ) - pin = Pin.get_from(self.sqs_client) - buckets = pin.tracer.data_streams_processor._buckets - assert len(buckets) == 1 - first = list(buckets.values())[0].pathway_stats + pin = Pin.get_from(self.sqs_client) + buckets = pin.tracer.data_streams_processor._buckets + assert len(buckets) == 1 + first = list(buckets.values())[0].pathway_stats - assert ( - first[("direction:out,topic:Test,type:sqs", 15309751356108160802, 0)].full_pathway_latency._count - >= 1 - ) - assert first[("direction:out,topic:Test,type:sqs", 15309751356108160802, 0)].edge_latency._count >= 1 - assert ( - first[("direction:in,topic:Test,type:sqs", 3569019635468821892, 0)].full_pathway_latency._count >= 1 - ) - assert first[("direction:in,topic:Test,type:sqs", 3569019635468821892, 0)].edge_latency._count >= 1 + assert ( + first[("direction:out,topic:Test,type:sqs", 15309751356108160802, 0)].full_pathway_latency._count >= 1 + ) + assert first[("direction:out,topic:Test,type:sqs", 15309751356108160802, 0)].edge_latency._count >= 1 + assert first[("direction:in,topic:Test,type:sqs", 3569019635468821892, 0)].full_pathway_latency._count >= 1 + assert first[("direction:in,topic:Test,type:sqs", 3569019635468821892, 0)].edge_latency._count >= 1 @mock_lambda def test_lambda_client(self): @@ -1382,108 +1251,9 @@ def test_lambda_client(self): assert span.resource == "lambda.listfunctions" assert span.get_tag("params.ClientContext") is None - @mock_lambda - def test_lambda_invoke_no_context_client(self): - # DEV: Test only deprecated behavior as we need to inspect span tags for ClientContext - with self.override_config("botocore", dict(tag_all_params=True)): - lamb = self.session.create_client("lambda", region_name="us-west-2", endpoint_url="http://localhost:4566") - lamb.create_function( - FunctionName="ironmaiden", - Runtime="python3.7", - Role="test-iam-role", - Handler="lambda_function.lambda_handler", - Code={ - "ZipFile": get_zip_lambda(), - }, - Publish=True, - Timeout=30, - MemorySize=128, - ) - - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(lamb) - - lamb.invoke( - FunctionName="ironmaiden", - Payload=json.dumps({}), - ) - - spans = self.get_spans() - assert spans - span = spans[0] - - assert len(spans) == 1 - assert span.get_tag("aws.region") == "us-west-2" - assert span.get_tag("region") == "us-west-2" - assert span.get_tag("aws_service") == "lambda" - assert span.get_tag("functionname") == "ironmaiden" - assert span.get_tag("aws.operation") == "Invoke" - assert span.get_tag("component") == "botocore" - assert span.get_tag("span.kind"), "client" - assert_is_measured(span) - assert_span_http_status_code(span, 200) - assert span.service == "test-botocore-tracing.lambda" - assert span.resource == "lambda.invoke" - context_b64 = span.get_tag("params.ClientContext") - context_json = base64.b64decode(context_b64.encode()).decode() - context_obj = json.loads(context_json) - - assert context_obj["custom"][HTTP_HEADER_TRACE_ID] == str(span.trace_id) - assert context_obj["custom"][HTTP_HEADER_PARENT_ID] == str(span.span_id) - - lamb.delete_function(FunctionName="ironmaiden") - - @mock_lambda - def test_lambda_invoke_with_old_style_trace_propagation(self): - # DEV: Test only deprecated behavior as we need to inspect span tags for ClientContext - with self.override_config("botocore", dict(invoke_with_legacy_context=True, tag_all_params=True)): - lamb = self.session.create_client("lambda", region_name="us-west-2", endpoint_url="http://localhost:4566") - lamb.create_function( - FunctionName="ironmaiden", - Runtime="python3.7", - Role="test-iam-role", - Handler="lambda_function.lambda_handler", - Code={ - "ZipFile": get_zip_lambda(), - }, - Publish=True, - Timeout=30, - MemorySize=128, - ) - - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(lamb) - - lamb.invoke( - FunctionName="ironmaiden", - Payload=json.dumps({}), - ) - - spans = self.get_spans() - assert spans - span = spans[0] - - assert len(spans) == 1 - assert span.get_tag("aws.region") == "us-west-2" - assert span.get_tag("region") == "us-west-2" - assert span.get_tag("aws.operation") == "Invoke" - assert span.get_tag("component") == "botocore" - assert span.get_tag("span.kind"), "client" - assert_is_measured(span) - assert_span_http_status_code(span, 200) - assert span.service == "test-botocore-tracing.lambda" - assert span.resource == "lambda.invoke" - context_b64 = span.get_tag("params.ClientContext") - context_json = base64.b64decode(context_b64.encode()).decode() - context_obj = json.loads(context_json) - - assert context_obj["custom"]["_datadog"][HTTP_HEADER_TRACE_ID] == str(span.trace_id) - assert context_obj["custom"]["_datadog"][HTTP_HEADER_PARENT_ID] == str(span.span_id) - - lamb.delete_function(FunctionName="ironmaiden") - @mock_lambda def test_lambda_invoke_distributed_tracing_off(self): - # DEV: Test only deprecated behavior as we need to inspect span tags for ClientContext - with self.override_config("botocore", dict(distributed_tracing=False, tag_all_params=True)): + with self.override_config("botocore", dict(distributed_tracing=False)): lamb = self.session.create_client("lambda", region_name="us-west-2", endpoint_url="http://localhost:4566") lamb.create_function( FunctionName="ironmaiden", @@ -1522,57 +1292,6 @@ def test_lambda_invoke_distributed_tracing_off(self): assert span.get_tag("params.ClientContext") is None lamb.delete_function(FunctionName="ironmaiden") - @mock_lambda - def test_lambda_invoke_with_context_client(self): - # DEV: Test only deprecated behavior as we need to inspect span tags for ClientContext - with self.override_config("botocore", dict(tag_all_params=True)): - lamb = self.session.create_client("lambda", region_name="us-west-2", endpoint_url="http://localhost:4566") - lamb.create_function( - FunctionName="megadeth", - Runtime="python3.7", - Role="test-iam-role", - Handler="lambda_function.lambda_handler", - Code={ - "ZipFile": get_zip_lambda(), - }, - Publish=True, - Timeout=30, - MemorySize=128, - ) - client_context = base64.b64encode(json.dumps({"custom": {"foo": "bar"}}).encode()).decode() - - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(lamb) - - lamb.invoke( - FunctionName="megadeth", - ClientContext=client_context, - Payload=json.dumps({}), - ) - - spans = self.get_spans() - assert spans - span = spans[0] - - assert len(spans) == 1 - assert span.get_tag("aws.region") == "us-west-2" - assert span.get_tag("region") == "us-west-2" - assert span.get_tag("aws.operation") == "Invoke" - assert span.get_tag("component") == "botocore" - assert span.get_tag("span.kind"), "client" - assert_is_measured(span) - assert_span_http_status_code(span, 200) - assert span.service == "test-botocore-tracing.lambda" - assert span.resource == "lambda.invoke" - context_b64 = span.get_tag("params.ClientContext") - context_json = base64.b64decode(context_b64.encode()).decode() - context_obj = json.loads(context_json) - - assert context_obj["custom"]["foo"] == "bar" - assert context_obj["custom"][HTTP_HEADER_TRACE_ID] == str(span.trace_id) - assert context_obj["custom"][HTTP_HEADER_PARENT_ID] == str(span.span_id) - - lamb.delete_function(FunctionName="megadeth") - @mock_lambda def test_lambda_invoke_bad_context_client(self): lamb = self.session.create_client("lambda", region_name="us-west-2", endpoint_url="http://localhost:4566") @@ -1801,255 +1520,243 @@ def test_schematized_unspecified_service_lambda_client_v1(self): @mock_events def test_eventbridge_single_entry_trace_injection(self): - # DEV: Only check deprecated all params behavior - with self.override_config("botocore", dict(tag_all_params=True)): - bridge = self.session.create_client("events", region_name="us-east-1", endpoint_url="http://localhost:4566") - bridge.create_event_bus(Name="a-test-bus") + bridge = self.session.create_client("events", region_name="us-east-1", endpoint_url="http://localhost:4566") + bridge.create_event_bus(Name="a-test-bus") - entries = [ - { - "Source": "some-event-source", - "DetailType": "some-event-detail-type", - "Detail": json.dumps({"foo": "bar"}), - "EventBusName": "a-test-bus", - } - ] - bridge.put_rule( - Name="a-test-bus-rule", - EventBusName="a-test-bus", - EventPattern="""{"source": [{"prefix": ""}]}""", - State="ENABLED", - ) + entries = [ + { + "Source": "some-event-source", + "DetailType": "some-event-detail-type", + "Detail": json.dumps({"foo": "bar"}), + "EventBusName": "a-test-bus", + } + ] + bridge.put_rule( + Name="a-test-bus-rule", + EventBusName="a-test-bus", + EventPattern="""{"source": [{"prefix": ""}]}""", + State="ENABLED", + ) - bridge.list_rules() - queue_url = self.sqs_test_queue["QueueUrl"] - bridge.put_targets( - Rule="a-test-bus-rule", - Targets=[{"Id": "a-test-bus-rule-target", "Arn": "arn:aws:sqs:us-east-1:000000000000:Test"}], - ) + bridge.list_rules() + queue_url = self.sqs_test_queue["QueueUrl"] + bridge.put_targets( + Rule="a-test-bus-rule", + Targets=[{"Id": "a-test-bus-rule-target", "Arn": "arn:aws:sqs:us-east-1:000000000000:Test"}], + ) - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(bridge) - bridge.put_events(Entries=entries) + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(bridge) + bridge.put_events(Entries=entries) - messages = self.sqs_client.receive_message(QueueUrl=queue_url, WaitTimeSeconds=2) + messages = self.sqs_client.receive_message(QueueUrl=queue_url, WaitTimeSeconds=2) - bridge.delete_event_bus(Name="a-test-bus") + bridge.delete_event_bus(Name="a-test-bus") - spans = self.get_spans() - assert spans - assert len(spans) == 2 - span = spans[0] - str_entries = span.get_tag("params.Entries") - put_rule_span = spans[1] - assert put_rule_span.get_tag("rulename") == "a-test-bus" - assert put_rule_span.get_tag("aws_service") == "events" - assert put_rule_span.get_tag("region") == "us-east-1" - assert str_entries is None - - message = messages["Messages"][0] - body = message.get("Body") - assert body is not None - # body_obj = ast.literal_eval(body) - body_obj = json.loads(body) - detail = body_obj.get("detail") - headers = detail.get("_datadog") - assert headers is not None - assert headers[HTTP_HEADER_TRACE_ID] == str(span.trace_id) - assert headers[HTTP_HEADER_PARENT_ID] == str(span.span_id) + spans = self.get_spans() + assert spans + assert len(spans) == 2 + span = spans[0] + str_entries = span.get_tag("params.Entries") + put_rule_span = spans[1] + assert put_rule_span.get_tag("rulename") == "a-test-bus" + assert put_rule_span.get_tag("aws_service") == "events" + assert put_rule_span.get_tag("region") == "us-east-1" + assert str_entries is None + + message = messages["Messages"][0] + body = message.get("Body") + assert body is not None + # body_obj = ast.literal_eval(body) + body_obj = json.loads(body) + detail = body_obj.get("detail") + headers = detail.get("_datadog") + assert headers is not None + assert headers[HTTP_HEADER_TRACE_ID] == str(span.trace_id) + assert headers[HTTP_HEADER_PARENT_ID] == str(span.span_id) @mock_events def test_eventbridge_multiple_entries_trace_injection(self): - # DEV: Only check deprecated all params behavior - with self.override_config("botocore", dict(tag_all_params=True)): - bridge = self.session.create_client("events", region_name="us-east-1", endpoint_url="http://localhost:4566") - bridge.create_event_bus(Name="a-test-bus") + bridge = self.session.create_client("events", region_name="us-east-1", endpoint_url="http://localhost:4566") + bridge.create_event_bus(Name="a-test-bus") - entries = [ - { - "Source": "another-event-source", - "DetailType": "a-different-event-detail-type", - "Detail": json.dumps({"abc": "xyz"}), - "EventBusName": "a-test-bus", - }, - { - "Source": "some-event-source", - "DetailType": "some-event-detail-type", - "Detail": json.dumps({"foo": "bar"}), - "EventBusName": "a-test-bus", - }, - ] - bridge.put_rule( - Name="a-test-bus-rule", - EventBusName="a-test-bus", - EventPattern="""{"source": [{"prefix": ""}]}""", - State="ENABLED", - ) + entries = [ + { + "Source": "another-event-source", + "DetailType": "a-different-event-detail-type", + "Detail": json.dumps({"abc": "xyz"}), + "EventBusName": "a-test-bus", + }, + { + "Source": "some-event-source", + "DetailType": "some-event-detail-type", + "Detail": json.dumps({"foo": "bar"}), + "EventBusName": "a-test-bus", + }, + ] + bridge.put_rule( + Name="a-test-bus-rule", + EventBusName="a-test-bus", + EventPattern="""{"source": [{"prefix": ""}]}""", + State="ENABLED", + ) - bridge.list_rules() - queue_url = self.sqs_test_queue["QueueUrl"] - bridge.put_targets( - Rule="a-test-bus-rule", - Targets=[{"Id": "a-test-bus-rule-target", "Arn": "arn:aws:sqs:us-east-1:000000000000:Test"}], - ) + bridge.list_rules() + queue_url = self.sqs_test_queue["QueueUrl"] + bridge.put_targets( + Rule="a-test-bus-rule", + Targets=[{"Id": "a-test-bus-rule-target", "Arn": "arn:aws:sqs:us-east-1:000000000000:Test"}], + ) - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(bridge) - bridge.put_events(Entries=entries) + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(bridge) + bridge.put_events(Entries=entries) - messages = self.sqs_client.receive_message(QueueUrl=queue_url, WaitTimeSeconds=2) + messages = self.sqs_client.receive_message(QueueUrl=queue_url, WaitTimeSeconds=2) - bridge.delete_event_bus(Name="a-test-bus") + bridge.delete_event_bus(Name="a-test-bus") - spans = self.get_spans() - assert spans - assert len(spans) == 2 - span = spans[0] - str_entries = span.get_tag("params.Entries") - assert str_entries is None - - message = messages["Messages"][0] - body = message.get("Body") - assert body is not None - body_obj = json.loads(body) - detail = body_obj.get("detail") - headers = detail.get("_datadog") - assert headers is not None - assert headers[HTTP_HEADER_TRACE_ID] == str(span.trace_id) - assert headers[HTTP_HEADER_PARENT_ID] == str(span.span_id) + spans = self.get_spans() + assert spans + assert len(spans) == 2 + span = spans[0] + str_entries = span.get_tag("params.Entries") + assert str_entries is None + + message = messages["Messages"][0] + body = message.get("Body") + assert body is not None + body_obj = json.loads(body) + detail = body_obj.get("detail") + headers = detail.get("_datadog") + assert headers is not None + assert headers[HTTP_HEADER_TRACE_ID] == str(span.trace_id) + assert headers[HTTP_HEADER_PARENT_ID] == str(span.span_id) - # the following doesn't work due to an issue in moto/localstack where - # an SQS message is generated per put_events rather than per event sent + # the following doesn't work due to an issue in moto/localstack where + # an SQS message is generated per put_events rather than per event sent - # message = messages["Messages"][1] - # body = message.get("Body") - # assert body is not None - # body_obj = json.loads(body) - # detail = body_obj.get("detail") - # headers = detail.get("_datadog") - # assert headers is not None - # assert headers[HTTP_HEADER_TRACE_ID] == str(span.trace_id) - # assert headers[HTTP_HEADER_PARENT_ID] == str(span.span_id) + # message = messages["Messages"][1] + # body = message.get("Body") + # assert body is not None + # body_obj = json.loads(body) + # detail = body_obj.get("detail") + # headers = detail.get("_datadog") + # assert headers is not None + # assert headers[HTTP_HEADER_TRACE_ID] == str(span.trace_id) + # assert headers[HTTP_HEADER_PARENT_ID] == str(span.span_id) @mock_kms def test_kms_client(self): - # DEV: We can ignore the params tags as none currently exists. Test all params for deprecated exclusion. - with self.override_config("botocore", dict(tag_all_params=True)): - kms = self.session.create_client("kms", region_name="us-east-1") - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(kms) + kms = self.session.create_client("kms", region_name="us-east-1") + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(kms) - kms.list_keys(Limit=21) + kms.list_keys(Limit=21) - spans = self.get_spans() - assert spans - span = spans[0] - assert len(spans) == 1 - assert span.get_tag("aws.region") == "us-east-1" - assert span.get_tag("region") == "us-east-1" - assert span.get_tag("aws.operation") == "ListKeys" - assert span.get_tag("component") == "botocore" - assert span.get_tag("span.kind"), "client" - assert_is_measured(span) - assert_span_http_status_code(span, 200) - assert span.service == "test-botocore-tracing.kms" - assert span.resource == "kms.listkeys" + spans = self.get_spans() + assert spans + span = spans[0] + assert len(spans) == 1 + assert span.get_tag("aws.region") == "us-east-1" + assert span.get_tag("region") == "us-east-1" + assert span.get_tag("aws.operation") == "ListKeys" + assert span.get_tag("component") == "botocore" + assert span.get_tag("span.kind"), "client" + assert_is_measured(span) + assert_span_http_status_code(span, 200) + assert span.service == "test-botocore-tracing.kms" + assert span.resource == "kms.listkeys" - # checking for protection on sts against security leak - assert span.get_tag("params") is None + # checking for protection on sts against security leak + assert span.get_tag("params") is None @mock_kms @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_SERVICE="mysvc")) def test_schematized_kms_client_default(self): - with self.override_config("botocore", dict(tag_all_params=True)): - kms = self.session.create_client("kms", region_name="us-east-1") - Pin.get_from(kms).clone(tracer=self.tracer).onto(kms) + kms = self.session.create_client("kms", region_name="us-east-1") + Pin.get_from(kms).clone(tracer=self.tracer).onto(kms) - kms.list_keys(Limit=21) + kms.list_keys(Limit=21) - spans = self.get_spans() - assert spans - span = spans[0] - assert len(spans) == 1 - assert span.service == "aws.kms" - assert span.name == "kms.command" + spans = self.get_spans() + assert spans + span = spans[0] + assert len(spans) == 1 + assert span.service == "aws.kms" + assert span.name == "kms.command" @mock_kms @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_SERVICE="mysvc", DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v0")) def test_schematized_kms_client_v0(self): - with self.override_config("botocore", dict(tag_all_params=True)): - kms = self.session.create_client("kms", region_name="us-east-1") - Pin.get_from(kms).clone(tracer=self.tracer).onto(kms) + kms = self.session.create_client("kms", region_name="us-east-1") + Pin.get_from(kms).clone(tracer=self.tracer).onto(kms) - kms.list_keys(Limit=21) + kms.list_keys(Limit=21) - spans = self.get_spans() - assert spans - span = spans[0] - assert len(spans) == 1 - assert span.service == "aws.kms" - assert span.name == "kms.command" + spans = self.get_spans() + assert spans + span = spans[0] + assert len(spans) == 1 + assert span.service == "aws.kms" + assert span.name == "kms.command" @mock_kms @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_SERVICE="mysvc", DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v1")) def test_schematized_kms_client_v1(self): - with self.override_config("botocore", dict(tag_all_params=True)): - kms = self.session.create_client("kms", region_name="us-east-1") - Pin.get_from(kms).clone(tracer=self.tracer).onto(kms) + kms = self.session.create_client("kms", region_name="us-east-1") + Pin.get_from(kms).clone(tracer=self.tracer).onto(kms) - kms.list_keys(Limit=21) + kms.list_keys(Limit=21) - spans = self.get_spans() - assert spans - span = spans[0] - assert len(spans) == 1 - assert span.service == "mysvc" - assert span.name == "aws.kms.request" + spans = self.get_spans() + assert spans + span = spans[0] + assert len(spans) == 1 + assert span.service == "mysvc" + assert span.name == "aws.kms.request" @mock_kms @TracerTestCase.run_in_subprocess(env_overrides=dict()) def test_schematized_unspecified_service_kms_client_default(self): - with self.override_config("botocore", dict(tag_all_params=True)): - kms = self.session.create_client("kms", region_name="us-east-1") - Pin.get_from(kms).clone(tracer=self.tracer).onto(kms) + kms = self.session.create_client("kms", region_name="us-east-1") + Pin.get_from(kms).clone(tracer=self.tracer).onto(kms) - kms.list_keys(Limit=21) + kms.list_keys(Limit=21) - spans = self.get_spans() - assert spans - span = spans[0] - assert len(spans) == 1 - assert span.service == "aws.kms" - assert span.name == "kms.command" + spans = self.get_spans() + assert spans + span = spans[0] + assert len(spans) == 1 + assert span.service == "aws.kms" + assert span.name == "kms.command" @mock_kms @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v0")) def test_schematized_unspecified_service_kms_client_v0(self): - with self.override_config("botocore", dict(tag_all_params=True)): - kms = self.session.create_client("kms", region_name="us-east-1") - Pin.get_from(kms).clone(tracer=self.tracer).onto(kms) + kms = self.session.create_client("kms", region_name="us-east-1") + Pin.get_from(kms).clone(tracer=self.tracer).onto(kms) - kms.list_keys(Limit=21) + kms.list_keys(Limit=21) - spans = self.get_spans() - assert spans - span = spans[0] - assert len(spans) == 1 - assert span.service == "aws.kms" - assert span.name == "kms.command" + spans = self.get_spans() + assert spans + span = spans[0] + assert len(spans) == 1 + assert span.service == "aws.kms" + assert span.name == "kms.command" @mock_kms @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA="v1")) def test_schematized_unspecified_service_kms_client_v1(self): - with self.override_config("botocore", dict(tag_all_params=True)): - kms = self.session.create_client("kms", region_name="us-east-1") - Pin.get_from(kms).clone(tracer=self.tracer).onto(kms) + kms = self.session.create_client("kms", region_name="us-east-1") + Pin.get_from(kms).clone(tracer=self.tracer).onto(kms) - kms.list_keys(Limit=21) + kms.list_keys(Limit=21) - spans = self.get_spans() - assert spans - span = spans[0] - assert len(spans) == 1 - assert span.service == DEFAULT_SPAN_SERVICE_NAME - assert span.name == "aws.kms.request" + spans = self.get_spans() + assert spans + span = spans[0] + assert len(spans) == 1 + assert span.service == DEFAULT_SPAN_SERVICE_NAME + assert span.name == "aws.kms.request" @mock_ec2 def test_traced_client_ot(self): @@ -2104,50 +1811,48 @@ def test_stubber_no_response_metadata(self): @mock_firehose def test_firehose_no_records_arg(self): - # DEV: This test only applies for deprecated all params - with self.override_config("botocore", dict(tag_all_params=True)): - firehose = self.session.create_client("firehose", region_name="us-west-2") - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(firehose) - - stream_name = "test-stream" - account_id = "test-account" - - firehose.create_delivery_stream( - DeliveryStreamName=stream_name, - RedshiftDestinationConfiguration={ + firehose = self.session.create_client("firehose", region_name="us-west-2") + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(firehose) + + stream_name = "test-stream" + account_id = "test-account" + + firehose.create_delivery_stream( + DeliveryStreamName=stream_name, + RedshiftDestinationConfiguration={ + "RoleARN": "arn:aws:iam::{}:role/firehose_delivery_role".format(account_id), + "ClusterJDBCURL": "jdbc:redshift://host.amazonaws.com:5439/database", + "CopyCommand": { + "DataTableName": "outputTable", + "CopyOptions": "CSV DELIMITER ',' NULL '\\0'", + }, + "Username": "username", + "Password": "password", + "S3Configuration": { "RoleARN": "arn:aws:iam::{}:role/firehose_delivery_role".format(account_id), - "ClusterJDBCURL": "jdbc:redshift://host.amazonaws.com:5439/database", - "CopyCommand": { - "DataTableName": "outputTable", - "CopyOptions": "CSV DELIMITER ',' NULL '\\0'", - }, - "Username": "username", - "Password": "password", - "S3Configuration": { - "RoleARN": "arn:aws:iam::{}:role/firehose_delivery_role".format(account_id), - "BucketARN": "arn:aws:s3:::kinesis-test", - "Prefix": "myFolder/", - "BufferingHints": {"SizeInMBs": 123, "IntervalInSeconds": 124}, - "CompressionFormat": "UNCOMPRESSED", - }, + "BucketARN": "arn:aws:s3:::kinesis-test", + "Prefix": "myFolder/", + "BufferingHints": {"SizeInMBs": 123, "IntervalInSeconds": 124}, + "CompressionFormat": "UNCOMPRESSED", }, - ) + }, + ) - firehose.put_record_batch( - DeliveryStreamName=stream_name, - Records=[{"Data": "some data"}], - ) + firehose.put_record_batch( + DeliveryStreamName=stream_name, + Records=[{"Data": "some data"}], + ) - spans = self.get_spans() + spans = self.get_spans() - assert spans - assert len(spans) == 2 - assert all(span.name == "firehose.command" for span in spans) + assert spans + assert len(spans) == 2 + assert all(span.name == "firehose.command" for span in spans) - delivery_stream_span, put_record_batch_span = spans - assert delivery_stream_span.get_tag("aws.operation") == "CreateDeliveryStream" - assert put_record_batch_span.get_tag("aws.operation") == "PutRecordBatch" - assert put_record_batch_span.get_tag("params.Records") is None + delivery_stream_span, put_record_batch_span = spans + assert delivery_stream_span.get_tag("aws.operation") == "CreateDeliveryStream" + assert put_record_batch_span.get_tag("aws.operation") == "PutRecordBatch" + assert put_record_batch_span.get_tag("params.Records") is None @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_BOTOCORE_DISTRIBUTED_TRACING="true")) def test_distributed_tracing_env_override(self): @@ -2260,215 +1965,202 @@ def test_sns_no_params(self): span = self._test_sns() assert span.get_tag("aws.sns.topic_arn") is None - @mock_sns - @mock_sqs - def test_sns_all_params(self): - with self.override_config("botocore", dict(tag_all_params=True)): - span = self._test_sns() - assert span.get_tag("params.MessageBody") is None - @mock_sns @mock_sqs def test_sns_send_message_trace_injection_with_no_message_attributes(self): - # DEV: This test expects MessageAttributes to be included as span tags which has been deprecated. # TODO: Move away from inspecting MessageAttributes using span tag - with self.override_config("botocore", dict(tag_all_params=True)): - sns = self.session.create_client("sns", region_name="us-east-1", endpoint_url="http://localhost:4566") + sns = self.session.create_client("sns", region_name="us-east-1", endpoint_url="http://localhost:4566") - topic = sns.create_topic(Name="testTopic") + topic = sns.create_topic(Name="testTopic") - topic_arn = topic["TopicArn"] - sqs_url = self.sqs_test_queue["QueueUrl"] - url_parts = sqs_url.split("/") - sqs_arn = "arn:aws:sqs:{}:{}:{}".format("us-east-1", url_parts[-2], url_parts[-1]) - sns.subscribe(TopicArn=topic_arn, Protocol="sqs", Endpoint=sqs_arn) + topic_arn = topic["TopicArn"] + sqs_url = self.sqs_test_queue["QueueUrl"] + url_parts = sqs_url.split("/") + sqs_arn = "arn:aws:sqs:{}:{}:{}".format("us-east-1", url_parts[-2], url_parts[-1]) + sns.subscribe(TopicArn=topic_arn, Protocol="sqs", Endpoint=sqs_arn) - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(sns) + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(sns) - sns.publish(TopicArn=topic_arn, Message="test") - spans = self.get_spans() + sns.publish(TopicArn=topic_arn, Message="test") + spans = self.get_spans() - # get SNS messages via SQS - response = self.sqs_client.receive_message(QueueUrl=self.sqs_test_queue["QueueUrl"], WaitTimeSeconds=2) + # get SNS messages via SQS + response = self.sqs_client.receive_message(QueueUrl=self.sqs_test_queue["QueueUrl"], WaitTimeSeconds=2) - # clean up resources - sns.delete_topic(TopicArn=topic_arn) + # clean up resources + sns.delete_topic(TopicArn=topic_arn) - # check if the appropriate span was generated - assert spans - span = spans[0] - assert len(spans) == 2 - assert span.get_tag("aws.region") == "us-east-1" - assert span.get_tag("region") == "us-east-1" - assert span.get_tag("aws.operation") == "Publish" - assert span.get_tag("params.MessageBody") is None - assert span.get_tag("component") == "botocore" - assert span.get_tag("span.kind"), "client" - assert_is_measured(span) - assert_span_http_status_code(span, 200) - assert span.service == "test-botocore-tracing.sns" - assert span.resource == "sns.publish" - trace_json = span.get_tag("params.MessageAttributes._datadog.StringValue") - assert trace_json is None + # check if the appropriate span was generated + assert spans + span = spans[0] + assert len(spans) == 2 + assert span.get_tag("aws.region") == "us-east-1" + assert span.get_tag("region") == "us-east-1" + assert span.get_tag("aws.operation") == "Publish" + assert span.get_tag("params.MessageBody") is None + assert span.get_tag("component") == "botocore" + assert span.get_tag("span.kind"), "client" + assert_is_measured(span) + assert_span_http_status_code(span, 200) + assert span.service == "test-botocore-tracing.sns" + assert span.resource == "sns.publish" + trace_json = span.get_tag("params.MessageAttributes._datadog.StringValue") + assert trace_json is None - # receive message using SQS and ensure headers are present - assert len(response["Messages"]) == 1 - msg = response["Messages"][0] - assert msg is not None - msg_body = json.loads(msg["Body"]) - msg_str = msg_body["Message"] - assert msg_str == "test" - msg_attr = msg_body["MessageAttributes"] - assert msg_attr.get("_datadog") is not None - assert msg_attr["_datadog"]["Type"] == "Binary" - datadog_value_decoded = base64.b64decode(msg_attr["_datadog"]["Value"]) - headers = json.loads(datadog_value_decoded.decode()) - assert headers is not None - assert headers[HTTP_HEADER_TRACE_ID] == str(span.trace_id) - assert headers[HTTP_HEADER_PARENT_ID] == str(span.span_id) + # receive message using SQS and ensure headers are present + assert len(response["Messages"]) == 1 + msg = response["Messages"][0] + assert msg is not None + msg_body = json.loads(msg["Body"]) + msg_str = msg_body["Message"] + assert msg_str == "test" + msg_attr = msg_body["MessageAttributes"] + assert msg_attr.get("_datadog") is not None + assert msg_attr["_datadog"]["Type"] == "Binary" + datadog_value_decoded = base64.b64decode(msg_attr["_datadog"]["Value"]) + headers = json.loads(datadog_value_decoded.decode()) + assert headers is not None + assert headers[HTTP_HEADER_TRACE_ID] == str(span.trace_id) + assert headers[HTTP_HEADER_PARENT_ID] == str(span.span_id) @mock_sns @mock_sqs @pytest.mark.xfail(strict=False) # FIXME: flaky test def test_sns_send_message_trace_injection_with_message_attributes(self): - # DEV: This test expects MessageAttributes to be included as span tags which has been deprecated. # TODO: Move away from inspecting MessageAttributes using span tag - with self.override_config("botocore", dict(tag_all_params=True)): - sns = self.session.create_client("sns", region_name="us-east-1", endpoint_url="http://localhost:4566") + sns = self.session.create_client("sns", region_name="us-east-1", endpoint_url="http://localhost:4566") - topic = sns.create_topic(Name="testTopic") + topic = sns.create_topic(Name="testTopic") - topic_arn = topic["TopicArn"] - sqs_url = self.sqs_test_queue["QueueUrl"] - sns.subscribe(TopicArn=topic_arn, Protocol="sqs", Endpoint=sqs_url) + topic_arn = topic["TopicArn"] + sqs_url = self.sqs_test_queue["QueueUrl"] + sns.subscribe(TopicArn=topic_arn, Protocol="sqs", Endpoint=sqs_url) - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(sns) + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(sns) - message_attributes = { - "one": {"DataType": "String", "StringValue": "one"}, - "two": {"DataType": "String", "StringValue": "two"}, - "three": {"DataType": "String", "StringValue": "three"}, - "four": {"DataType": "String", "StringValue": "four"}, - "five": {"DataType": "String", "StringValue": "five"}, - "six": {"DataType": "String", "StringValue": "six"}, - "seven": {"DataType": "String", "StringValue": "seven"}, - "eight": {"DataType": "String", "StringValue": "eight"}, - "nine": {"DataType": "String", "StringValue": "nine"}, - } + message_attributes = { + "one": {"DataType": "String", "StringValue": "one"}, + "two": {"DataType": "String", "StringValue": "two"}, + "three": {"DataType": "String", "StringValue": "three"}, + "four": {"DataType": "String", "StringValue": "four"}, + "five": {"DataType": "String", "StringValue": "five"}, + "six": {"DataType": "String", "StringValue": "six"}, + "seven": {"DataType": "String", "StringValue": "seven"}, + "eight": {"DataType": "String", "StringValue": "eight"}, + "nine": {"DataType": "String", "StringValue": "nine"}, + } - sns.publish(TopicArn=topic_arn, Message="test", MessageAttributes=message_attributes) - spans = self.get_spans() + sns.publish(TopicArn=topic_arn, Message="test", MessageAttributes=message_attributes) + spans = self.get_spans() - # get SNS messages via SQS - response = self.sqs_client.receive_message( - QueueUrl=self.sqs_test_queue["QueueUrl"], - MessageAttributeNames=["_datadog"], - WaitTimeSeconds=2, - ) + # get SNS messages via SQS + response = self.sqs_client.receive_message( + QueueUrl=self.sqs_test_queue["QueueUrl"], + MessageAttributeNames=["_datadog"], + WaitTimeSeconds=2, + ) - # clean up resources - sns.delete_topic(TopicArn=topic_arn) + # clean up resources + sns.delete_topic(TopicArn=topic_arn) - # check if the appropriate span was generated - assert spans - span = spans[0] - assert len(spans) == 2 - assert span.get_tag("aws.region") == "us-east-1" - assert span.get_tag("region") == "us-east-1" - assert span.get_tag("aws.operation") == "Publish" - assert span.get_tag("params.MessageBody") is None - assert span.get_tag("component") == "botocore" - assert span.get_tag("span.kind"), "client" - assert_is_measured(span) - assert_span_http_status_code(span, 200) - assert span.service == "test-botocore-tracing.sns" - assert span.resource == "sns.publish" - trace_json = span.get_tag("params.MessageAttributes._datadog.StringValue") - assert trace_json is None + # check if the appropriate span was generated + assert spans + span = spans[0] + assert len(spans) == 2 + assert span.get_tag("aws.region") == "us-east-1" + assert span.get_tag("region") == "us-east-1" + assert span.get_tag("aws.operation") == "Publish" + assert span.get_tag("params.MessageBody") is None + assert span.get_tag("component") == "botocore" + assert span.get_tag("span.kind"), "client" + assert_is_measured(span) + assert_span_http_status_code(span, 200) + assert span.service == "test-botocore-tracing.sns" + assert span.resource == "sns.publish" + trace_json = span.get_tag("params.MessageAttributes._datadog.StringValue") + assert trace_json is None - # receive message using SQS and ensure headers are present - assert len(response["Messages"]) == 1 - msg = response["Messages"][0] - assert msg is not None - msg_body = json.loads(msg["Body"]) - msg_str = msg_body["Message"] - assert msg_str == "test" - msg_attr = msg_body["MessageAttributes"] - assert msg_attr.get("_datadog") is not None - assert msg_attr["_datadog"]["Type"] == "Binary" - datadog_value_decoded = base64.b64decode(msg_attr["_datadog"]["Value"]) - headers = json.loads(datadog_value_decoded.decode()) - assert headers is not None - assert headers[HTTP_HEADER_TRACE_ID] == str(span.trace_id) - assert headers[HTTP_HEADER_PARENT_ID] == str(span.span_id) + # receive message using SQS and ensure headers are present + assert len(response["Messages"]) == 1 + msg = response["Messages"][0] + assert msg is not None + msg_body = json.loads(msg["Body"]) + msg_str = msg_body["Message"] + assert msg_str == "test" + msg_attr = msg_body["MessageAttributes"] + assert msg_attr.get("_datadog") is not None + assert msg_attr["_datadog"]["Type"] == "Binary" + datadog_value_decoded = base64.b64decode(msg_attr["_datadog"]["Value"]) + headers = json.loads(datadog_value_decoded.decode()) + assert headers is not None + assert headers[HTTP_HEADER_TRACE_ID] == str(span.trace_id) + assert headers[HTTP_HEADER_PARENT_ID] == str(span.span_id) @mock_sns @mock_sqs def test_sns_send_message_trace_injection_with_max_message_attributes(self): - # DEV: This test expects MessageAttributes to be included as span tags which has been deprecated. # TODO: Move away from inspecting MessageAttributes using span tag - with self.override_config("botocore", dict(tag_all_params=True)): - region = "us-east-1" - sns = self.session.create_client("sns", region_name=region, endpoint_url="http://localhost:4566") + region = "us-east-1" + sns = self.session.create_client("sns", region_name=region, endpoint_url="http://localhost:4566") - topic = sns.create_topic(Name="testTopic") + topic = sns.create_topic(Name="testTopic") - topic_arn = topic["TopicArn"] - sqs_url = self.sqs_test_queue["QueueUrl"] - url_parts = sqs_url.split("/") - sqs_arn = "arn:aws:sqs:{}:{}:{}".format(region, url_parts[-2], url_parts[-1]) - sns.subscribe(TopicArn=topic_arn, Protocol="sqs", Endpoint=sqs_arn) + topic_arn = topic["TopicArn"] + sqs_url = self.sqs_test_queue["QueueUrl"] + url_parts = sqs_url.split("/") + sqs_arn = "arn:aws:sqs:{}:{}:{}".format(region, url_parts[-2], url_parts[-1]) + sns.subscribe(TopicArn=topic_arn, Protocol="sqs", Endpoint=sqs_arn) - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(sns) + Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(sns) - message_attributes = { - "one": {"DataType": "String", "StringValue": "one"}, - "two": {"DataType": "String", "StringValue": "two"}, - "three": {"DataType": "String", "StringValue": "three"}, - "four": {"DataType": "String", "StringValue": "four"}, - "five": {"DataType": "String", "StringValue": "five"}, - "six": {"DataType": "String", "StringValue": "six"}, - "seven": {"DataType": "String", "StringValue": "seven"}, - "eight": {"DataType": "String", "StringValue": "eight"}, - "nine": {"DataType": "String", "StringValue": "nine"}, - "ten": {"DataType": "String", "StringValue": "ten"}, - } + message_attributes = { + "one": {"DataType": "String", "StringValue": "one"}, + "two": {"DataType": "String", "StringValue": "two"}, + "three": {"DataType": "String", "StringValue": "three"}, + "four": {"DataType": "String", "StringValue": "four"}, + "five": {"DataType": "String", "StringValue": "five"}, + "six": {"DataType": "String", "StringValue": "six"}, + "seven": {"DataType": "String", "StringValue": "seven"}, + "eight": {"DataType": "String", "StringValue": "eight"}, + "nine": {"DataType": "String", "StringValue": "nine"}, + "ten": {"DataType": "String", "StringValue": "ten"}, + } - sns.publish(TopicArn=topic_arn, Message="test", MessageAttributes=message_attributes) - spans = self.get_spans() + sns.publish(TopicArn=topic_arn, Message="test", MessageAttributes=message_attributes) + spans = self.get_spans() - # get SNS messages via SQS - response = self.sqs_client.receive_message(QueueUrl=self.sqs_test_queue["QueueUrl"], WaitTimeSeconds=2) + # get SNS messages via SQS + response = self.sqs_client.receive_message(QueueUrl=self.sqs_test_queue["QueueUrl"], WaitTimeSeconds=2) - # clean up resources - sns.delete_topic(TopicArn=topic_arn) + # clean up resources + sns.delete_topic(TopicArn=topic_arn) - # check if the appropriate span was generated - assert spans - span = spans[0] - assert len(spans) == 2 - assert span.get_tag("aws.region") == "us-east-1" - assert span.get_tag("region") == "us-east-1" - assert span.get_tag("aws.operation") == "Publish" - assert span.get_tag("params.MessageBody") is None - assert span.get_tag("component") == "botocore" - assert span.get_tag("span.kind"), "client" - assert_is_measured(span) - assert_span_http_status_code(span, 200) - assert span.service == "test-botocore-tracing.sns" - assert span.resource == "sns.publish" - trace_json = span.get_tag("params.MessageAttributes._datadog.StringValue") - assert trace_json is None + # check if the appropriate span was generated + assert spans + span = spans[0] + assert len(spans) == 2 + assert span.get_tag("aws.region") == "us-east-1" + assert span.get_tag("region") == "us-east-1" + assert span.get_tag("aws.operation") == "Publish" + assert span.get_tag("params.MessageBody") is None + assert span.get_tag("component") == "botocore" + assert span.get_tag("span.kind"), "client" + assert_is_measured(span) + assert_span_http_status_code(span, 200) + assert span.service == "test-botocore-tracing.sns" + assert span.resource == "sns.publish" + trace_json = span.get_tag("params.MessageAttributes._datadog.StringValue") + assert trace_json is None - # receive message using SQS and ensure headers are present - assert len(response["Messages"]) == 1 - msg = response["Messages"][0] - assert msg is not None - msg_body = json.loads(msg["Body"]) - msg_str = msg_body["Message"] - assert msg_str == "test" - msg_attr = msg_body["MessageAttributes"] - assert msg_attr.get("_datadog") is None + # receive message using SQS and ensure headers are present + assert len(response["Messages"]) == 1 + msg = response["Messages"][0] + assert msg is not None + msg_body = json.loads(msg["Body"]) + msg_str = msg_body["Message"] + assert msg_str == "test" + msg_attr = msg_body["MessageAttributes"] + assert msg_attr.get("_datadog") is None @pytest.mark.skipif( PYTHON_VERSION_INFO < (3, 6), @@ -3222,33 +2914,6 @@ def test_secretsmanager(self): assert span.get_tag("params.SecretString") is None assert span.get_tag("params.SecretBinary") is None - @unittest.skipIf(PY2, "Skipping for Python 2.7 since older moto doesn't support secretsmanager") - def test_secretsmanager_all_params(self): - with self.override_config("botocore", dict(tag_all_params=True)): - from moto import mock_secretsmanager - - with mock_secretsmanager(): - client = self.session.create_client("secretsmanager", region_name="us-east-1") - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(client) - - resp = client.create_secret(Name="/my/secrets", SecretString="supersecret-string") - assert resp["ResponseMetadata"]["HTTPStatusCode"] == 200 - - spans = self.get_spans() - assert len(spans) == 1 - span = spans[0] - - assert span.name == "secretsmanager.command" - assert span.resource == "secretsmanager.createsecret" - assert span.get_tag("params.Name") == "/my/secrets" - assert span.get_tag("aws.operation") == "CreateSecret" - assert span.get_tag("aws.region") == "us-east-1" - assert span.get_tag("region") == "us-east-1" - assert span.get_tag("aws.agent") == "botocore" - assert span.get_tag("http.status_code") == "200" - assert span.get_tag("params.SecretString") is None - assert span.get_tag("params.SecretBinary") is None - @unittest.skipIf(PY2, "Skipping for Python 2.7 since older moto doesn't support secretsmanager") def test_secretsmanager_binary(self): from moto import mock_secretsmanager @@ -3275,33 +2940,6 @@ def test_secretsmanager_binary(self): assert span.get_tag("params.SecretString") is None assert span.get_tag("params.SecretBinary") is None - @unittest.skipIf(PY2, "Skipping for Python 2.7 since older moto doesn't support secretsmanager") - def test_secretsmanager_binary_all_params(self): - with self.override_config("botocore", dict(tag_all_params=True)): - from moto import mock_secretsmanager - - with mock_secretsmanager(): - client = self.session.create_client("secretsmanager", region_name="us-east-1") - Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(client) - - resp = client.create_secret(Name="/my/secrets", SecretBinary=b"supersecret-binary") - assert resp["ResponseMetadata"]["HTTPStatusCode"] == 200 - - spans = self.get_spans() - assert len(spans) == 1 - span = spans[0] - - assert span.name == "secretsmanager.command" - assert span.resource == "secretsmanager.createsecret" - assert span.get_tag("params.Name") == "/my/secrets" - assert span.get_tag("aws.operation") == "CreateSecret" - assert span.get_tag("aws.region") == "us-east-1" - assert span.get_tag("region") == "us-east-1" - assert span.get_tag("aws.agent") == "botocore" - assert span.get_tag("http.status_code") == "200" - assert span.get_tag("params.SecretString") is None - assert span.get_tag("params.SecretBinary") is None - @TracerTestCase.run_in_subprocess(env_overrides=dict(DD_SERVICE="mysvc")) def test_schematized_secretsmanager_default(self): from moto import mock_secretsmanager diff --git a/tests/contrib/cherrypy/test_middleware.py b/tests/contrib/cherrypy/test_middleware.py index 15187a52fab..6a61a8c3878 100644 --- a/tests/contrib/cherrypy/test_middleware.py +++ b/tests/contrib/cherrypy/test_middleware.py @@ -581,7 +581,7 @@ def test(self): env["DD_SERVICE"] = "mysvc" out, err, status, pid = ddtrace_run_python_code_in_subprocess(code, env=env) assert status == 0, (err, out) - assert err == b"" + assert b"2 passed" in out @pytest.mark.parametrize("schema_version", [None, "v0", "v1"]) @@ -640,4 +640,4 @@ def test(self): env["DD_SERVICE"] = "mysvc" out, err, status, pid = ddtrace_run_python_code_in_subprocess(code, env=env) assert status == 0, (err, out) - assert err == b"" + assert b"2 passed" in out diff --git a/tests/contrib/fastapi/test_fastapi.py b/tests/contrib/fastapi/test_fastapi.py index 26dcaf6af7e..fbcfc7e9300 100644 --- a/tests/contrib/fastapi/test_fastapi.py +++ b/tests/contrib/fastapi/test_fastapi.py @@ -8,7 +8,6 @@ import pytest import ddtrace -from ddtrace import config from ddtrace.contrib.fastapi import patch as fastapi_patch from ddtrace.contrib.fastapi import unpatch as fastapi_unpatch from ddtrace.contrib.starlette.patch import patch as patch_starlette @@ -577,14 +576,6 @@ def test_subapp_snapshot(snapshot_client): assert response.status_code == 200 -@snapshot() -def test_subapp_no_aggregate_snapshot(snapshot_client): - config.fastapi["aggregate_resources"] = False - response = snapshot_client.get("/sub-app/hello/name") - assert response.status_code == 200 - config.fastapi["aggregate_resources"] = True - - @snapshot(token_override="tests.contrib.fastapi.test_fastapi.test_subapp_snapshot") def test_subapp_w_starlette_patch_snapshot(snapshot_client): # Test that patching starlette doesn't affect the spans generated diff --git a/tests/contrib/grpc/test_constants.py b/tests/contrib/grpc/test_constants.py index 0605856869e..bcd728933fe 100644 --- a/tests/contrib/grpc/test_constants.py +++ b/tests/contrib/grpc/test_constants.py @@ -3,22 +3,6 @@ import pytest -def test_deprecated(): - from ddtrace.contrib.grpc import constants as grpc_constants - - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter("always") - - assert grpc_constants.GRPC_PORT_KEY - - (warn,) = warns - assert issubclass(warn.category, DeprecationWarning) - assert ( - "ddtrace.contrib.grpc.constants.GRPC_PORT_KEY is deprecated and will be removed in version '2.0.0'." - " Use ddtrace.ext.net.TARGET_PORT instead." == str(warn.message) - ) - - def test_not_deprecated(): from ddtrace.contrib.grpc import constants as grpc_constants diff --git a/tests/contrib/logging/test_tracer_logging.py b/tests/contrib/logging/test_tracer_logging.py index 5030332e1a6..dfaeb387cfa 100644 --- a/tests/contrib/logging/test_tracer_logging.py +++ b/tests/contrib/logging/test_tracer_logging.py @@ -38,8 +38,6 @@ def assert_file_logging(expected_log, out, err, dd_trace_debug, dd_log_path): if PY2 and dd_trace_debug == "true": assert 'No handlers could be found for logger "ddtrace' in err - else: - assert err == b"" assert_file_contains_log(dd_log_path) else: @@ -177,8 +175,6 @@ def test_unrelated_logger_in_debug_with_ddtrace_run( if dd_trace_debug == "true": assert "ddtrace.commands.ddtrace_run" in str(err) # comes from ddtrace-run debug logging - else: - assert err == b"" assert_file_contains_log(tmpdir.strpath + "/" + dd_trace_log_file) @@ -208,7 +204,6 @@ def test_logs_with_basicConfig(run_python_code_in_subprocess, ddtrace_run_python ddtrace_logger = logging.getLogger('ddtrace') assert ddtrace_logger.getEffectiveLevel() == logging.WARN -assert len(ddtrace_logger.handlers) == 0 ddtrace_logger.warning('warning log') ddtrace_logger.debug('debug log') @@ -237,10 +232,10 @@ def test_warn_logs_can_go_to_file(run_python_code_in_subprocess, ddtrace_run_pyt ddtrace_logger = logging.getLogger('ddtrace') assert ddtrace_logger.getEffectiveLevel() == logging.WARN -assert len(ddtrace_logger.handlers) == 1 -assert isinstance(ddtrace_logger.handlers[0], logging.handlers.RotatingFileHandler) -assert ddtrace_logger.handlers[0].maxBytes == 200000 -assert ddtrace_logger.handlers[0].backupCount == 1 +assert len(ddtrace_logger.handlers) == 2 +assert isinstance(ddtrace_logger.handlers[1], logging.handlers.RotatingFileHandler) +assert ddtrace_logger.handlers[1].maxBytes == 200000 +assert ddtrace_logger.handlers[1].backupCount == 1 ddtrace_logger.warning('warning log') """ @@ -250,10 +245,10 @@ def test_warn_logs_can_go_to_file(run_python_code_in_subprocess, ddtrace_run_pyt ddtrace_logger = logging.getLogger('ddtrace') assert ddtrace_logger.getEffectiveLevel() == logging.WARN -assert len(ddtrace_logger.handlers) == 1 -assert isinstance(ddtrace_logger.handlers[0], logging.handlers.RotatingFileHandler) -assert ddtrace_logger.handlers[0].maxBytes == 200000 -assert ddtrace_logger.handlers[0].backupCount == 1 +assert len(ddtrace_logger.handlers) == 2 +assert isinstance(ddtrace_logger.handlers[1], logging.handlers.RotatingFileHandler) +assert ddtrace_logger.handlers[1].maxBytes == 200000 +assert ddtrace_logger.handlers[1].backupCount == 1 ddtrace_logger.warning('warning log') """ @@ -264,7 +259,7 @@ def test_warn_logs_can_go_to_file(run_python_code_in_subprocess, ddtrace_run_pyt ]: out, err, status, pid = run_in_subprocess(code, env=env) assert status == 0, err - assert err == b"", err.decode() + assert err == b"warning log\n", err.decode() assert out == b"", out.decode() with open(log_file) as file: first_line = file.readline() @@ -295,7 +290,6 @@ def test_debug_logs_streamhandler_default( ddtrace_logger = logging.getLogger('ddtrace') assert ddtrace_logger.getEffectiveLevel() == logging.DEBUG -assert len(ddtrace_logger.handlers) == 0 ddtrace_logger.warning('warning log') ddtrace_logger.debug('debug log') @@ -315,7 +309,6 @@ def test_debug_logs_streamhandler_default( ddtrace_logger = logging.getLogger('ddtrace') assert ddtrace_logger.getEffectiveLevel() == logging.DEBUG -assert len(ddtrace_logger.handlers) == 0 ddtrace_logger.warning('warning log') ddtrace_logger.debug('debug log') @@ -354,12 +347,12 @@ def test_debug_logs_can_go_to_file_backup_count( ddtrace_logger = logging.getLogger('ddtrace') assert ddtrace_logger.getEffectiveLevel() == logging.DEBUG -assert len(ddtrace_logger.handlers) == 1 -assert isinstance(ddtrace_logger.handlers[0], logging.handlers.RotatingFileHandler) -assert ddtrace_logger.handlers[0].maxBytes == 10 -assert ddtrace_logger.handlers[0].backupCount == 1 +assert len(ddtrace_logger.handlers) == 2 +assert isinstance(ddtrace_logger.handlers[1], logging.handlers.RotatingFileHandler) +assert ddtrace_logger.handlers[1].maxBytes == 10 +assert ddtrace_logger.handlers[1].backupCount == 1 if os.environ.get("DD_TRACE_LOG_FILE_LEVEL") is not None: - ddtrace_logger.handlers[0].level == getattr(logging, os.environ.get("DD_TRACE_LOG_FILE_LEVEL")) + ddtrace_logger.handlers[1].level == getattr(logging, os.environ.get("DD_TRACE_LOG_FILE_LEVEL")) ddtrace_logger = logging.getLogger('ddtrace') @@ -373,8 +366,6 @@ def test_debug_logs_can_go_to_file_backup_count( if PY2: assert 'No handlers could be found for logger "ddtrace' in err - else: - assert err == b"" assert out == b"" @@ -386,13 +377,13 @@ def test_debug_logs_can_go_to_file_backup_count( ddtrace_logger = logging.getLogger('ddtrace') assert ddtrace_logger.getEffectiveLevel() == logging.DEBUG -assert len(ddtrace_logger.handlers) == 1 -assert isinstance(ddtrace_logger.handlers[0], logging.handlers.RotatingFileHandler) -assert ddtrace_logger.handlers[0].maxBytes == 10 -assert ddtrace_logger.handlers[0].backupCount == 1 +assert len(ddtrace_logger.handlers) == 2 +assert isinstance(ddtrace_logger.handlers[1], logging.handlers.RotatingFileHandler) +assert ddtrace_logger.handlers[1].maxBytes == 10 +assert ddtrace_logger.handlers[1].backupCount == 1 if os.environ.get("DD_TRACE_LOG_FILE_LEVEL") is not None: - ddtrace_logger.handlers[0].level == getattr(logging, os.environ.get("DD_TRACE_LOG_FILE_LEVEL")) + ddtrace_logger.handlers[1].level == getattr(logging, os.environ.get("DD_TRACE_LOG_FILE_LEVEL")) for attempt in range(100): ddtrace_logger.debug('ddtrace multiple debug log') diff --git a/tests/contrib/starlette/test_starlette.py b/tests/contrib/starlette/test_starlette.py index f844563966e..a0987e1719b 100644 --- a/tests/contrib/starlette/test_starlette.py +++ b/tests/contrib/starlette/test_starlette.py @@ -10,7 +10,6 @@ import ddtrace from ddtrace import Pin -from ddtrace import config from ddtrace.constants import ERROR_MSG from ddtrace.contrib.sqlalchemy import patch as sql_patch from ddtrace.contrib.sqlalchemy import unpatch as sql_unpatch @@ -371,27 +370,6 @@ def test_multi_path_param_aggregate(client, tracer, test_spans): assert request_span.get_tag("span.kind") == "server" -def test_path_param_no_aggregate(client, tracer, test_spans): - config.starlette["aggregate_resources"] = False - r = client.get("/users/1") - - assert r.status_code == 200 - assert r.text == "Success" - - request_span = next(test_spans.filter_spans(name="starlette.request")) - assert request_span.service == "starlette" - assert request_span.name == "starlette.request" - assert request_span.resource == "GET /users/1" - assert request_span.get_tag("http.route") is None - assert request_span.error == 0 - assert request_span.get_tag("http.method") == "GET" - assert request_span.get_tag("http.url") == "http://testserver/users/1" - assert request_span.get_tag("http.status_code") == "200" - assert request_span.get_tag("component") == "starlette" - assert request_span.get_tag("span.kind") == "server" - config.starlette["aggregate_resources"] = True - - def test_table_query(client, tracer, test_spans): r = client.post("/notes", json={"id": 1, "text": "test", "completed": 1}) assert r.status_code == 200 @@ -463,15 +441,6 @@ def test_subapp_snapshot(snapshot_client): assert response.text == "Success" -@snapshot() -def test_subapp_no_aggregate_snapshot(snapshot_client): - config.starlette["aggregate_resources"] = False - response = snapshot_client.get("/sub-app/hello/name") - assert response.status_code == 200 - assert response.text == "Success" - config.starlette["aggregate_resources"] = True - - @snapshot() def test_table_query_snapshot(snapshot_client): r_post = snapshot_client.post("/notes", json={"id": 1, "text": "test", "completed": 1}) @@ -573,7 +542,6 @@ def engine(): yield engine def test(snapshot_client): - config.starlette["aggregate_resources"] = False response = snapshot_client.get("/sub-app/hello/name") if __name__ == "__main__": diff --git a/tests/integration/test_debug.py b/tests/integration/test_debug.py index 12be5e16e69..1ce4e0b33b5 100644 --- a/tests/integration/test_debug.py +++ b/tests/integration/test_debug.py @@ -366,9 +366,7 @@ def test_startup_logs_sampling_rules(): def test_error_output_ddtracerun_debug_mode(): p = subprocess.Popen( ["ddtrace-run", "python", "tests/integration/hello.py"], - env=dict( - DD_TRACE_AGENT_URL="http://localhost:8126", DD_TRACE_DEBUG="true", DD_CALL_BASIC_CONFIG="true", **os.environ - ), + env=dict(DD_TRACE_AGENT_URL="http://localhost:8126", DD_TRACE_DEBUG="true", **os.environ), stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) @@ -380,9 +378,7 @@ def test_error_output_ddtracerun_debug_mode(): # No connection to agent, debug mode enabled p = subprocess.Popen( ["ddtrace-run", "python", "tests/integration/hello.py"], - env=dict( - DD_TRACE_AGENT_URL="http://localhost:4321", DD_TRACE_DEBUG="true", DD_CALL_BASIC_CONFIG="true", **os.environ - ), + env=dict(DD_TRACE_AGENT_URL="http://localhost:4321", DD_TRACE_DEBUG="true", **os.environ), stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) @@ -424,9 +420,7 @@ def test_error_output_ddtracerun(): def test_debug_span_log(): p = subprocess.Popen( ["python", "-c", 'import os; print(os.environ);import ddtrace; ddtrace.tracer.trace("span").finish()'], - env=dict( - DD_TRACE_AGENT_URL="http://localhost:8126", DD_TRACE_DEBUG="true", DD_CALL_BASIC_CONFIG="true", **os.environ - ), + env=dict(DD_TRACE_AGENT_URL="http://localhost:8126", DD_TRACE_DEBUG="true", **os.environ), stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py index 0ce27750b7d..bfd287b035e 100644 --- a/tests/integration/test_integration.py +++ b/tests/integration/test_integration.py @@ -55,10 +55,12 @@ def test_debug_mode_generates_debug_output(): assert b"DEBUG:ddtrace" not in p.stderr.read(), "stderr should have no debug lines when DD_TRACE_DEBUG is unset" env = os.environ.copy() - env.update({"DD_TRACE_DEBUG": "true", "DD_CALL_BASIC_CONFIG": "true"}) + env.update({"DD_TRACE_DEBUG": "true"}) p = import_ddtrace_in_subprocess(env) assert p.stdout.read() == b"" - assert b"DEBUG:ddtrace" in p.stderr.read(), "stderr should have some debug lines when DD_TRACE_DEBUG is set" + assert ( + b"debug mode has been enabled for the ddtrace logger" in p.stderr.read() + ), "stderr should have some debug lines when DD_TRACE_DEBUG is set" def test_import_ddtrace_generates_no_output_by_default(ddtrace_run_python_code_in_subprocess): @@ -619,7 +621,6 @@ def test_application_does_not_deadlock_when_parent_span_closes_before_child(run_ { "DD_TRACE_LOGS_INJECTION": str(logs_injection).lower(), "DD_TRACE_DEBUG": str(debug_mode).lower(), - "DD_CALL_BASIC_CONFIG": "true", } ) @@ -627,38 +628,7 @@ def test_application_does_not_deadlock_when_parent_span_closes_before_child(run_ assert status == 0, err -@pytest.mark.parametrize( - "call_basic_config,debug_mode", - itertools.permutations((True, False, None), 2), -) -def test_call_basic_config(ddtrace_run_python_code_in_subprocess, call_basic_config, debug_mode): - env = os.environ.copy() - - if debug_mode is not None: - env["DD_TRACE_DEBUG"] = str(debug_mode).lower() - if call_basic_config is not None: - env["DD_CALL_BASIC_CONFIG"] = str(call_basic_config).lower() - has_root_handlers = call_basic_config - else: - has_root_handlers = False - - out, err, status, pid = ddtrace_run_python_code_in_subprocess( - """ -import logging -root = logging.getLogger() -print(len(root.handlers)) -""", - env=env, - ) - - assert status == 0 - if has_root_handlers: - assert out == six.b("1\n") - else: - assert out == six.b("0\n") - - -@parametrize_with_all_encodings( +@pytest.mark.subprocess( env=dict( DD_TRACE_WRITER_BUFFER_SIZE_BYTES="1000", DD_TRACE_WRITER_MAX_PAYLOAD_SIZE_BYTES="5000", @@ -750,7 +720,6 @@ def test_logging_during_tracer_init_succeeds_when_debug_logging_and_logs_injecti env = os.environ.copy() env["DD_TRACE_DEBUG"] = "true" env["DD_LOGS_INJECTION"] = "true" - env["DD_CALL_BASIC_CONFIG"] = "true" # DEV: We don't actually have to execute any code to validate this out, err, status, pid = ddtrace_run_python_code_in_subprocess("", env=env) diff --git a/tests/internal/remoteconfig/test_remoteconfig.py b/tests/internal/remoteconfig/test_remoteconfig.py index 803851551c6..95c7421354d 100644 --- a/tests/internal/remoteconfig/test_remoteconfig.py +++ b/tests/internal/remoteconfig/test_remoteconfig.py @@ -4,7 +4,6 @@ import hashlib import json from time import sleep -import warnings import mock from mock.mock import ANY @@ -18,12 +17,10 @@ from ddtrace.internal.remoteconfig.client import RemoteConfigClient from ddtrace.internal.remoteconfig.constants import ASM_FEATURES_PRODUCT from ddtrace.internal.remoteconfig.constants import REMOTE_CONFIG_AGENT_ENDPOINT -from ddtrace.internal.remoteconfig.utils import get_poll_interval_seconds from ddtrace.internal.remoteconfig.worker import RemoteConfigPoller from ddtrace.internal.remoteconfig.worker import remoteconfig_poller from ddtrace.internal.service import ServiceStatus from tests.internal.test_utils_version import _assert_and_get_version_agent_format -from tests.utils import override_env from tests.utils import override_global_config @@ -177,13 +174,6 @@ def test_remote_config_forksafe(): exit(0) -def test_remote_configuration_check_deprecated_var(): - with override_global_config(dict(_remote_config_poll_interval="0.1")): - with warnings.catch_warnings(record=True) as capture: - get_poll_interval_seconds() - assert len(capture) == 0 - - @mock.patch.object(RemoteConfigClient, "_send_request") def test_remote_configuration_1_click(mock_send_request): class Callback: @@ -209,23 +199,6 @@ def _reload_features(self, features, test_tracer=None): } -def test_remote_configuration_check_deprecated_var_message(): - with override_env(dict(DD_REMOTECONFIG_POLL_SECONDS="0.1")): - with warnings.catch_warnings(record=True) as capture: - get_poll_interval_seconds() - assert len(capture) == 1 - assert str(capture[0].message).startswith("Using environment") - - -def test_remote_configuration_check_deprecated_override(): - with override_global_config(dict(_remote_config_enabled=True, _remote_config_poll_interval=0.1)): - with override_env(dict(DD_REMOTECONFIG_POLL_SECONDS="0.5")): - with warnings.catch_warnings(record=True) as capture: - assert get_poll_interval_seconds() == 0.1 - assert len(capture) == 1 - assert str(capture[0].message).startswith("Using environment") - - @mock.patch.object(RemoteConfigClient, "_send_request") def test_remote_configuration_ip_blocking(mock_send_request): class Callback: diff --git a/tests/lib-injection/dd-lib-python-init-test-django-gunicorn-alpine/django_app.py b/tests/lib-injection/dd-lib-python-init-test-django-gunicorn-alpine/django_app.py index 7a1b44ddc96..d25a658e4b1 100644 --- a/tests/lib-injection/dd-lib-python-init-test-django-gunicorn-alpine/django_app.py +++ b/tests/lib-injection/dd-lib-python-init-test-django-gunicorn-alpine/django_app.py @@ -1,3 +1,4 @@ +import logging import os from django.core.wsgi import get_wsgi_application @@ -11,6 +12,8 @@ SECRET_KEY = "fdsfdasfa" ALLOWED_HOSTS = ["*"] +logging.basicConfig(level=logging.DEBUG) + def index(request): return HttpResponse("test") diff --git a/tests/lib-injection/dd-lib-python-init-test-django-gunicorn/django_app.py b/tests/lib-injection/dd-lib-python-init-test-django-gunicorn/django_app.py index 7a1b44ddc96..d25a658e4b1 100644 --- a/tests/lib-injection/dd-lib-python-init-test-django-gunicorn/django_app.py +++ b/tests/lib-injection/dd-lib-python-init-test-django-gunicorn/django_app.py @@ -1,3 +1,4 @@ +import logging import os from django.core.wsgi import get_wsgi_application @@ -11,6 +12,8 @@ SECRET_KEY = "fdsfdasfa" ALLOWED_HOSTS = ["*"] +logging.basicConfig(level=logging.DEBUG) + def index(request): return HttpResponse("test") diff --git a/tests/lib-injection/dd-lib-python-init-test-django-no-perms/django_app.py b/tests/lib-injection/dd-lib-python-init-test-django-no-perms/django_app.py index c0702f664b3..a563e549e91 100644 --- a/tests/lib-injection/dd-lib-python-init-test-django-no-perms/django_app.py +++ b/tests/lib-injection/dd-lib-python-init-test-django-no-perms/django_app.py @@ -1,3 +1,4 @@ +import logging import os from django.http import HttpResponse @@ -10,6 +11,8 @@ SECRET_KEY = "fdsfdasfa" ALLOWED_HOSTS = ["*"] +logging.basicConfig(level=logging.DEBUG) + def index(request): return HttpResponse("test") diff --git a/tests/lib-injection/dd-lib-python-init-test-django-pre-installed/django_app.py b/tests/lib-injection/dd-lib-python-init-test-django-pre-installed/django_app.py index 74488efb5e6..d83d49cd18f 100644 --- a/tests/lib-injection/dd-lib-python-init-test-django-pre-installed/django_app.py +++ b/tests/lib-injection/dd-lib-python-init-test-django-pre-installed/django_app.py @@ -1,3 +1,4 @@ +import logging import os from django.http import HttpResponse @@ -10,6 +11,8 @@ SECRET_KEY = "fdsfdasfa" ALLOWED_HOSTS = ["*"] +logging.basicConfig(level=logging.DEBUG) + def index(request): import ddtrace diff --git a/tests/lib-injection/dd-lib-python-init-test-django-uvicorn/django_app.py b/tests/lib-injection/dd-lib-python-init-test-django-uvicorn/django_app.py index dc0e14bad8c..c75a8df9a06 100644 --- a/tests/lib-injection/dd-lib-python-init-test-django-uvicorn/django_app.py +++ b/tests/lib-injection/dd-lib-python-init-test-django-uvicorn/django_app.py @@ -1,3 +1,4 @@ +import logging import os from django.core.asgi import get_asgi_application @@ -11,6 +12,8 @@ SECRET_KEY = "fdsfdasfa" ALLOWED_HOSTS = ["*"] +logging.basicConfig(level=logging.DEBUG) + def index(request): return HttpResponse("test") diff --git a/tests/lib-injection/dd-lib-python-init-test-django/django_app.py b/tests/lib-injection/dd-lib-python-init-test-django/django_app.py index 576ca308056..6ed1046ce87 100644 --- a/tests/lib-injection/dd-lib-python-init-test-django/django_app.py +++ b/tests/lib-injection/dd-lib-python-init-test-django/django_app.py @@ -1,3 +1,4 @@ +import logging import os from django.http import HttpResponse @@ -10,6 +11,8 @@ SECRET_KEY = "fdsfdasfa" ALLOWED_HOSTS = ["*"] +logging.basicConfig(level=logging.DEBUG) + def index(request): import ddtrace diff --git a/tests/pep562_test/__init__.py b/tests/pep562_test/__init__.py deleted file mode 100644 index 9871f89a5ce..00000000000 --- a/tests/pep562_test/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from ddtrace.internal.compat import ensure_pep562 - - -def __getattr__(name): - if name == "deprecated": - raise RuntimeError("bad module attribute!") - return "good module attribute" - - -ensure_pep562(__name__) diff --git a/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema0]_rest.json b/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema0]_rest.json index f3deb3dbfd1..902267ea1e2 100644 --- a/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema0]_rest.json +++ b/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema0]_rest.json @@ -2,7 +2,7 @@ { "name": "starlette.request", "service": "starlette", - "resource": "GET /sub-app/hello/name", + "resource": "GET /sub-app/hello/{name}", "trace_id": 0, "span_id": 1, "parent_id": 0, @@ -13,6 +13,7 @@ "_dd.p.dm": "-0", "component": "starlette", "http.method": "GET", + "http.route": "/sub-app/hello/{name}", "http.status_code": "200", "http.url": "http://testserver/sub-app/hello/name", "http.useragent": "testclient", @@ -33,7 +34,7 @@ { "name": "starlette.request", "service": "starlette", - "resource": "GET /hello/name", + "resource": "GET /hello/{name}", "trace_id": 0, "span_id": 2, "parent_id": 1, diff --git a/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema1]_rest.json b/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema1]_rest.json index a73eed32ad6..c5b3d6ff20d 100644 --- a/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema1]_rest.json +++ b/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema1]_rest.json @@ -2,7 +2,7 @@ { "name": "starlette.request", "service": "starlette", - "resource": "GET /sub-app/hello/name", + "resource": "GET /sub-app/hello/{name}", "trace_id": 0, "span_id": 1, "parent_id": 0, @@ -13,6 +13,7 @@ "_dd.p.dm": "-0", "component": "starlette", "http.method": "GET", + "http.route": "/sub-app/hello/{name}", "http.status_code": "200", "http.url": "http://testserver/sub-app/hello/name", "http.useragent": "testclient", @@ -33,7 +34,7 @@ { "name": "starlette.request", "service": "starlette", - "resource": "GET /hello/name", + "resource": "GET /hello/{name}", "trace_id": 0, "span_id": 2, "parent_id": 1, diff --git a/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema2]_rest.json b/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema2]_rest.json index f3e6c1eef7f..cfd85030550 100644 --- a/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema2]_rest.json +++ b/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema2]_rest.json @@ -2,7 +2,7 @@ { "name": "http.server.request", "service": "unnamed-python-service", - "resource": "GET /sub-app/hello/name", + "resource": "GET /sub-app/hello/{name}", "trace_id": 0, "span_id": 1, "parent_id": 0, @@ -12,6 +12,7 @@ "_dd.p.dm": "-0", "component": "starlette", "http.method": "GET", + "http.route": "/sub-app/hello/{name}", "http.status_code": "200", "http.url": "http://testserver/sub-app/hello/name", "http.useragent": "testclient", @@ -32,7 +33,7 @@ { "name": "http.server.request", "service": "unnamed-python-service", - "resource": "GET /hello/name", + "resource": "GET /hello/{name}", "trace_id": 0, "span_id": 2, "parent_id": 1, diff --git a/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema3]_rest.json b/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema3]_rest.json index f9b26e05459..72df8bbabed 100644 --- a/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema3]_rest.json +++ b/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema3]_rest.json @@ -2,7 +2,7 @@ { "name": "starlette.request", "service": "mysvc", - "resource": "GET /sub-app/hello/name", + "resource": "GET /sub-app/hello/{name}", "trace_id": 0, "span_id": 1, "parent_id": 0, @@ -12,6 +12,7 @@ "_dd.p.dm": "-0", "component": "starlette", "http.method": "GET", + "http.route": "/sub-app/hello/{name}", "http.status_code": "200", "http.url": "http://testserver/sub-app/hello/name", "http.useragent": "testclient", @@ -32,7 +33,7 @@ { "name": "starlette.request", "service": "mysvc", - "resource": "GET /hello/name", + "resource": "GET /hello/{name}", "trace_id": 0, "span_id": 2, "parent_id": 1, diff --git a/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema4]_rest.json b/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema4]_rest.json index a04ac50cc47..1fd3ad25319 100644 --- a/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema4]_rest.json +++ b/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema4]_rest.json @@ -2,7 +2,7 @@ { "name": "starlette.request", "service": "mysvc", - "resource": "GET /sub-app/hello/name", + "resource": "GET /sub-app/hello/{name}", "trace_id": 0, "span_id": 1, "parent_id": 0, @@ -12,6 +12,7 @@ "_dd.p.dm": "-0", "component": "starlette", "http.method": "GET", + "http.route": "/sub-app/hello/{name}", "http.status_code": "200", "http.url": "http://testserver/sub-app/hello/name", "http.useragent": "testclient", @@ -32,7 +33,7 @@ { "name": "starlette.request", "service": "mysvc", - "resource": "GET /hello/name", + "resource": "GET /hello/{name}", "trace_id": 0, "span_id": 2, "parent_id": 1, diff --git a/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema5]_rest.json b/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema5]_rest.json index 6686c306284..0e67916e9e2 100644 --- a/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema5]_rest.json +++ b/tests/snapshots/tests.contrib.starlette.test_starlette.test_schematization[service_schema5]_rest.json @@ -2,7 +2,7 @@ { "name": "http.server.request", "service": "mysvc", - "resource": "GET /sub-app/hello/name", + "resource": "GET /sub-app/hello/{name}", "trace_id": 0, "span_id": 1, "parent_id": 0, @@ -12,6 +12,7 @@ "_dd.p.dm": "-0", "component": "starlette", "http.method": "GET", + "http.route": "/sub-app/hello/{name}", "http.status_code": "200", "http.url": "http://testserver/sub-app/hello/name", "http.useragent": "testclient", @@ -32,7 +33,7 @@ { "name": "http.server.request", "service": "mysvc", - "resource": "GET /hello/name", + "resource": "GET /hello/{name}", "trace_id": 0, "span_id": 2, "parent_id": 1, diff --git a/tests/telemetry/test_writer.py b/tests/telemetry/test_writer.py index cf67464b2a1..dd712ee771f 100644 --- a/tests/telemetry/test_writer.py +++ b/tests/telemetry/test_writer.py @@ -70,7 +70,6 @@ def test_app_started_event(telemetry_writer, test_agent_session, mock_time): payload = { "configuration": [ {"name": "DD_APPSEC_ENABLED", "origin": "unknown", "value": False}, - {"name": "DD_CALL_BASIC_CONFIG", "origin": "unknown", "value": False}, {"name": "DD_DATA_STREAMS_ENABLED", "origin": "unknown", "value": False}, {"name": "DD_DYNAMIC_INSTRUMENTATION_ENABLED", "origin": "unknown", "value": False}, {"name": "DD_EXCEPTION_DEBUGGING_ENABLED", "origin": "unknown", "value": False}, @@ -149,7 +148,6 @@ def test_app_started_event_configuration_override(test_agent_session, run_python env["DD_INSTRUMENTATION_TELEMETRY_ENABLED"] = "True" env["DD_TRACE_STARTUP_LOGS"] = "True" env["DD_LOGS_INJECTION"] = "True" - env["DD_CALL_BASIC_CONFIG"] = "True" env["DD_PROFILING_ENABLED"] = "True" env["DD_RUNTIME_METRICS_ENABLED"] = "True" env["DD_SERVICE_MAPPING"] = "default_dd_service:remapped_dd_service" @@ -198,7 +196,6 @@ def test_app_started_event_configuration_override(test_agent_session, run_python events[0]["payload"]["configuration"].sort(key=lambda c: c["name"]) assert events[0]["payload"]["configuration"] == [ {"name": "DD_APPSEC_ENABLED", "origin": "unknown", "value": False}, - {"name": "DD_CALL_BASIC_CONFIG", "origin": "unknown", "value": True}, {"name": "DD_DATA_STREAMS_ENABLED", "origin": "unknown", "value": False}, {"name": "DD_DYNAMIC_INSTRUMENTATION_ENABLED", "origin": "unknown", "value": True}, {"name": "DD_EXCEPTION_DEBUGGING_ENABLED", "origin": "unknown", "value": True}, diff --git a/tests/tracer/test_compat.py b/tests/tracer/test_compat.py index d623e151f44..5750cae1585 100644 --- a/tests/tracer/test_compat.py +++ b/tests/tracer/test_compat.py @@ -127,17 +127,6 @@ def test_is_integer(obj, expected): assert is_integer(obj) is expected -def test_pep562(): - with pytest.raises(RuntimeError): - from tests.pep562_test import deprecated - - print(deprecated) - - from tests.pep562_test import whatever - - assert whatever == "good module attribute" - - @pytest.mark.skipif(PY2, reason="This hypothesis test hangs occasionally on Python 2") @given( obj=st.one_of( diff --git a/tests/tracer/test_global_config.py b/tests/tracer/test_global_config.py index e46a4b26ca8..334e67d468a 100644 --- a/tests/tracer/test_global_config.py +++ b/tests/tracer/test_global_config.py @@ -5,7 +5,6 @@ from ddtrace import config as global_config from ddtrace.settings import Config -from ddtrace.settings.config import _parse_propagation_styles from ..utils import DummyTracer from ..utils import override_env @@ -278,11 +277,3 @@ def test_dd_service_mapping(self): with override_env(dict(DD_SERVICE_MAPPING="foobar:bar,snafu:foo")): c = Config() assert c.service_mapping == {"foobar": "bar", "snafu": "foo"} - - -def test_parse_propagation_styles_b3_deprecation(capsys): - with pytest.warns(DeprecationWarning, match='Using DD_TRACE_PROPAGATION_STYLE="b3" is deprecated'), override_env( - dict(DD_TRACE_PROPAGATION_STYLE="b3") - ): - style = _parse_propagation_styles("DD_TRACE_PROPAGATION_STYLE", default="datadog") - assert style == ["b3multi"] diff --git a/tests/tracer/test_propagation.py b/tests/tracer/test_propagation.py index c14edbbfc31..803a7c65b29 100644 --- a/tests/tracer/test_propagation.py +++ b/tests/tracer/test_propagation.py @@ -1516,18 +1516,6 @@ def test_extract_tracecontext(headers, expected_context): # Only add fixtures here if they can't pass both test_propagation_extract_env # and test_propagation_extract_w_config EXTRACT_FIXTURES_ENV_ONLY = [ - ( - # b3 will only override to b3multi when set via envar - "test_deprecated_b3_style_still_works", - ["b3"], - B3_HEADERS_VALID, - { - "trace_id": TRACE_ID, - "span_id": 11744061942159299346, - "sampling_priority": 1, - "dd_origin": None, - }, - ), ( # tracecontext propagation sets additional meta data that # can't be tested correctly via test_propagation_extract_w_config. It is tested separately