From c26f35a248bb2400f547f1d0ecb957b961f35563 Mon Sep 17 00:00:00 2001 From: Ivana Kellyerova Date: Wed, 21 Jun 2023 10:28:26 +0200 Subject: [PATCH 1/4] Auto-enable httpx integration if httpx installed (#2177) --- sentry_sdk/integrations/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sentry_sdk/integrations/__init__.py b/sentry_sdk/integrations/__init__.py index a2bbc04260..9870471623 100644 --- a/sentry_sdk/integrations/__init__.py +++ b/sentry_sdk/integrations/__init__.py @@ -67,6 +67,7 @@ def iter_default_integrations(with_auto_enabling_integrations): "sentry_sdk.integrations.redis.RedisIntegration", "sentry_sdk.integrations.pyramid.PyramidIntegration", "sentry_sdk.integrations.boto3.Boto3Integration", + "sentry_sdk.integrations.httpx.HttpxIntegration", ) From e68161c8ed29e47809addc6a249fb5cab5733c68 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Thu, 22 Jun 2023 10:23:01 +0200 Subject: [PATCH 2/4] Load tracing information from environment (#2176) It should be able to continue a trace with trace information that was given to the python process over environment variables. See this RFC for the spec: https://github.com/getsentry/rfcs/blob/main/text/0071-continue-trace-over-process-boundaries.md --------- Co-authored-by: Ivana Kellyerova --- Makefile | 2 +- sentry_sdk/_compat.py | 5 ++- sentry_sdk/consts.py | 8 ++++ sentry_sdk/scope.py | 40 +++++++++++++++++- tests/test_scope.py | 95 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 147 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index a4d07279da..2011b1b63e 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ lint: .venv apidocs: .venv @$(VENV_PATH)/bin/pip install --editable . @$(VENV_PATH)/bin/pip install -U -r ./docs-requirements.txt - @$(VENV_PATH)/bin/sphinx-build -W -b html docs/ docs/_build + @$(VENV_PATH)/bin/sphinx-build -vv -W -b html docs/ docs/_build .PHONY: apidocs apidocs-hotfix: apidocs diff --git a/sentry_sdk/_compat.py b/sentry_sdk/_compat.py index 4fa489569b..0e56608d13 100644 --- a/sentry_sdk/_compat.py +++ b/sentry_sdk/_compat.py @@ -82,7 +82,10 @@ def check_thread_support(): if "threads" in opt: return - if str(opt.get("enable-threads", "0")).lower() in ("false", "off", "no", "0"): + # put here because of circular import + from sentry_sdk.consts import FALSE_VALUES + + if str(opt.get("enable-threads", "0")).lower() in FALSE_VALUES: from warnings import warn warn( diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index ebe5719471..0f276e05df 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -45,6 +45,14 @@ MATCH_ALL = r".*" +FALSE_VALUES = [ + "false", + "no", + "off", + "n", + "0", +] + class INSTRUMENTER: SENTRY = "sentry" diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index c7ff150064..3ad61d31d5 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -1,6 +1,7 @@ from copy import copy from collections import deque from itertools import chain +import os import uuid from sentry_sdk.attachments import Attachment @@ -19,6 +20,8 @@ from sentry_sdk._types import TYPE_CHECKING from sentry_sdk.utils import logger, capture_internal_exceptions +from sentry_sdk.consts import FALSE_VALUES + if TYPE_CHECKING: from typing import Any @@ -122,7 +125,36 @@ def __init__(self): self._propagation_context = None # type: Optional[Dict[str, Any]] self.clear() - self.generate_propagation_context() + + incoming_trace_information = self._load_trace_data_from_env() + self.generate_propagation_context(incoming_data=incoming_trace_information) + + def _load_trace_data_from_env(self): + # type: () -> Optional[Dict[str, str]] + """ + Load Sentry trace id and baggage from environment variables. + Can be disabled by setting SENTRY_USE_ENVIRONMENT to "false". + """ + incoming_trace_information = None + + sentry_use_environment = ( + os.environ.get("SENTRY_USE_ENVIRONMENT") or "" + ).lower() + use_environment = sentry_use_environment not in FALSE_VALUES + if use_environment: + incoming_trace_information = {} + + if os.environ.get("SENTRY_TRACE"): + incoming_trace_information[SENTRY_TRACE_HEADER_NAME] = ( + os.environ.get("SENTRY_TRACE") or "" + ) + + if os.environ.get("SENTRY_BAGGAGE"): + incoming_trace_information[BAGGAGE_HEADER_NAME] = ( + os.environ.get("SENTRY_BAGGAGE") or "" + ) + + return incoming_trace_information or None def _extract_propagation_context(self, data): # type: (Dict[str, Any]) -> Optional[Dict[str, Any]] @@ -141,6 +173,12 @@ def _extract_propagation_context(self, data): if sentrytrace_data is not None: context.update(sentrytrace_data) + only_baggage_no_sentry_trace = ( + "dynamic_sampling_context" in context and "trace_id" not in context + ) + if only_baggage_no_sentry_trace: + context.update(self._create_new_propagation_context()) + if context: if not context.get("span_id"): context["span_id"] = uuid.uuid4().hex[16:] diff --git a/tests/test_scope.py b/tests/test_scope.py index d90a89f490..8bdd46e02f 100644 --- a/tests/test_scope.py +++ b/tests/test_scope.py @@ -1,7 +1,14 @@ import copy +import os +import pytest from sentry_sdk import capture_exception from sentry_sdk.scope import Scope +try: + from unittest import mock # python 3.3 and above +except ImportError: + import mock # python < 3.3 + def test_copying(): s1 = Scope() @@ -62,3 +69,91 @@ def test_common_args(): assert s2._extras == {"k": "v", "foo": "bar"} assert s2._tags == {"a": "b", "x": "y"} assert s2._contexts == {"os": {"name": "Blafasel"}, "device": {"a": "b"}} + + +BAGGAGE_VALUE = ( + "other-vendor-value-1=foo;bar;baz, sentry-trace_id=771a43a4192642f0b136d5159a501700, " + "sentry-public_key=49d0f7386ad645858ae85020e393bef3, sentry-sample_rate=0.01337, " + "sentry-user_id=Am%C3%A9lie, other-vendor-value-2=foo;bar;" +) + +SENTRY_TRACE_VALUE = "771a43a4192642f0b136d5159a501700-1234567890abcdef-1" + + +@pytest.mark.parametrize( + "env,excepted_value", + [ + ( + { + "SENTRY_TRACE": SENTRY_TRACE_VALUE, + }, + { + "sentry-trace": SENTRY_TRACE_VALUE, + }, + ), + ( + { + "SENTRY_BAGGAGE": BAGGAGE_VALUE, + }, + { + "baggage": BAGGAGE_VALUE, + }, + ), + ( + { + "SENTRY_TRACE": SENTRY_TRACE_VALUE, + "SENTRY_BAGGAGE": BAGGAGE_VALUE, + }, + { + "sentry-trace": SENTRY_TRACE_VALUE, + "baggage": BAGGAGE_VALUE, + }, + ), + ( + { + "SENTRY_USE_ENVIRONMENT": "", + "SENTRY_TRACE": SENTRY_TRACE_VALUE, + "SENTRY_BAGGAGE": BAGGAGE_VALUE, + }, + { + "sentry-trace": SENTRY_TRACE_VALUE, + "baggage": BAGGAGE_VALUE, + }, + ), + ( + { + "SENTRY_USE_ENVIRONMENT": "True", + "SENTRY_TRACE": SENTRY_TRACE_VALUE, + "SENTRY_BAGGAGE": BAGGAGE_VALUE, + }, + { + "sentry-trace": SENTRY_TRACE_VALUE, + "baggage": BAGGAGE_VALUE, + }, + ), + ( + { + "SENTRY_USE_ENVIRONMENT": "no", + "SENTRY_TRACE": SENTRY_TRACE_VALUE, + "SENTRY_BAGGAGE": BAGGAGE_VALUE, + }, + None, + ), + ( + { + "SENTRY_USE_ENVIRONMENT": "True", + "MY_OTHER_VALUE": "asdf", + "SENTRY_RELEASE": "1.0.0", + }, + None, + ), + ], +) +def test_load_trace_data_from_env(env, excepted_value): + new_env = os.environ.copy() + new_env.update(env) + + with mock.patch.dict(os.environ, new_env): + s = Scope() + incoming_trace_data = s._load_trace_data_from_env() + assert incoming_trace_data == excepted_value From bba1ec27094b982a3b1b4546ceb0a9e9e9818b00 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Thu, 22 Jun 2023 08:53:46 +0000 Subject: [PATCH 3/4] release: 1.26.0 --- CHANGELOG.md | 15 +++++++++++++++ docs/conf.py | 2 +- sentry_sdk/consts.py | 2 +- setup.py | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f8eec56f6..18ad88dba4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## 1.26.0 + +### Various fixes & improvements + +- Load tracing information from environment (#2176) by @antonpirker +- Auto-enable httpx integration if httpx installed (#2177) by @sentrivana +- Run 2.7 tests in CI again (#2181) by @sentrivana +- support SOCKS proxies in sentry_sdk (#1050) by @Roguelazer +- Do not support sub-minute cron intervals (#2172) by @antonpirker +- Tracing without performance (#2136) by @antonpirker +- build(deps): bump checkouts/data-schemas from `0ed3357` to `7fdde87` (#2165) by @dependabot +- fix(profiler): Add function name to profiler frame cache (#2164) by @Zylphrex +- Wrap `parse_url` calls in `capture_internal_exceptions` (#2162) by @sentrivana +- Update changelog (#2163) by @sentrivana + ## 1.25.1 ### Django update (ongoing) diff --git a/docs/conf.py b/docs/conf.py index bcc3275f08..9dde301cfb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -30,7 +30,7 @@ copyright = "2019, Sentry Team and Contributors" author = "Sentry Team and Contributors" -release = "1.25.1" +release = "1.26.0" version = ".".join(release.split(".")[:2]) # The short X.Y version. diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 0f276e05df..ed3b2d88ae 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -228,4 +228,4 @@ def _get_default_options(): del _get_default_options -VERSION = "1.25.1" +VERSION = "1.26.0" diff --git a/setup.py b/setup.py index 26c3a9e84d..577e7f08f6 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ def get_file_text(file_name): setup( name="sentry-sdk", - version="1.25.1", + version="1.26.0", author="Sentry Team and Contributors", author_email="hello@sentry.io", url="https://github.com/getsentry/sentry-python", From 892f794113407eaf6e23452f66b8aee07d65fbb2 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Thu, 22 Jun 2023 13:09:14 +0200 Subject: [PATCH 4/4] Update changelog --- CHANGELOG.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18ad88dba4..f75708dd25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,15 +4,15 @@ ### Various fixes & improvements -- Load tracing information from environment (#2176) by @antonpirker -- Auto-enable httpx integration if httpx installed (#2177) by @sentrivana -- Run 2.7 tests in CI again (#2181) by @sentrivana -- support SOCKS proxies in sentry_sdk (#1050) by @Roguelazer -- Do not support sub-minute cron intervals (#2172) by @antonpirker - Tracing without performance (#2136) by @antonpirker -- build(deps): bump checkouts/data-schemas from `0ed3357` to `7fdde87` (#2165) by @dependabot -- fix(profiler): Add function name to profiler frame cache (#2164) by @Zylphrex +- Load tracing information from environment (#2176) by @antonpirker +- Auto-enable HTTPX integration if HTTPX installed (#2177) by @sentrivana +- Support for SOCKS proxies (#1050) by @Roguelazer - Wrap `parse_url` calls in `capture_internal_exceptions` (#2162) by @sentrivana +- Run 2.7 tests in CI again (#2181) by @sentrivana +- Crons: Do not support sub-minute cron intervals (#2172) by @antonpirker +- Profile: Add function name to profiler frame cache (#2164) by @Zylphrex +- Dependencies: bump checkouts/data-schemas from `0ed3357` to `7fdde87` (#2165) by @dependabot - Update changelog (#2163) by @sentrivana ## 1.25.1