Skip to content

Commit 44f2b91

Browse files
committed
fix: Python 3.13 OTel Initialization
1 parent 9c39445 commit 44f2b91

3 files changed

Lines changed: 46 additions & 8 deletions

File tree

‎runtimes/v2/azure_functions_runtime/handle_event.py‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
)
1919
from .loader import index_function_app, process_indexed_function
2020
from .logging import logger
21-
from .otel import otel_manager, configure_opentelemetry, initialize_azure_monitor
21+
from .otel import (configure_opentelemetry,
22+
initialize_azure_monitor,
23+
otel_manager,
24+
update_opentelemetry_status)
2225
from .version import VERSION
2326

2427
from .bindings.context import get_context
@@ -86,6 +89,7 @@ async def worker_init_request(request):
8689

8790
if is_envvar_true(PYTHON_ENABLE_OPENTELEMETRY):
8891
otel_manager.set_otel_libs_available(True)
92+
update_opentelemetry_status()
8993

9094
if (otel_manager.get_azure_monitor_available()
9195
or otel_manager.get_otel_libs_available()):
@@ -337,6 +341,7 @@ async def function_environment_reload_request(request):
337341
capabilities = {}
338342
if is_envvar_true(PYTHON_ENABLE_OPENTELEMETRY):
339343
otel_manager.set_otel_libs_available(True)
344+
update_opentelemetry_status()
340345

341346
if is_envvar_true(PYTHON_APPLICATIONINSIGHTS_ENABLE_TELEMETRY):
342347
initialize_azure_monitor()

‎runtimes/v2/azure_functions_runtime/otel.py‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,15 @@ def initialize_azure_monitor():
107107

108108

109109
def configure_opentelemetry(invocation_context):
110+
trace_context_propagator = otel_manager.get_trace_context_propagator()
111+
context_api = otel_manager.get_context_api()
112+
if trace_context_propagator is None or context_api is None:
113+
return
114+
110115
carrier = {TRACEPARENT: invocation_context.trace_context.trace_parent,
111116
TRACESTATE: invocation_context.trace_context.trace_state}
112-
ctx = otel_manager.get_trace_context_propagator().extract(carrier)
113-
otel_manager.get_context_api().attach(ctx)
117+
ctx = trace_context_propagator.extract(carrier)
118+
context_api.attach(ctx)
114119

115120

116121
otel_manager = OTelManager()

‎runtimes/v2/tests/unittests/test_opentelemetry.py‎

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
import asyncio
23
import os
34
import unittest
45

56
import tests.protos as protos
67

78
from azure_functions_runtime.handle_event import otel_manager, worker_init_request
8-
from azure_functions_runtime.otel import (initialize_azure_monitor,
9+
from azure_functions_runtime.otel import (configure_opentelemetry,
10+
initialize_azure_monitor,
911
update_opentelemetry_status,
1012
OTelManager)
1113
from azure_functions_runtime.logging import logger
@@ -19,6 +21,24 @@
1921

2022
class TestOpenTelemetry(unittest.TestCase):
2123

24+
def setUp(self):
25+
self._otel_manager_state = (
26+
otel_manager.get_azure_monitor_available(),
27+
otel_manager.get_otel_libs_available(),
28+
otel_manager.get_context_api(),
29+
otel_manager.get_trace_context_propagator(),
30+
)
31+
32+
def tearDown(self):
33+
(azure_monitor_available,
34+
otel_libs_available,
35+
context_api,
36+
trace_context_propagator) = self._otel_manager_state
37+
otel_manager.set_azure_monitor_available(azure_monitor_available)
38+
otel_manager.set_otel_libs_available(otel_libs_available)
39+
otel_manager.set_context_api(context_api)
40+
otel_manager.set_trace_context_propagator(trace_context_propagator)
41+
2242
def test_update_opentelemetry_status_import_error(self):
2343
with patch.dict('sys.modules', {
2444
'opentelemetry': None,
@@ -43,6 +63,12 @@ def test_update_opentelemetry_status_success(
4363
self.assertIsNotNone(otel_manager.get_context_api())
4464
self.assertIsNotNone(otel_manager.get_trace_context_propagator())
4565

66+
def test_configure_opentelemetry_noops_when_not_initialized(self):
67+
otel_manager.set_context_api(None)
68+
otel_manager.set_trace_context_propagator(None)
69+
70+
configure_opentelemetry(MagicMock())
71+
4672
@patch('builtins.__import__')
4773
@patch("azure_functions_runtime.otel.update_opentelemetry_status")
4874
def test_initialize_azure_monitor_success(
@@ -146,7 +172,7 @@ async def test_init_request_initialize_azure_monitor_disabled_app_setting(
146172
self.assertNotIn("WorkerOpenTelemetryEnabled", capabilities)
147173

148174
@patch.dict(os.environ, {'PYTHON_ENABLE_OPENTELEMETRY': 'true'})
149-
async def test_init_request_enable_opentelemetry_enabled_app_setting(
175+
def test_init_request_enable_opentelemetry_enabled_app_setting(
150176
self,
151177
):
152178
worker_request = WorkerRequest(name='worker_init_request',
@@ -155,13 +181,15 @@ async def test_init_request_enable_opentelemetry_enabled_app_setting(
155181
FUNCTION_APP_DIRECTORY)),
156182
properties={'host': '123',
157183
'protos': protos})
158-
init_response = await worker_init_request(worker_request)
184+
init_response = asyncio.run(worker_init_request(worker_request))
159185

160186
self.assertEqual(init_response.result.status,
161187
protos.StatusResult.Success)
162188

163-
# Verify otel_libs_available is set to True
164-
self.assertTrue(otel_manager.get_azure_monitor_available())
189+
# Verify OpenTelemetry propagation is initialized
190+
self.assertTrue(otel_manager.get_otel_libs_available())
191+
self.assertIsNotNone(otel_manager.get_context_api())
192+
self.assertIsNotNone(otel_manager.get_trace_context_propagator())
165193
# Verify that WorkerOpenTelemetryEnabled capability is set to _TRUE
166194
capabilities = init_response.capabilities
167195
self.assertIn("WorkerOpenTelemetryEnabled", capabilities)

0 commit comments

Comments
 (0)