Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
7e63dde
some intermitten or whatever
antonpirker May 10, 2023
8a6f872
Merge branch 'master' into antonpirker/tracing_without_performance
antonpirker May 15, 2023
36243e7
Fixed dict access
antonpirker May 15, 2023
22aaa0f
Merge branch 'master' into antonpirker/tracing_without_performance
antonpirker May 22, 2023
fedd946
.
antonpirker May 22, 2023
cfaf2f8
.
antonpirker May 22, 2023
e1c259f
Merge branch 'master' into antonpirker/tracing_without_performance
antonpirker May 23, 2023
968187f
Pair programming.
antonpirker May 23, 2023
479e1a6
Cleanup
antonpirker May 23, 2023
423f011
Cleanup
antonpirker May 23, 2023
14f111b
Cleanup
antonpirker May 23, 2023
9b6b043
Cleanup
antonpirker May 23, 2023
f2479f9
.
antonpirker May 24, 2023
615402b
Generate DSC and also load tracing info from headers in wsgi into scope
antonpirker May 24, 2023
643a0f8
Fix copying of scope and set default span id when populating propagat…
antonpirker May 24, 2023
dd05272
Merge branch 'master' into antonpirker/tracing_without_performance
sentrivana May 25, 2023
5ae431f
populate propagation context from headers
sentrivana May 25, 2023
a43dd79
Merge branch 'master' into antonpirker/tracing_without_performance
sentrivana May 25, 2023
cac41ea
oops
sentrivana May 25, 2023
512553f
make mypy happy?
sentrivana May 26, 2023
72aa89c
"fix"
sentrivana May 26, 2023
dfdff31
simplify
sentrivana May 26, 2023
48d4aa2
mypy fix
sentrivana May 30, 2023
c412e17
.
sentrivana May 30, 2023
d3680d0
If no relevant headers, do not set from env
sentrivana May 30, 2023
ccb4923
fix test
sentrivana May 30, 2023
5cc763a
Convince black to not add trailing commas after kwargs
sentrivana May 30, 2023
a62fe01
py2.7 friendly string formatting (so that the tests can run)
sentrivana May 30, 2023
b4a9bb1
handle trace being none
sentrivana May 30, 2023
04722e9
"fix"
sentrivana May 31, 2023
b1b59dd
actual fix
sentrivana May 31, 2023
a703f0b
Fixed some tests
antonpirker May 31, 2023
d06a50a
Nit: code formatting to be similar to other integrations
antonpirker May 31, 2023
82861b7
Made generate_propagation_context more readable
antonpirker May 31, 2023
c0972e6
Naming things
antonpirker May 31, 2023
67d0d0c
Moved data functions outside of Scope class
antonpirker May 31, 2023
74016a8
Moved functions back into class, they belong there.
antonpirker May 31, 2023
39c4763
fix rq, add more tests
sentrivana May 31, 2023
87f6661
fix weird asgi scoping
sentrivana May 31, 2023
c45a220
Some test preparation (waiting for aws access to finish)
antonpirker Jun 1, 2023
6aa8fa6
debug output
antonpirker Jun 1, 2023
1e29e88
more test output
antonpirker Jun 1, 2023
5293b98
Added tests for tornado and fixed a small bug in scope
antonpirker Jun 1, 2023
ce081d4
Added message to tornado test case
antonpirker Jun 1, 2023
12bd129
format
antonpirker Jun 1, 2023
929f286
add more tests (wsgi, flask)
sentrivana Jun 1, 2023
a9d2182
asgi tests
sentrivana Jun 1, 2023
20d154b
More tests
antonpirker Jun 1, 2023
cf15409
Merge branch 'antonpirker/tracing_without_performance' of github.com:…
antonpirker Jun 1, 2023
e308d4c
add some msgs too
sentrivana Jun 1, 2023
54520e9
Remove debug logs
sentrivana Jun 1, 2023
85aa9e3
fix aiohttp tests, add new ones
sentrivana Jun 1, 2023
6b64b1b
Merge branch 'master' into antonpirker/tracing_without_performance
sentrivana Jun 1, 2023
4862732
removed old environments
antonpirker Jun 1, 2023
25727ea
Merge branch 'antonpirker/tracing_without_performance' of github.com:…
antonpirker Jun 1, 2023
835b716
cleanup
antonpirker Jun 1, 2023
c36cb6c
cleanup
antonpirker Jun 1, 2023
90a96c8
Merge branch 'master' into antonpirker/tracing_without_performance
sentrivana Jun 2, 2023
35197e7
AWS tests
antonpirker Jun 2, 2023
7966368
Merge branch 'antonpirker/tracing_without_performance' of github.com:…
antonpirker Jun 2, 2023
b19eff1
Some cleanup
antonpirker Jun 2, 2023
3641064
Reverted black format
antonpirker Jun 2, 2023
b2f2c5c
Merge branch 'master' into antonpirker/tracing_without_performance
antonpirker Jun 2, 2023
70bcd66
django tests + some cleanup
sentrivana Jun 2, 2023
c95d07b
consistency
sentrivana Jun 2, 2023
fedca76
asgi django tests
sentrivana Jun 2, 2023
3b69de4
Fixed python 3.7 in tox.ini
antonpirker Jun 5, 2023
7cc9cb6
Do not run in parallel to have better output (just for debugging)
antonpirker Jun 5, 2023
7ad0387
Merge branch 'master' into antonpirker/tracing_without_performance
antonpirker Jun 5, 2023
94d4ef6
Merge branch 'master' into antonpirker/tracing_without_performance
antonpirker Jun 6, 2023
dff4d68
Merge branch 'master' into antonpirker/tracing_without_performance
antonpirker Jun 6, 2023
36944a2
Fixed Django ASGI tests
antonpirker Jun 6, 2023
48ba65b
Do not run async django tests in Django < 3.1 (where async views wher…
antonpirker Jun 6, 2023
2281638
Sort imports
antonpirker Jun 6, 2023
f85e489
Fixed circular imports during docs generation
antonpirker Jun 6, 2023
8f7fc54
Merge branch 'master' into antonpirker/tracing_without_performance
sentrivana Jun 7, 2023
7dfb9f2
Merge branch 'master' into antonpirker/tracing_without_performance
sentrivana Jun 7, 2023
230be9a
Merge branch 'master' into antonpirker/tracing_without_performance
sentrivana Jun 9, 2023
b45ebc7
Merge branch 'master' into antonpirker/tracing_without_performance
sentrivana Jun 12, 2023
85b127a
remove -0 from traceparent
sentrivana Jun 12, 2023
d29cd92
add traceparent, baggage, continue_trace
sentrivana Jun 12, 2023
9c90bb0
fix type
sentrivana Jun 13, 2023
da4c2e0
more type fixes
sentrivana Jun 13, 2023
0d54269
Merge branch 'master' into antonpirker/tracing_without_performance
sentrivana Jun 13, 2023
5d4c43e
Merge branch 'master' into antonpirker/tracing_without_performance
sentrivana Jun 13, 2023
692aff0
change names, change baggage to return str
sentrivana Jun 13, 2023
0280627
Merge branch 'master' into antonpirker/tracing_without_performance
sentrivana Jun 13, 2023
4d072a2
fix init
sentrivana Jun 13, 2023
aa45190
fix old py
sentrivana Jun 13, 2023
2f99c63
better test names
sentrivana Jun 13, 2023
35e7431
Fixed parent_span_id (and added debug log output)
antonpirker Jun 14, 2023
f908069
Cleanup
antonpirker Jun 15, 2023
cecfeff
Cleanup
antonpirker Jun 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions sentry_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"set_level",
"set_measurement",
"get_current_span",
"get_traceparent",
"get_baggage",
"continue_trace",
]

