From 04e56c8c86fed83526c0b528e93b672c8248c0e1 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 11 Jun 2024 14:29:02 -0700 Subject: [PATCH 01/15] distro-commit --- azure_functions_worker/constants.py | 12 +++++++++- azure_functions_worker/dispatcher.py | 36 +++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/azure_functions_worker/constants.py b/azure_functions_worker/constants.py index 69c59ad0b..f1f4decdb 100644 --- a/azure_functions_worker/constants.py +++ b/azure_functions_worker/constants.py @@ -81,5 +81,15 @@ # Base extension supported Python minor version BASE_EXT_SUPPORTED_PY_MINOR_VERSION = 8 +# Appsetting to turn on OpenTelemetry support/features +# Includes turning on Azure monitor distro to send telemetry to Application Insights PYTHON_ENABLE_OPENTELEMETRY = "PYTHON_ENABLE_OPENTELEMETRY" -PYTHON_ENABLE_OPENTELEMETRY_DEFAULT = True +PYTHON_ENABLE_OPENTELEMETRY_DEFAULT = False + +# Appsetting to specify root logger name of logger to collect telemetry for +# Used by Azure monitor distro +PYTHON_AZURE_MONITOR_LOGGER_NAME = "PYTHON_AZURE_MONITOR_LOGGER_NAME" +PYTHON_AZURE_MONITOR_LOGGER_NAME_DEFAULT = "" + +# Appsetting to specify AppInsights connection string +APPLICATIONINSIGHTS_CONNECTION_STRING = "APPLICATIONINSIGHTS_CONNECTION_STRING" diff --git a/azure_functions_worker/dispatcher.py b/azure_functions_worker/dispatcher.py index 807985cc6..1572bb689 100644 --- a/azure_functions_worker/dispatcher.py +++ b/azure_functions_worker/dispatcher.py @@ -21,7 +21,8 @@ import grpc from . import bindings, constants, functions, loader, protos from .bindings.shared_memory_data_transfer import SharedMemoryManager -from .constants import (PYTHON_ROLLBACK_CWD_PATH, +from .constants import (APPLICATIONINSIGHTS_CONNECTION_STRING, + PYTHON_ROLLBACK_CWD_PATH, PYTHON_THREADPOOL_THREAD_COUNT, PYTHON_THREADPOOL_THREAD_COUNT_DEFAULT, PYTHON_THREADPOOL_THREAD_COUNT_MAX_37, @@ -31,8 +32,10 @@ PYTHON_SCRIPT_FILE_NAME_DEFAULT, PYTHON_LANGUAGE_RUNTIME, PYTHON_ENABLE_INIT_INDEXING, METADATA_PROPERTIES_WORKER_INDEXED, + PYTHON_AZURE_MONITOR_LOGGER_NAME, + PYTHON_AZURE_MONITOR_LOGGER_NAME_DEFAULT, PYTHON_ENABLE_OPENTELEMETRY, - PYTHON_ENABLE_OPENTELEMETRY_DEFAULT) + PYTHON_ENABLE_OPENTELEMETRY_DEFAULT,) from .extension import ExtensionManager from .http_v2 import http_coordinator, initialize_http_server, HttpV2Registry, \ sync_http_request, HttpServerInitError @@ -274,6 +277,33 @@ async def _dispatch_grpc_request(self, request): resp = await request_handler(request) self._grpc_resp_queue.put_nowait(resp) + def initialize_opentelemetry(self): + """Initializes OpenTelemetry and Azure monitor distro + """ + self.update_opentelemetry_status() + try: + from azure.monitor.opentelemetry import configure_azure_monitor + + configure_azure_monitor( + # Connection string can be explicitly specified in Appsetting + # If not set, env var APPLICATIONINSIGHTS_CONNECTION_STRING is used + connection_string=get_app_setting(setting=APPLICATIONINSIGHTS_CONNECTION_STRING), + logger_name=get_app_setting(setting=PYTHON_AZURE_MONITOR_LOGGER_NAME, + default_value=PYTHON_AZURE_MONITOR_LOGGER_NAME_DEFAULT), + ) + + logger.info("Successfully configured Azure monitor distro.") + except ImportError: + logger.exception( + "Cannot import Azure Monitor distro." + ) + self._otel_libs_available = False + except Exception: + logger.exception( + "Error initializing Azure monitor distro." + ) + self._otel_libs_available = False + def update_opentelemetry_status(self): """Check for OpenTelemetry library availability and update the status attribute.""" @@ -322,7 +352,7 @@ async def _handle__worker_init_request(self, request): if get_app_setting(setting=PYTHON_ENABLE_OPENTELEMETRY, default_value=PYTHON_ENABLE_OPENTELEMETRY_DEFAULT): - self.update_opentelemetry_status() + self.initialize_opentelemetry() if self._otel_libs_available: capabilities[constants.WORKER_OPEN_TELEMETRY_ENABLED] = _TRUE From 1f173df93eeb8c50431df1be161a5c6268bca147 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 11 Jun 2024 15:38:23 -0700 Subject: [PATCH 02/15] resource detector --- azure_functions_worker/dispatcher.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/azure_functions_worker/dispatcher.py b/azure_functions_worker/dispatcher.py index 1572bb689..a4b3e00aa 100644 --- a/azure_functions_worker/dispatcher.py +++ b/azure_functions_worker/dispatcher.py @@ -284,6 +284,12 @@ def initialize_opentelemetry(self): try: from azure.monitor.opentelemetry import configure_azure_monitor + # Set resource detector manually until officially supported in distro + os.environ.setdefault( + "OTEL_EXPERIMENTAL_RESOURCE_DETECTORS", + "azure_functions", + ) + configure_azure_monitor( # Connection string can be explicitly specified in Appsetting # If not set, env var APPLICATIONINSIGHTS_CONNECTION_STRING is used From 2281262fa2993e335985aea5e438123cae0a4e1e Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Wed, 26 Jun 2024 12:33:41 -0700 Subject: [PATCH 03/15] tests --- azure_functions_worker/dispatcher.py | 2 +- tests/unittests/test_opentelemetry.py | 53 +++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/azure_functions_worker/dispatcher.py b/azure_functions_worker/dispatcher.py index a4b3e00aa..e813163a5 100644 --- a/azure_functions_worker/dispatcher.py +++ b/azure_functions_worker/dispatcher.py @@ -297,6 +297,7 @@ def initialize_opentelemetry(self): logger_name=get_app_setting(setting=PYTHON_AZURE_MONITOR_LOGGER_NAME, default_value=PYTHON_AZURE_MONITOR_LOGGER_NAME_DEFAULT), ) + self._otel_libs_available = True logger.info("Successfully configured Azure monitor distro.") except ImportError: @@ -355,7 +356,6 @@ async def _handle__worker_init_request(self, request): constants.RPC_HTTP_TRIGGER_METADATA_REMOVED: _TRUE, constants.SHARED_MEMORY_DATA_TRANSFER: _TRUE, } - if get_app_setting(setting=PYTHON_ENABLE_OPENTELEMETRY, default_value=PYTHON_ENABLE_OPENTELEMETRY_DEFAULT): self.initialize_opentelemetry() diff --git a/tests/unittests/test_opentelemetry.py b/tests/unittests/test_opentelemetry.py index bf785b7a6..22c4bdb17 100644 --- a/tests/unittests/test_opentelemetry.py +++ b/tests/unittests/test_opentelemetry.py @@ -32,9 +32,39 @@ def test_update_opentelemetry_status_success( self.assertTrue(self.dispatcher._otel_libs_available) @patch('builtins.__import__') - def test_init_request_otel_capability_enabled( - self, mock_imports): + @patch("azure_functions_worker.dispatcher.Dispatcher.update_opentelemetry_status") + def test_initialize_opentelemetry_success( + self, + mock_update_ot, + mock_imports, + ): mock_imports.return_value = MagicMock() + self.dispatcher.initialize_opentelemetry() + mock_update_ot.assert_called_once() + self.assertTrue(self.dispatcher._otel_libs_available) + + @patch("azure_functions_worker.dispatcher.Dispatcher.update_opentelemetry_status") + def test_initialize_opentelemetry_import_error( + self, + mock_update_ot, + ): + with patch('builtins.__import__', side_effect=ImportError): + self.dispatcher.initialize_opentelemetry() + mock_update_ot.assert_called_once() + # Verify that otel_libs_available is set to False due to ImportError + self.assertFalse(self.dispatcher._otel_libs_available) + + @patch("os.environ.setdefault") + @patch("azure_functions_worker.dispatcher.get_app_setting") + @patch('builtins.__import__') + def test_init_request_otel_capability_enabled_app_setting( + self, + mock_imports, + mock_app_setting, + mock_environ, + ): + mock_imports.return_value = MagicMock() + mock_app_setting.return_value = True init_request = protos.StreamingMessage( worker_init_request=protos.WorkerInitRequest( @@ -49,12 +79,25 @@ def test_init_request_otel_capability_enabled( self.assertEqual(init_response.worker_init_response.result.status, protos.StatusResult.Success) + # Verify that Azure functions resource detector is set in env + mock_environ.assert_called_with( + "OTEL_EXPERIMENTAL_RESOURCE_DETECTORS", + "azure_functions", + ) + # Verify that WorkerOpenTelemetryEnabled capability is set to _TRUE capabilities = init_response.worker_init_response.capabilities self.assertIn("WorkerOpenTelemetryEnabled", capabilities) self.assertEqual(capabilities["WorkerOpenTelemetryEnabled"], "true") - def test_init_request_otel_capability_disabled(self): + @patch("azure_functions_worker.dispatcher.Dispatcher.initialize_opentelemetry") + @patch("azure_functions_worker.dispatcher.get_app_setting") + def test_init_request_otel_capability_disabled_app_setting( + self, + mock_app_setting, + mock_initialize_ot, + ): + mock_app_setting.return_value = False init_request = protos.StreamingMessage( worker_init_request=protos.WorkerInitRequest( @@ -69,5 +112,9 @@ def test_init_request_otel_capability_disabled(self): self.assertEqual(init_response.worker_init_response.result.status, protos.StatusResult.Success) + # OpenTelemetry initialized not called + mock_initialize_ot.assert_not_called() + + # Verify that WorkerOpenTelemetryEnabled capability is not set capabilities = init_response.worker_init_response.capabilities self.assertNotIn("WorkerOpenTelemetryEnabled", capabilities) From 3826beb7578aea79bd7d5728ccb3d1ccdcd9939d Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 2 Jul 2024 08:42:49 -0700 Subject: [PATCH 04/15] lint --- azure_functions_worker/dispatcher.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/azure_functions_worker/dispatcher.py b/azure_functions_worker/dispatcher.py index e813163a5..cf73e0306 100644 --- a/azure_functions_worker/dispatcher.py +++ b/azure_functions_worker/dispatcher.py @@ -284,7 +284,8 @@ def initialize_opentelemetry(self): try: from azure.monitor.opentelemetry import configure_azure_monitor - # Set resource detector manually until officially supported in distro + # Set functions resource detector manually until officially + # include in Azure monitor distro os.environ.setdefault( "OTEL_EXPERIMENTAL_RESOURCE_DETECTORS", "azure_functions", @@ -292,10 +293,15 @@ def initialize_opentelemetry(self): configure_azure_monitor( # Connection string can be explicitly specified in Appsetting - # If not set, env var APPLICATIONINSIGHTS_CONNECTION_STRING is used - connection_string=get_app_setting(setting=APPLICATIONINSIGHTS_CONNECTION_STRING), - logger_name=get_app_setting(setting=PYTHON_AZURE_MONITOR_LOGGER_NAME, - default_value=PYTHON_AZURE_MONITOR_LOGGER_NAME_DEFAULT), + # If not set, defaults to env var + # APPLICATIONINSIGHTS_CONNECTION_STRING + connection_string=get_app_setting( + setting=APPLICATIONINSIGHTS_CONNECTION_STRING + ), + logger_name=get_app_setting( + setting=PYTHON_AZURE_MONITOR_LOGGER_NAME, + default_value=PYTHON_AZURE_MONITOR_LOGGER_NAME_DEFAULT + ), ) self._otel_libs_available = True From cd499501f866cdc2890d040c40aae9332662468e Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 2 Jul 2024 08:54:15 -0700 Subject: [PATCH 05/15] Update constants.py --- azure_functions_worker/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure_functions_worker/constants.py b/azure_functions_worker/constants.py index f1f4decdb..6611a919c 100644 --- a/azure_functions_worker/constants.py +++ b/azure_functions_worker/constants.py @@ -82,7 +82,7 @@ BASE_EXT_SUPPORTED_PY_MINOR_VERSION = 8 # Appsetting to turn on OpenTelemetry support/features -# Includes turning on Azure monitor distro to send telemetry to Application Insights +# Includes turning on Azure monitor distro to send telemetry to AppInsights PYTHON_ENABLE_OPENTELEMETRY = "PYTHON_ENABLE_OPENTELEMETRY" PYTHON_ENABLE_OPENTELEMETRY_DEFAULT = False From 82d535b7ca642cd7cfd49d87ebf0f1905fba832c Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Wed, 3 Jul 2024 13:42:56 -0700 Subject: [PATCH 06/15] fix --- tests/unittests/test_opentelemetry.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/unittests/test_opentelemetry.py b/tests/unittests/test_opentelemetry.py index 22c4bdb17..6c1cd3568 100644 --- a/tests/unittests/test_opentelemetry.py +++ b/tests/unittests/test_opentelemetry.py @@ -1,4 +1,5 @@ import asyncio +import os import unittest from unittest.mock import patch, MagicMock @@ -53,16 +54,16 @@ def test_initialize_opentelemetry_import_error( mock_update_ot.assert_called_once() # Verify that otel_libs_available is set to False due to ImportError self.assertFalse(self.dispatcher._otel_libs_available) - - @patch("os.environ.setdefault") + @patch("azure_functions_worker.dispatcher.get_app_setting") @patch('builtins.__import__') def test_init_request_otel_capability_enabled_app_setting( - self, + self, mock_imports, mock_app_setting, - mock_environ, - ): + ): + if "OTEL_EXPERIMENTAL_RESOURCE_DETECTORS" in os.environ: + del os.environ["OTEL_EXPERIMENTAL_RESOURCE_DETECTORS"] mock_imports.return_value = MagicMock() mock_app_setting.return_value = True @@ -80,16 +81,16 @@ def test_init_request_otel_capability_enabled_app_setting( protos.StatusResult.Success) # Verify that Azure functions resource detector is set in env - mock_environ.assert_called_with( - "OTEL_EXPERIMENTAL_RESOURCE_DETECTORS", - "azure_functions", - ) + self.assertEqual(os.environ.get("OTEL_EXPERIMENTAL_RESOURCE_DETECTORS"), "azure_functions") # Verify that WorkerOpenTelemetryEnabled capability is set to _TRUE capabilities = init_response.worker_init_response.capabilities self.assertIn("WorkerOpenTelemetryEnabled", capabilities) self.assertEqual(capabilities["WorkerOpenTelemetryEnabled"], "true") + if "OTEL_EXPERIMENTAL_RESOURCE_DETECTORS" in os.environ: + del os.environ["OTEL_EXPERIMENTAL_RESOURCE_DETECTORS"] + @patch("azure_functions_worker.dispatcher.Dispatcher.initialize_opentelemetry") @patch("azure_functions_worker.dispatcher.get_app_setting") def test_init_request_otel_capability_disabled_app_setting( From 5e95655a7cb323bf718752a8f04bf62989abb197 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Wed, 3 Jul 2024 15:14:42 -0700 Subject: [PATCH 07/15] Update test_opentelemetry.py --- tests/unittests/test_opentelemetry.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/unittests/test_opentelemetry.py b/tests/unittests/test_opentelemetry.py index 6c1cd3568..e6c0cccf5 100644 --- a/tests/unittests/test_opentelemetry.py +++ b/tests/unittests/test_opentelemetry.py @@ -62,8 +62,6 @@ def test_init_request_otel_capability_enabled_app_setting( mock_imports, mock_app_setting, ): - if "OTEL_EXPERIMENTAL_RESOURCE_DETECTORS" in os.environ: - del os.environ["OTEL_EXPERIMENTAL_RESOURCE_DETECTORS"] mock_imports.return_value = MagicMock() mock_app_setting.return_value = True @@ -80,17 +78,11 @@ def test_init_request_otel_capability_enabled_app_setting( self.assertEqual(init_response.worker_init_response.result.status, protos.StatusResult.Success) - # Verify that Azure functions resource detector is set in env - self.assertEqual(os.environ.get("OTEL_EXPERIMENTAL_RESOURCE_DETECTORS"), "azure_functions") - # Verify that WorkerOpenTelemetryEnabled capability is set to _TRUE capabilities = init_response.worker_init_response.capabilities self.assertIn("WorkerOpenTelemetryEnabled", capabilities) self.assertEqual(capabilities["WorkerOpenTelemetryEnabled"], "true") - if "OTEL_EXPERIMENTAL_RESOURCE_DETECTORS" in os.environ: - del os.environ["OTEL_EXPERIMENTAL_RESOURCE_DETECTORS"] - @patch("azure_functions_worker.dispatcher.Dispatcher.initialize_opentelemetry") @patch("azure_functions_worker.dispatcher.get_app_setting") def test_init_request_otel_capability_disabled_app_setting( From 74114c87d639cd049814efd955cd87a3bf2c6681 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Wed, 3 Jul 2024 16:06:41 -0700 Subject: [PATCH 08/15] Update test_opentelemetry.py --- tests/unittests/test_opentelemetry.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unittests/test_opentelemetry.py b/tests/unittests/test_opentelemetry.py index e6c0cccf5..ff19c3836 100644 --- a/tests/unittests/test_opentelemetry.py +++ b/tests/unittests/test_opentelemetry.py @@ -1,5 +1,4 @@ import asyncio -import os import unittest from unittest.mock import patch, MagicMock From 84a41ed869ad07576cef8c01158d61b5c3902475 Mon Sep 17 00:00:00 2001 From: Victoria Hall Date: Wed, 31 Jul 2024 10:54:39 -0500 Subject: [PATCH 09/15] fixing tests, added setting to logs --- azure_functions_worker/dispatcher.py | 3 +++ azure_functions_worker/utils/app_setting_manager.py | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/azure_functions_worker/dispatcher.py b/azure_functions_worker/dispatcher.py index b923f3dd8..1013c10e1 100644 --- a/azure_functions_worker/dispatcher.py +++ b/azure_functions_worker/dispatcher.py @@ -36,6 +36,9 @@ PYTHON_THREADPOOL_THREAD_COUNT_DEFAULT, PYTHON_THREADPOOL_THREAD_COUNT_MAX_37, PYTHON_THREADPOOL_THREAD_COUNT_MIN, + APPLICATIONINSIGHTS_CONNECTION_STRING, + PYTHON_AZURE_MONITOR_LOGGER_NAME, + PYTHON_AZURE_MONITOR_LOGGER_NAME_DEFAULT ) from .extension import ExtensionManager from .http_v2 import ( diff --git a/azure_functions_worker/utils/app_setting_manager.py b/azure_functions_worker/utils/app_setting_manager.py index bffec8ddf..f4d70fe1d 100644 --- a/azure_functions_worker/utils/app_setting_manager.py +++ b/azure_functions_worker/utils/app_setting_manager.py @@ -14,6 +14,7 @@ PYTHON_ROLLBACK_CWD_PATH, PYTHON_SCRIPT_FILE_NAME, PYTHON_THREADPOOL_THREAD_COUNT, + PYTHON_ENABLE_OPENTELEMETRY ) @@ -27,7 +28,8 @@ def get_python_appsetting_state(): PYTHON_ENABLE_WORKER_EXTENSIONS, FUNCTIONS_WORKER_SHARED_MEMORY_DATA_TRANSFER_ENABLED, PYTHON_SCRIPT_FILE_NAME, - PYTHON_ENABLE_INIT_INDEXING] + PYTHON_ENABLE_INIT_INDEXING, + PYTHON_ENABLE_OPENTELEMETRY] app_setting_states = "".join( f"{app_setting}: {current_vars[app_setting]} | " From f298073e60f1e924e06b0789ecb8665be48a8c55 Mon Sep 17 00:00:00 2001 From: Victoria Hall Date: Wed, 31 Jul 2024 10:58:51 -0500 Subject: [PATCH 10/15] reordered import statements --- azure_functions_worker/dispatcher.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/azure_functions_worker/dispatcher.py b/azure_functions_worker/dispatcher.py index 1013c10e1..a54406b1a 100644 --- a/azure_functions_worker/dispatcher.py +++ b/azure_functions_worker/dispatcher.py @@ -23,7 +23,10 @@ from . import bindings, constants, functions, loader, protos from .bindings.shared_memory_data_transfer import SharedMemoryManager from .constants import ( + APPLICATIONINSIGHTS_CONNECTION_STRING, METADATA_PROPERTIES_WORKER_INDEXED, + PYTHON_AZURE_MONITOR_LOGGER_NAME, + PYTHON_AZURE_MONITOR_LOGGER_NAME_DEFAULT, PYTHON_ENABLE_DEBUG_LOGGING, PYTHON_ENABLE_INIT_INDEXING, PYTHON_ENABLE_OPENTELEMETRY, @@ -35,10 +38,7 @@ PYTHON_THREADPOOL_THREAD_COUNT, PYTHON_THREADPOOL_THREAD_COUNT_DEFAULT, PYTHON_THREADPOOL_THREAD_COUNT_MAX_37, - PYTHON_THREADPOOL_THREAD_COUNT_MIN, - APPLICATIONINSIGHTS_CONNECTION_STRING, - PYTHON_AZURE_MONITOR_LOGGER_NAME, - PYTHON_AZURE_MONITOR_LOGGER_NAME_DEFAULT + PYTHON_THREADPOOL_THREAD_COUNT_MIN ) from .extension import ExtensionManager from .http_v2 import ( From 1c08f2457ca81b01e73ff6f0c72abea8584bb290 Mon Sep 17 00:00:00 2001 From: Victoria Hall Date: Wed, 31 Jul 2024 11:02:56 -0500 Subject: [PATCH 11/15] formatting --- azure_functions_worker/dispatcher.py | 2 +- azure_functions_worker/utils/app_setting_manager.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/azure_functions_worker/dispatcher.py b/azure_functions_worker/dispatcher.py index a54406b1a..3e53076b5 100644 --- a/azure_functions_worker/dispatcher.py +++ b/azure_functions_worker/dispatcher.py @@ -38,7 +38,7 @@ PYTHON_THREADPOOL_THREAD_COUNT, PYTHON_THREADPOOL_THREAD_COUNT_DEFAULT, PYTHON_THREADPOOL_THREAD_COUNT_MAX_37, - PYTHON_THREADPOOL_THREAD_COUNT_MIN + PYTHON_THREADPOOL_THREAD_COUNT_MIN, ) from .extension import ExtensionManager from .http_v2 import ( diff --git a/azure_functions_worker/utils/app_setting_manager.py b/azure_functions_worker/utils/app_setting_manager.py index f4d70fe1d..3d8ccbb45 100644 --- a/azure_functions_worker/utils/app_setting_manager.py +++ b/azure_functions_worker/utils/app_setting_manager.py @@ -7,6 +7,7 @@ FUNCTIONS_WORKER_SHARED_MEMORY_DATA_TRANSFER_ENABLED, PYTHON_ENABLE_DEBUG_LOGGING, PYTHON_ENABLE_INIT_INDEXING, + PYTHON_ENABLE_OPENTELEMETRY, PYTHON_ENABLE_WORKER_EXTENSIONS, PYTHON_ENABLE_WORKER_EXTENSIONS_DEFAULT, PYTHON_ENABLE_WORKER_EXTENSIONS_DEFAULT_39, @@ -14,7 +15,6 @@ PYTHON_ROLLBACK_CWD_PATH, PYTHON_SCRIPT_FILE_NAME, PYTHON_THREADPOOL_THREAD_COUNT, - PYTHON_ENABLE_OPENTELEMETRY ) From d13be182b90206e2bfddc7132d6cf27934955d99 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Wed, 31 Jul 2024 14:07:04 -0700 Subject: [PATCH 12/15] rename --- azure_functions_worker/dispatcher.py | 25 ++++++++++++------------- tests/unittests/test_opentelemetry.py | 25 +++++++++++++------------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/azure_functions_worker/dispatcher.py b/azure_functions_worker/dispatcher.py index 3e53076b5..355f546e8 100644 --- a/azure_functions_worker/dispatcher.py +++ b/azure_functions_worker/dispatcher.py @@ -102,7 +102,7 @@ def __init__(self, loop: BaseEventLoop, host: str, port: int, self._function_metadata_exception = None # Used for checking if open telemetry is enabled - self._otel_libs_available = False + self._azure_monitor_available = False self._context_api = None self._trace_context_propagator = None @@ -291,7 +291,7 @@ async def _dispatch_grpc_request(self, request): resp = await request_handler(request) self._grpc_resp_queue.put_nowait(resp) - def initialize_opentelemetry(self): + def initialize_azure_monitor(self): """Initializes OpenTelemetry and Azure monitor distro """ self.update_opentelemetry_status() @@ -317,19 +317,19 @@ def initialize_opentelemetry(self): default_value=PYTHON_AZURE_MONITOR_LOGGER_NAME_DEFAULT ), ) - self._otel_libs_available = True + self._azure_monitor_available = True logger.info("Successfully configured Azure monitor distro.") except ImportError: logger.exception( "Cannot import Azure Monitor distro." ) - self._otel_libs_available = False + self._azure_monitor_available = False except Exception: logger.exception( "Error initializing Azure monitor distro." ) - self._otel_libs_available = False + self._azure_monitor_available = False def update_opentelemetry_status(self): """Check for OpenTelemetry library availability and @@ -342,12 +342,11 @@ def update_opentelemetry_status(self): self._context_api = context_api self._trace_context_propagator = TraceContextTextMapPropagator() - self._otel_libs_available = True logger.info("Successfully loaded OpenTelemetry modules. " "OpenTelemetry is now enabled.") except ImportError: - self._otel_libs_available = False + self._azure_monitor_available = False async def _handle__worker_init_request(self, request): logger.info('Received WorkerInitRequest, ' @@ -379,9 +378,9 @@ async def _handle__worker_init_request(self, request): } if get_app_setting(setting=PYTHON_ENABLE_OPENTELEMETRY, default_value=PYTHON_ENABLE_OPENTELEMETRY_DEFAULT): - self.initialize_opentelemetry() + self.initialize_azure_monitor() - if self._otel_libs_available: + if self._azure_monitor_available: capabilities[constants.WORKER_OPEN_TELEMETRY_ENABLED] = _TRUE if DependencyManager.should_load_cx_dependencies(): @@ -653,7 +652,7 @@ async def _handle__invocation_request(self, request): args[name] = bindings.Out() if fi.is_async: - if self._otel_libs_available: + if self._azure_monitor_available: self.configure_opentelemetry(fi_context) call_result = \ @@ -773,9 +772,9 @@ async def _handle__function_environment_reload_request(self, request): if get_app_setting( setting=PYTHON_ENABLE_OPENTELEMETRY, default_value=PYTHON_ENABLE_OPENTELEMETRY_DEFAULT): - self.update_opentelemetry_status() + self.initialize_azure_monitor() - if self._otel_libs_available: + if self._azure_monitor_available: capabilities[constants.WORKER_OPEN_TELEMETRY_ENABLED] = ( _TRUE) @@ -986,7 +985,7 @@ def _run_sync_func(self, invocation_id, context, func, params): # invocation_id from ThreadPoolExecutor's threads. context.thread_local_storage.invocation_id = invocation_id try: - if self._otel_libs_available: + if self._azure_monitor_available: self.configure_opentelemetry(context) return ExtensionManager.get_sync_invocation_wrapper(context, func)(params) diff --git a/tests/unittests/test_opentelemetry.py b/tests/unittests/test_opentelemetry.py index 89ef953f5..ce28e2583 100644 --- a/tests/unittests/test_opentelemetry.py +++ b/tests/unittests/test_opentelemetry.py @@ -23,37 +23,38 @@ def test_update_opentelemetry_status_import_error(self): with patch('builtins.__import__', side_effect=ImportError): self.dispatcher.update_opentelemetry_status() # Verify that otel_libs_available is set to False due to ImportError - self.assertFalse(self.dispatcher._otel_libs_available) + self.assertFalse(self.dispatcher._azure_monitor_available) @patch('builtins.__import__') def test_update_opentelemetry_status_success( self, mock_imports): mock_imports.return_value = MagicMock() self.dispatcher.update_opentelemetry_status() - self.assertTrue(self.dispatcher._otel_libs_available) + self.assertIsNotNone(self.dispatcher._context_api) + self.assertIsNotNone(self.dispatcher._trace_context_propagator) @patch('builtins.__import__') @patch("azure_functions_worker.dispatcher.Dispatcher.update_opentelemetry_status") - def test_initialize_opentelemetry_success( + def test_initialize_azure_monitor_success( self, mock_update_ot, mock_imports, ): mock_imports.return_value = MagicMock() - self.dispatcher.initialize_opentelemetry() + self.dispatcher.initialize_azure_monitor() mock_update_ot.assert_called_once() - self.assertTrue(self.dispatcher._otel_libs_available) + self.assertTrue(self.dispatcher._azure_monitor_available) @patch("azure_functions_worker.dispatcher.Dispatcher.update_opentelemetry_status") - def test_initialize_opentelemetry_import_error( + def test_initialize_azure_monitor_import_error( self, mock_update_ot, ): with patch('builtins.__import__', side_effect=ImportError): - self.dispatcher.initialize_opentelemetry() + self.dispatcher.initialize_azure_monitor() mock_update_ot.assert_called_once() # Verify that otel_libs_available is set to False due to ImportError - self.assertFalse(self.dispatcher._otel_libs_available) + self.assertFalse(self.dispatcher._azure_monitor_available) @patch("azure_functions_worker.dispatcher.get_app_setting") @patch('builtins.__import__') @@ -83,12 +84,12 @@ def test_init_request_otel_capability_enabled_app_setting( self.assertIn("WorkerOpenTelemetryEnabled", capabilities) self.assertEqual(capabilities["WorkerOpenTelemetryEnabled"], "true") - @patch("azure_functions_worker.dispatcher.Dispatcher.initialize_opentelemetry") + @patch("azure_functions_worker.dispatcher.Dispatcher.initialize_azure_monitor") @patch("azure_functions_worker.dispatcher.get_app_setting") def test_init_request_otel_capability_disabled_app_setting( self, mock_app_setting, - mock_initialize_ot, + mock_initialize_azmon, ): mock_app_setting.return_value = False @@ -105,8 +106,8 @@ def test_init_request_otel_capability_disabled_app_setting( self.assertEqual(init_response.worker_init_response.result.status, protos.StatusResult.Success) - # OpenTelemetry initialized not called - mock_initialize_ot.assert_not_called() + # Azure monitor initialized not called + mock_initialize_azmon.assert_not_called() # Verify that WorkerOpenTelemetryEnabled capability is not set capabilities = init_response.worker_init_response.capabilities From 74fe555e800a12ec7bfca203988bf8468696bb54 Mon Sep 17 00:00:00 2001 From: Victoria Hall Date: Thu, 1 Aug 2024 10:32:44 -0500 Subject: [PATCH 13/15] fix mock env variable --- tests/unittests/test_opentelemetry.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/unittests/test_opentelemetry.py b/tests/unittests/test_opentelemetry.py index ce28e2583..b26334bdf 100644 --- a/tests/unittests/test_opentelemetry.py +++ b/tests/unittests/test_opentelemetry.py @@ -1,4 +1,5 @@ import asyncio +import os import unittest from unittest.mock import MagicMock, patch @@ -56,15 +57,13 @@ def test_initialize_azure_monitor_import_error( # Verify that otel_libs_available is set to False due to ImportError self.assertFalse(self.dispatcher._azure_monitor_available) - @patch("azure_functions_worker.dispatcher.get_app_setting") + @patch.dict(os.environ, {'PYTHON_ENABLE_OPENTELEMETRY': 'true'}) @patch('builtins.__import__') def test_init_request_otel_capability_enabled_app_setting( self, mock_imports, - mock_app_setting, ): mock_imports.return_value = MagicMock() - mock_app_setting.return_value = True init_request = protos.StreamingMessage( worker_init_request=protos.WorkerInitRequest( @@ -85,13 +84,10 @@ def test_init_request_otel_capability_enabled_app_setting( self.assertEqual(capabilities["WorkerOpenTelemetryEnabled"], "true") @patch("azure_functions_worker.dispatcher.Dispatcher.initialize_azure_monitor") - @patch("azure_functions_worker.dispatcher.get_app_setting") def test_init_request_otel_capability_disabled_app_setting( self, - mock_app_setting, mock_initialize_azmon, ): - mock_app_setting.return_value = False init_request = protos.StreamingMessage( worker_init_request=protos.WorkerInitRequest( From 2e50fba41e4dff83b1be14bc71ef56f16b542d94 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Thu, 1 Aug 2024 15:19:03 -0700 Subject: [PATCH 14/15] Update dispatcher.py --- azure_functions_worker/dispatcher.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/azure_functions_worker/dispatcher.py b/azure_functions_worker/dispatcher.py index 355f546e8..3735c662f 100644 --- a/azure_functions_worker/dispatcher.py +++ b/azure_functions_worker/dispatcher.py @@ -346,7 +346,9 @@ def update_opentelemetry_status(self): logger.info("Successfully loaded OpenTelemetry modules. " "OpenTelemetry is now enabled.") except ImportError: - self._azure_monitor_available = False + logger.exception( + "Cannot import OpenTelemetry libraries." + ) async def _handle__worker_init_request(self, request): logger.info('Received WorkerInitRequest, ' From 0b461f9204a0ed86c00a16cd10df09cd771ea2f2 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Mon, 5 Aug 2024 09:15:14 -0700 Subject: [PATCH 15/15] Update dispatcher.py --- azure_functions_worker/dispatcher.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/azure_functions_worker/dispatcher.py b/azure_functions_worker/dispatcher.py index 3735c662f..cd0815839 100644 --- a/azure_functions_worker/dispatcher.py +++ b/azure_functions_worker/dispatcher.py @@ -343,8 +343,6 @@ def update_opentelemetry_status(self): self._context_api = context_api self._trace_context_propagator = TraceContextTextMapPropagator() - logger.info("Successfully loaded OpenTelemetry modules. " - "OpenTelemetry is now enabled.") except ImportError: logger.exception( "Cannot import OpenTelemetry libraries."