Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add decorator for Sentry tracing #1089

Merged
merged 51 commits into from
Mar 15, 2023
Merged
Changes from 1 commit
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
bd86719
Add decorator for Sentry tracing
ynouri Apr 15, 2021
23d23de
Update decorators.py
ynouri Dec 30, 2021
af136a7
Merge branch 'master' into feature/tracing-decorator
antonpirker Mar 28, 2022
146c8ad
Merge branch 'master' into feature/tracing-decorator
antonpirker Mar 3, 2023
c0bc0d8
Linting
antonpirker Mar 3, 2023
fa6c550
Merge branch 'master' into feature/tracing-decorator
antonpirker Mar 3, 2023
9d1fb9a
Fixed syntax errors
antonpirker Mar 3, 2023
c272e17
Merge branch 'feature/tracing-decorator' of https://github.com/ynouri…
antonpirker Mar 3, 2023
b795e19
Fixed syntax error
antonpirker Mar 3, 2023
e839e4c
Try to make it work in Python 2.x
antonpirker Mar 3, 2023
99d5485
Removed transaction generation and made OP set to .
antonpirker Mar 6, 2023
1a6958f
Added function name as descripion to span.
antonpirker Mar 6, 2023
aecfda9
Merge branch 'master' into feature/tracing-decorator
antonpirker Mar 6, 2023
f8138b8
Try to make it run in Python 2
antonpirker Mar 6, 2023
c885e4c
Merge branch 'feature/tracing-decorator' of https://github.com/ynouri…
antonpirker Mar 6, 2023
05a7caa
Trying something else.
antonpirker Mar 6, 2023
33ecfcf
Merge branch 'master' into feature/tracing-decorator
antonpirker Mar 6, 2023
0160be0
Reverted changes to tracing_utils
antonpirker Mar 6, 2023
17eb234
Merge branch 'feature/tracing-decorator' of https://github.com/ynouri…
antonpirker Mar 6, 2023
1589a56
Added warning message in case there is no transaction
antonpirker Mar 6, 2023
639e190
Update sentry_sdk/tracing.py
antonpirker Mar 7, 2023
37a1b9c
Merge branch 'master' into feature/tracing-decorator
antonpirker Mar 7, 2023
0b26cf1
Added tests
antonpirker Mar 8, 2023
6635d62
Updated how to run tests
antonpirker Mar 8, 2023
10fe566
Fixed invocation of tests
antonpirker Mar 8, 2023
b293047
Fixed invocation (again)
antonpirker Mar 8, 2023
b40578a
Fixed tests
antonpirker Mar 8, 2023
333286f
Linting
antonpirker Mar 8, 2023
3e0e769
Fixed typing
antonpirker Mar 8, 2023
1bdf047
.
antonpirker Mar 8, 2023
95e877e
Create span under current span
antonpirker Mar 8, 2023
4c7f8eb
.
antonpirker Mar 8, 2023
6cf968a
More test coverage
antonpirker Mar 8, 2023
0ec4f56
Cleanup
antonpirker Mar 8, 2023
a882f54
Fixed typing
antonpirker Mar 8, 2023
e51a93f
Better naming
antonpirker Mar 8, 2023
4af3170
Added top level api to get current span and transaction
antonpirker Mar 14, 2023
4efec57
Split out function in separate PR
antonpirker Mar 14, 2023
0b3c227
Merge branch 'antonpirker/top-level-get-current-span-transaction' int…
antonpirker Mar 14, 2023
a1e49c8
Always install pytest-asyncio in Python3 to run new async tests in co…
antonpirker Mar 14, 2023
3265709
Updated test config to make it possible to have dependencies only nee…
antonpirker Mar 15, 2023
933535f
Fixed minimum Python versions the tests should run in.
antonpirker Mar 15, 2023
c124a7d
Dont run common tests in py3.4 (like it was before)
antonpirker Mar 15, 2023
d5e10fb
Updated test matrix
antonpirker Mar 15, 2023
2ede736
Trying normal fixture
antonpirker Mar 15, 2023
cefd2bc
Run asyncio tests only in python >3.6
antonpirker Mar 15, 2023
535eb74
Remove check because it is not really useful and breaks when asyncio …
antonpirker Mar 15, 2023
c1b6a6b
Fixed some tests
antonpirker Mar 15, 2023
62e5719
Use get_current_span, because it also returns the transaction if no s…
antonpirker Mar 15, 2023
6b90c09
Merge branch 'master' into feature/tracing-decorator
antonpirker Mar 15, 2023
524fb88
Linting
antonpirker Mar 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
Prev Previous commit
Next Next commit
Cleanup
antonpirker committed Mar 8, 2023
commit 0ec4f56ba8d7b5b7d4dd4c1aa63407dab1a5b69d
12 changes: 12 additions & 0 deletions sentry_sdk/tracing_utils.py
Original file line number Diff line number Diff line change
@@ -33,6 +33,8 @@
from typing import Optional
from typing import Union

