diff --git a/azure_functions_worker/bindings/__init__.py b/azure_functions_worker/bindings/__init__.py index 372cd8051..4e34b02e5 100644 --- a/azure_functions_worker/bindings/__init__.py +++ b/azure_functions_worker/bindings/__init__.py @@ -1,3 +1,4 @@ +from .tracecontext import TraceContext from .context import Context from .meta import check_input_type_annotation from .meta import check_output_type_annotation @@ -10,5 +11,5 @@ 'Out', 'Context', 'is_trigger_binding', 'check_input_type_annotation', 'check_output_type_annotation', - 'from_incoming_proto', 'to_outgoing_proto', + 'from_incoming_proto', 'to_outgoing_proto', 'TraceContext', ) diff --git a/azure_functions_worker/bindings/context.py b/azure_functions_worker/bindings/context.py index 2d3d5645a..0cbfe10a0 100644 --- a/azure_functions_worker/bindings/context.py +++ b/azure_functions_worker/bindings/context.py @@ -1,10 +1,14 @@ +from . import TraceContext + + class Context: def __init__(self, func_name: str, func_dir: str, - invocation_id: str) -> None: + invocation_id: str, trace_context: TraceContext) -> None: self.__func_name = func_name self.__func_dir = func_dir self.__invocation_id = invocation_id + self.__trace_context = trace_context @property def invocation_id(self) -> str: @@ -17,3 +21,7 @@ def function_name(self) -> str: @property def function_directory(self) -> str: return self.__func_dir + + @property + def trace_context(self) -> TraceContext: + return self.__trace_context diff --git a/azure_functions_worker/bindings/tracecontext.py b/azure_functions_worker/bindings/tracecontext.py new file mode 100644 index 000000000..ccb11bf49 --- /dev/null +++ b/azure_functions_worker/bindings/tracecontext.py @@ -0,0 +1,19 @@ +class TraceContext: + + def __init__(self, trace_parent: str, + trace_state: str, attributes: dict) -> None: + self.__trace_parent = trace_parent + self.__trace_state = trace_state + self.__attributes = attributes + + @property + def Tracestate(self) -> str: + return self.__trace_state + + @property + def Traceparent(self) -> str: + return self.__trace_parent + + @property + def Attributes(self) -> str: + return self.__attributes diff --git a/azure_functions_worker/dispatcher.py b/azure_functions_worker/dispatcher.py index 41e76a16e..659190659 100644 --- a/azure_functions_worker/dispatcher.py +++ b/azure_functions_worker/dispatcher.py @@ -269,7 +269,10 @@ async def _handle__invocation_request(self, req): invocation_id = invoc_request.invocation_id function_id = invoc_request.function_id - + trace_context = bindings.TraceContext( + invoc_request.trace_context.trace_parent, + invoc_request.trace_context.trace_state, + invoc_request.trace_context.attributes) # Set the current `invocation_id` to the current task so # that our logging handler can find it. current_task = asyncio.Task.current_task(self._loop) @@ -298,7 +301,7 @@ async def _handle__invocation_request(self, req): if fi.requires_context: args['context'] = bindings.Context( - fi.name, fi.directory, invocation_id) + fi.name, fi.directory, invocation_id, trace_context) if fi.output_types: for name in fi.output_types: diff --git a/tests/unittests/http_functions/return_context/main.py b/tests/unittests/http_functions/return_context/main.py index eb9eb3597..171248e0b 100644 --- a/tests/unittests/http_functions/return_context/main.py +++ b/tests/unittests/http_functions/return_context/main.py @@ -9,4 +9,6 @@ def main(req: azure.functions.HttpRequest, context: azure.functions.Context): 'ctx_func_name': context.function_name, 'ctx_func_dir': context.function_directory, 'ctx_invocation_id': context.invocation_id, + 'ctx_trace_context_Traceparent': context.trace_context.Traceparent, + 'ctx_trace_context_Tracestate': context.trace_context.Tracestate, }) diff --git a/tests/unittests/test_http_functions.py b/tests/unittests/test_http_functions.py index 4cedd5540..6d1b0c879 100644 --- a/tests/unittests/test_http_functions.py +++ b/tests/unittests/test_http_functions.py @@ -104,6 +104,8 @@ def test_return_context(self): self.assertEqual(data['ctx_func_name'], 'return_context') self.assertIn('return_context', data['ctx_func_dir']) self.assertIn('ctx_invocation_id', data) + self.assertIn('ctx_trace_context_Tracestate', data) + self.assertIn('ctx_trace_context_Traceparent', data) def test_remapped_context(self): r = self.webhost.request('GET', 'remapped_context')