Fix the trace function for async functions. (#7872)

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
Patrick Cloke 2020-07-17 13:32:01 -04:00 committed by GitHub
parent 1ec2961b3b
commit d1d5fa66e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 25 deletions

1
changelog.d/7872.bugfix Normal file
View File

@ -0,0 +1 @@
Fix a long standing bug where the tracing of async functions with opentracing was broken.

View File

@ -733,37 +733,54 @@ def trace(func=None, opname=None):
_opname = opname if opname else func.__name__ _opname = opname if opname else func.__name__
@wraps(func) if inspect.iscoroutinefunction(func):
def _trace_inner(*args, **kwargs):
if opentracing is None:
return func(*args, **kwargs)
scope = start_active_span(_opname) @wraps(func)
scope.__enter__() async def _trace_inner(*args, **kwargs):
if opentracing is None:
return await func(*args, **kwargs)
try: with start_active_span(_opname) as scope:
result = func(*args, **kwargs) try:
if isinstance(result, defer.Deferred): return await func(*args, **kwargs)
except Exception:
def call_back(result):
scope.__exit__(None, None, None)
return result
def err_back(result):
scope.span.set_tag(tags.ERROR, True) scope.span.set_tag(tags.ERROR, True)
raise
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)
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
def err_back(result):
scope.span.set_tag(tags.ERROR, True)
scope.__exit__(None, None, None)
return result
result.addCallbacks(call_back, err_back)
else:
scope.__exit__(None, None, None) scope.__exit__(None, None, None)
return result
result.addCallbacks(call_back, err_back) return result
else: except Exception as e:
scope.__exit__(None, None, None) scope.__exit__(type(e), None, e.__traceback__)
raise
return result
except Exception as e:
scope.__exit__(type(e), None, e.__traceback__)
raise
return _trace_inner return _trace_inner