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
89 changes: 89 additions & 0 deletions sentry_sdk/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import logging
from typing import Optional
from functools import wraps
import inspect

import sentry_sdk

logger = logging.getLogger(__name__)


def sentry_traced(
func=None,
*,
transaction_name: Optional[str] = None,
op: Optional[str] = None,
):
"""
Function decorator to start a child under the existing current transaction or
under a new transaction, if it doesn't exist.

Args:
transaction_name: the name of the new transaction if no transaction already
exists. If a transaction is found in current scope, this name is ignored.
If no transaction is found and no transaction name is provided, no action
is taken.
op: the name of the child. Defaults to the decorated function name.

Returns:
a decorated function executing within a Sentry transaction child

Usage:
@sentry_traced
def my_function():
...

@sentry_traced(transaction_name="new_tx")
async def my_async_function():
...

@sentry_trace(op="child_name")
ynouri marked this conversation as resolved.
Show resolved Hide resolved
def my_function():
...
"""

def start_child_decorator(func):
def _transaction_and_op():
# Set transaction
transaction = sentry_sdk.Hub.current.scope.transaction
# If no current transaction we create one
if transaction_name and transaction is None:
transaction = sentry_sdk.start_transaction(name=transaction_name)
# Child name - defaults to the decorated function name
op_ = op or func.__name__
return transaction, op_

# Asynchronous case
if inspect.iscoroutinefunction(func):

@wraps(func)
async def func_with_tracing(*args, **kwargs):
transaction, op_ = _transaction_and_op()
# If no transaction, do nothing
if transaction is None:
return await func(*args, **kwargs)
# If we have a transaction, we decorate the function!
with transaction.start_child(op=op_):
return await func(*args, **kwargs)

# Synchronous case
else:

@wraps(func)
def func_with_tracing(*args, **kwargs):
transaction, op_ = _transaction_and_op()
# If no transaction, do nothing
if transaction is None:
return func(*args, **kwargs)
# If we have a transaction, we decorate the function!
with transaction.start_child(op=op_):
return func(*args, **kwargs)

return func_with_tracing

# This patterns allows usage of both @sentry_traced and @sentry_traced(...)
# See https://stackoverflow.com/questions/52126071/decorator-with-arguments-avoid-parenthesis-when-no-arguments/52126278
if func:
return start_child_decorator(func)
else:
return start_child_decorator