# Initialize the debug support after everything is loaded
Expand Down
65 changes: 61 additions & 4 deletions sentry_sdk/api.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import inspect

from sentry_sdk._types import TYPE_CHECKING
from sentry_sdk.hub import Hub
from sentry_sdk.scope import Scope

from sentry_sdk._types import TYPE_CHECKING
from sentry_sdk.tracing import NoOpSpan
from sentry_sdk.tracing import NoOpSpan, Transaction
from sentry_sdk.tracing_utils import (
has_tracing_enabled,
normalize_incoming_data,
)

if TYPE_CHECKING:
from typing import Any
Expand All @@ -24,7 +27,7 @@
ExcInfo,
MeasurementUnit,
)
from sentry_sdk.tracing import Span, Transaction
from sentry_sdk.tracing import Span

T = TypeVar("T")
F = TypeVar("F", bound=Callable[..., Any])
Expand Down Expand Up @@ -54,6 +57,9 @@ def overload(x):
"set_level",
"set_measurement",
"get_current_span",
"get_traceparent",
"get_baggage",
"continue_trace",
]


Expand Down Expand Up @@ -241,3 +247,54 @@ def get_current_span(hub=None):

current_span = hub.scope.span
return current_span


def get_traceparent():
# type: () -> Optional[str]
"""
Returns the traceparent either from the active span or from the scope.
"""
hub = Hub.current
if hub.client is not None:
if has_tracing_enabled(hub.client.options) and hub.scope.span is not None:
return hub.scope.span.to_traceparent()