from sentry_sdk import Hub


SENTRY_TRACE_REGEX = re.compile(
"^[ \t]*" # whitespace
@@ -395,6 +397,16 @@ def should_propagate_trace(hub, url):
return False


def _get_running_span_or_transaction(hub):
# type: (Hub) -> Optional[Union[Span, Transaction]]
current_span = hub.scope.span
if current_span is not None:
return current_span

transaction = hub.scope.transaction
return transaction


# Circular imports
from sentry_sdk.tracing import LOW_QUALITY_TRANSACTION_SOURCES

24 changes: 5 additions & 19 deletions sentry_sdk/tracing_utils_py2.py
Original file line number Diff line number Diff line change
@@ -2,25 +2,13 @@

import sentry_sdk
from sentry_sdk._types import TYPE_CHECKING
from sentry_sdk.tracing_utils import _get_running_span_or_transaction
from sentry_sdk.consts import OP
from sentry_sdk.utils import logger, qualname_from_function


if TYPE_CHECKING:
from typing import Any, Optional, Union

from sentry_sdk import Hub
from sentry_sdk.tracing import Span, Transaction


def _get_running_span_or_transaction(hub):
# type: (Hub) -> Optional[Union[Span, Transaction]]
current_span = hub.scope.span
if current_span is not None:
return current_span

transaction = hub.scope.transaction
return transaction
from typing import Any


def start_child_span_decorator(func):
@@ -38,19 +26,17 @@ def start_child_span_decorator(func):
def func_with_tracing(*args, **kwargs):
# type: (*Any, **Any) -> Any

transaction = _get_running_span_or_transaction()
span_or_trx = _get_running_span_or_transaction(sentry_sdk.Hub.current)

# If no transaction, do nothing
if transaction is None:
if span_or_trx is None:
logger.warning(
"No transaction found. Not creating a child span for %s. "
"Please start a Sentry transaction before calling this function.",
qualname_from_function(func),
)
return func(*args, **kwargs)

# If we have a transaction, we decorate the function!
with transaction.start_child(
with span_or_trx.start_child(
op=OP.FUNCTION,
description=qualname_from_function(func),
):
28 changes: 6 additions & 22 deletions sentry_sdk/tracing_utils_py3.py
Original file line number Diff line number Diff line change
@@ -4,24 +4,12 @@
import sentry_sdk
from sentry_sdk._types import TYPE_CHECKING
from sentry_sdk.consts import OP
from sentry_sdk.tracing_utils import _get_running_span_or_transaction
from sentry_sdk.utils import logger, qualname_from_function


if TYPE_CHECKING:
from typing import Any, Optional, Union

from sentry_sdk import Hub
from sentry_sdk.tracing import Span, Transaction


def _get_running_span_or_transaction(hub):
# type: (Hub) -> Optional[Union[Span, Transaction]]
current_span = hub.scope.span
if current_span is not None:
return current_span

transaction = hub.scope.transaction
return transaction
from typing import Any


def start_child_span_decorator(func):
@@ -42,9 +30,8 @@ def start_child_span_decorator(func):
async def func_with_tracing(*args, **kwargs):
# type: (*Any, **Any) -> Any

span_or_trx = _get_running_span_or_transaction()
span_or_trx = _get_running_span_or_transaction(sentry_sdk.Hub.current)

# If no transaction, do nothing
if span_or_trx is None:
logger.warning(
"No transaction found. Not creating a child span for %s. "
@@ -53,7 +40,6 @@ async def func_with_tracing(*args, **kwargs):
)
return await func(*args, **kwargs)

# If we have a transaction, we wrap the function.
with span_or_trx.start_child(
op=OP.FUNCTION,
description=qualname_from_function(func),
@@ -67,19 +53,17 @@ async def func_with_tracing(*args, **kwargs):
def func_with_tracing(*args, **kwargs):
# type: (*Any, **Any) -> Any

transaction = _get_running_span_or_transaction()
span_or_trx = _get_running_span_or_transaction(sentry_sdk.Hub.current)

# If no transaction, do nothing
if transaction is None:
if span_or_trx is None:
logger.warning(
"No transaction found. Not creating a child span for %s. "
"Please start a Sentry transaction before calling this function.",
qualname_from_function(func),
)
return func(*args, **kwargs)

# If we have a transaction, we decorate the function!
with transaction.start_child(
with span_or_trx.start_child(
op=OP.FUNCTION,
description=qualname_from_function(func),
):
19 changes: 0 additions & 19 deletions tests/tracing/test_decorator_py2.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import mock

import sentry_sdk
from sentry_sdk.tracing_utils_py2 import (
start_child_span_decorator as start_child_span_decorator_py2,
_get_running_span_or_transaction,
)
from sentry_sdk.utils import logger

@@ -12,23 +10,6 @@ def my_example_function():
return "return_of_sync_function"


def test_get_running_span_or_transaction():
fake_hub = mock.MagicMock()
fake_hub.scope = mock.MagicMock()

fake_hub.scope.span = mock.MagicMock()
fake_hub.scope.transaction = None
assert _get_running_span_or_transaction(fake_hub) == fake_hub.scope.span

fake_hub.scope.span = None
fake_hub.scope.transaction = mock.MagicMock()
assert _get_running_span_or_transaction(fake_hub) == fake_hub.scope.transaction

fake_hub.scope.span = None
fake_hub.scope.transaction = None
assert _get_running_span_or_transaction(fake_hub) == None


def test_trace_decorator_py2():
fake_start_child = mock.MagicMock()
fake_transaction = mock.MagicMock()
20 changes: 0 additions & 20 deletions tests/tracing/test_decorator_py3.py
Original file line number Diff line number Diff line change
@@ -2,10 +2,8 @@
import pytest
import sys

import sentry_sdk
from sentry_sdk.tracing_utils_py3 import (
start_child_span_decorator as start_child_span_decorator_py3,
_get_running_span_or_transaction,
)
from sentry_sdk.utils import logger

@@ -21,24 +19,6 @@ async def my_async_example_function():
return "return_of_async_function"


def test_get_running_span_or_transaction():
fake_hub = mock.MagicMock()
fake_hub.scope = mock.MagicMock()

fake_hub.scope.span = mock.MagicMock()
fake_hub.scope.transaction = None
assert _get_running_span_or_transaction(fake_hub) == fake_hub.scope.span

fake_hub.scope.span = None
fake_hub.scope.transaction = mock.MagicMock()
assert _get_running_span_or_transaction(fake_hub) == fake_hub.scope.transaction

fake_hub.scope.span = None
fake_hub.scope.transaction = None
assert _get_running_span_or_transaction(fake_hub) == None



def test_trace_decorator_sync_py3():
fake_start_child = mock.MagicMock()
fake_transaction = mock.MagicMock()
22 changes: 21 additions & 1 deletion tests/tracing/test_misc.py
Original file line number Diff line number Diff line change
@@ -8,7 +8,10 @@
from sentry_sdk import Hub, start_span, start_transaction, set_measurement
from sentry_sdk.consts import MATCH_ALL
from sentry_sdk.tracing import Span, Transaction
from sentry_sdk.tracing_utils import should_propagate_trace
from sentry_sdk.tracing_utils import (
should_propagate_trace,
_get_running_span_or_transaction,
)

try:
from unittest import mock # python 3.3 and above
@@ -306,3 +309,20 @@ def test_should_propagate_trace(
hub.client.options = {"trace_propagation_targets": trace_propagation_targets}

assert should_propagate_trace(hub, url) == expected_propagation_decision


def test_get_running_span_or_transaction():
fake_hub = mock.MagicMock()
fake_hub.scope = mock.MagicMock()

fake_hub.scope.span = mock.MagicMock()
fake_hub.scope.transaction = None
assert _get_running_span_or_transaction(fake_hub) == fake_hub.scope.span

fake_hub.scope.span = None
fake_hub.scope.transaction = mock.MagicMock()
assert _get_running_span_or_transaction(fake_hub) == fake_hub.scope.transaction

fake_hub.scope.span = None
fake_hub.scope.transaction = None
assert _get_running_span_or_transaction(fake_hub) is None