Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions changelog.d/7872.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a long standing bug where the tracing of async functions with opentracing was broken.
63 changes: 40 additions & 23 deletions synapse/logging/opentracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -733,37 +733,54 @@ def decorator(func):

_opname = opname if opname else func.__name__

@wraps(func)
def _trace_inner(*args, **kwargs):
if opentracing is None:
return func(*args, **kwargs)
if inspect.iscoroutinefunction(func):

scope = start_active_span(_opname)
scope.__enter__()
@wraps(func)
async def _trace_inner(*args, **kwargs):
if opentracing is None:
return await func(*args, **kwargs)

try:
result = func(*args, **kwargs)
if isinstance(result, defer.Deferred):
with start_active_span(_opname) as scope:
try:
return await func(*args, **kwargs)
except Exception:
scope.span.set_tag(tags.ERROR, True)
raise

def call_back(result):
scope.__exit__(None, None, None)
return result
else:
# The other case here handles both sync functions and those
# decorated with inlineDeferred.
@wraps(func)
def _trace_inner(*args, **kwargs):
if opentracing is None:
return func(*args, **kwargs)

def err_back(result):
scope.span.set_tag(tags.ERROR, True)
scope.__exit__(None, None, None)
return result
scope = start_active_span(_opname)
scope.__enter__()

try:
result = func(*args, **kwargs)
if isinstance(result, defer.Deferred):

def call_back(result):
scope.__exit__(None, None, None)
return result

result.addCallbacks(call_back, err_back)
def err_back(result):
scope.span.set_tag(tags.ERROR, True)
scope.__exit__(None, None, None)
return result

else:
scope.__exit__(None, None, None)
result.addCallbacks(call_back, err_back)

else:
scope.__exit__(None, None, None)

return result
return result

except Exception as e:
scope.__exit__(type(e), None, e.__traceback__)
raise
except Exception as e:
scope.__exit__(type(e), None, e.__traceback__)
raise

return _trace_inner

Expand Down