return hub.scope.get_traceparent()


def get_baggage():
# type: () -> Optional[str]
"""
Returns Baggage either from the active span or from the scope.
"""
hub = Hub.current
if (
hub.client is not None
and has_tracing_enabled(hub.client.options)
and hub.scope.span is not None
):
baggage = hub.scope.span.to_baggage()
else:
baggage = hub.scope.get_baggage()

if baggage is not None:
return baggage.serialize()

return None


def continue_trace(environ_or_headers, op=None, name=None, source=None):
# type: (Dict[str, Any], Optional[str], Optional[str], Optional[str]) -> Transaction
"""
Sets the propagation context from environment or headers and returns a transaction.
"""
with Hub.current.configure_scope() as scope:
scope.generate_propagation_context(environ_or_headers)

transaction = Transaction.continue_from_headers(
normalize_incoming_data(environ_or_headers),
op=op,
name=name,
source=source,
)
return transaction
9 changes: 3 additions & 6 deletions sentry_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def _prepare_event(

if scope is not None:
is_transaction = event.get("type") == "transaction"
event_ = scope.apply_to_event(event, hint)
event_ = scope.apply_to_event(event, hint, self.options)

# one of the event/error processors returned None
if event_ is None:
Expand Down Expand Up @@ -507,11 +507,8 @@ def capture_event(
is_checkin = event_opt.get("type") == "check_in"
attachments = hint.get("attachments")

dynamic_sampling_context = (
event_opt.get("contexts", {})
.get("trace", {})
.pop("dynamic_sampling_context", {})
)
trace_context = event_opt.get("contexts", {}).get("trace") or {}
dynamic_sampling_context = trace_context.pop("dynamic_sampling_context", {})

# If tracing is enabled all events should go to /envelope endpoint.
# If no tracing is enabled only transactions, events with attachments, and checkins should go to the /envelope endpoint.
Expand Down
90 changes: 38 additions & 52 deletions sentry_sdk/hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from sentry_sdk.profiler import Profile
from sentry_sdk.tracing import NoOpSpan, Span, Transaction
from sentry_sdk.session import Session
from sentry_sdk.tracing_utils import has_tracing_enabled
from sentry_sdk.utils import (
exc_info_from_error,
event_from_exception,
Expand Down Expand Up @@ -322,14 +323,8 @@ def bind_client(
top = self._stack[-1]
self._stack[-1] = (new, top[1])

def capture_event(
self,
event, # type: Event
hint=None, # type: Optional[Hint]
scope=None, # type: Optional[Any]
**scope_args # type: Any
):
# type: (...) -> Optional[str]
def capture_event(self, event, hint=None, scope=None, **scope_args):
# type: (Event, Optional[Hint], Optional[Scope], Any) -> Optional[str]
"""Captures an event. Alias of :py:meth:`sentry_sdk.Client.capture_event`."""
client, top_scope = self._stack[-1]
scope = _update_scope(top_scope, scope, scope_args)
Expand All @@ -341,14 +336,8 @@ def capture_event(
return rv
return None

def capture_message(
self,
message, # type: str
level=None, # type: Optional[str]
scope=None, # type: Optional[Any]
**scope_args # type: Any
):
# type: (...) -> Optional[str]
def capture_message(self, message, level=None, scope=None, **scope_args):
# type: (str, Optional[str], Optional[Scope], Any) -> Optional[str]
"""Captures a message. The message is just a string. If no level
is provided the default level is `info`.

Expand All @@ -362,13 +351,8 @@ def capture_message(
{"message": message, "level": level}, scope=scope, **scope_args
)

def capture_exception(
self,
error=None, # type: Optional[Union[BaseException, ExcInfo]]
scope=None, # type: Optional[Any]
**scope_args # type: Any
):
# type: (...) -> Optional[str]
def capture_exception(self, error=None, scope=None, **scope_args):
# type: (Optional[Union[BaseException, ExcInfo]], Optional[Scope], Any) -> Optional[str]
"""Captures an exception.

:param error: An exception to catch. If `None`, `sys.exc_info()` will be used.
Expand Down Expand Up @@ -403,13 +387,8 @@ def _capture_internal_exception(
"""
logger.error("Internal error in sentry_sdk", exc_info=exc_info)

def add_breadcrumb(
self,
crumb=None, # type: Optional[Breadcrumb]
hint=None, # type: Optional[BreadcrumbHint]
**kwargs # type: Any
):
# type: (...) -> None
def add_breadcrumb(self, crumb=None, hint=None, **kwargs):
# type: (Optional[Breadcrumb], Optional[BreadcrumbHint], Any) -> None
"""
Adds a breadcrumb.

Expand Down Expand Up @@ -449,13 +428,8 @@ def add_breadcrumb(
while len(scope._breadcrumbs) > max_breadcrumbs:
scope._breadcrumbs.popleft()

def start_span(
self,
span=None, # type: Optional[Span]
instrumenter=INSTRUMENTER.SENTRY, # type: str
**kwargs # type: Any
):
# type: (...) -> Span
def start_span(self, span=None, instrumenter=INSTRUMENTER.SENTRY, **kwargs):
# type: (Optional[Span], str, Any) -> Span
"""
Create and start timing a new span whose parent is the currently active
span or transaction, if any. The return value is a span instance,
Expand Down Expand Up @@ -500,12 +474,9 @@ def start_span(
return Span(**kwargs)

def start_transaction(
self,
transaction=None, # type: Optional[Transaction]
instrumenter=INSTRUMENTER.SENTRY, # type: str
**kwargs # type: Any
self, transaction=None, instrumenter=INSTRUMENTER.SENTRY, **kwargs
):
# type: (...) -> Union[Transaction, NoOpSpan]
# type: (Optional[Transaction], str, Any) -> Union[Transaction, NoOpSpan]
"""
Start and return a transaction.

Expand Down Expand Up @@ -577,7 +548,9 @@ def push_scope( # noqa: F811
pass

def push_scope( # noqa
self, callback=None # type: Optional[Callable[[Scope], None]]
self,
callback=None, # type: Optional[Callable[[Scope], None]]
continue_trace=True, # type: bool
):
# type: (...) -> Optional[ContextManager[Scope]]
"""
Expand All @@ -595,7 +568,13 @@ def push_scope( # noqa
return None

client, scope = self._stack[-1]
new_layer = (client, copy.copy(scope))

new_scope = copy.copy(scope)

if continue_trace:
new_scope.generate_propagation_context()

new_layer = (client, new_scope)
self._stack.append(new_layer)

return _ScopeManager(self)
Expand Down Expand Up @@ -626,7 +605,9 @@ def configure_scope( # noqa: F811
pass

def configure_scope( # noqa
self, callback=None # type: Optional[Callable[[Scope], None]]
self,
callback=None, # type: Optional[Callable[[Scope], None]]
continue_trace=True, # type: bool
):
# type: (...) -> Optional[ContextManager[Scope]]

Expand All @@ -639,6 +620,10 @@ def configure_scope( # noqa
"""

client, scope = self._stack[-1]

if continue_trace:
scope.generate_propagation_context()

if callback is not None:
if client is not None:
callback(scope)
Expand Down Expand Up @@ -721,18 +706,19 @@ def iter_trace_propagation_headers(self, span=None):
from the span representing the request, if available, or the current
span on the scope if not.
"""
span = span or self.scope.span
if not span:
return

client = self._stack[-1][0]

propagate_traces = client and client.options["propagate_traces"]
if not propagate_traces:
return

for header in span.iter_headers():
yield header
span = span or self.scope.span

if client and has_tracing_enabled(client.options) and span is not None:
for header in span.iter_headers():
yield header
else:
for header in self.scope.iter_headers():
yield header

def trace_propagation_meta(self, span=None):
# type: (Optional[Span]) -> str
Expand Down
5 changes: 3 additions & 2 deletions sentry_sdk/integrations/aiohttp.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import sys
import weakref

from sentry_sdk.api import continue_trace
from sentry_sdk._compat import reraise
from sentry_sdk.consts import OP
from sentry_sdk.hub import Hub
Expand All @@ -11,7 +12,7 @@
_filter_headers,
request_body_within_bounds,
)
from sentry_sdk.tracing import SOURCE_FOR_STYLE, Transaction, TRANSACTION_SOURCE_ROUTE
from sentry_sdk.tracing import SOURCE_FOR_STYLE, TRANSACTION_SOURCE_ROUTE
from sentry_sdk.utils import (
capture_internal_exceptions,
event_from_exception,
Expand Down Expand Up @@ -101,7 +102,7 @@ async def sentry_app_handle(self, request, *args, **kwargs):
scope.clear_breadcrumbs()
scope.add_event_processor(_make_request_processor(weak_request))

transaction = Transaction.continue_from_headers(
transaction = continue_trace(
request.headers,
op=OP.HTTP_SERVER,
# If this transaction name makes it to the UI, AIOHTTP's
Expand Down
3 changes: 2 additions & 1 deletion sentry_sdk/integrations/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from sentry_sdk._functools import partial
from sentry_sdk._types import TYPE_CHECKING
from sentry_sdk.api import continue_trace
from sentry_sdk.consts import OP
from sentry_sdk.hub import Hub, _should_send_default_pii
from sentry_sdk.integrations._wsgi_common import _filter_headers
Expand Down Expand Up @@ -163,7 +164,7 @@ async def _run_app(self, scope, callback):
ty = scope["type"]

if ty in ("http", "websocket"):
transaction = Transaction.continue_from_headers(
transaction = continue_trace(
self._get_headers(scope),
op="{}.server".format(ty),
)
Expand Down
9 changes: 5 additions & 4 deletions sentry_sdk/integrations/aws_lambda.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
from datetime import datetime, timedelta
from os import environ

from sentry_sdk.api import continue_trace
from sentry_sdk.consts import OP
from sentry_sdk.hub import Hub, _should_send_default_pii
from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT, Transaction
from sentry_sdk._compat import reraise
from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT
from sentry_sdk.utils import (
AnnotatedValue,
capture_internal_exceptions,
Expand All @@ -16,7 +16,7 @@
)
from sentry_sdk.integrations import Integration
from sentry_sdk.integrations._wsgi_common import _filter_headers

from sentry_sdk._compat import reraise
from sentry_sdk._types import TYPE_CHECKING

if TYPE_CHECKING:
Expand Down Expand Up @@ -140,7 +140,8 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs):
# AWS Service may set an explicit `{headers: None}`, we can't rely on `.get()`'s default.
if headers is None:
headers = {}
transaction = Transaction.continue_from_headers(

transaction = continue_trace(
headers,
op=OP.FUNCTION_AWS,
name=aws_context.function_name,
Expand Down
Loading