From f7c2b15b6bc20bfc29f86a3d5c17a01d8a5a2f0a Mon Sep 17 00:00:00 2001 From: jerevoss Date: Thu, 12 Jan 2023 13:52:18 -0800 Subject: [PATCH 1/2] Added status logger --- CHANGELOG.md | 2 + .../opentelemetry/distro/_status_logger.py | 52 ++++ .../monitor/opentelemetry/distro/distro.py | 6 + .../tests/test_status_logger.py | 267 ++++++++++++++++++ 4 files changed, 327 insertions(+) create mode 100644 azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_status_logger.py create mode 100644 azure-monitor-opentelemetry-distro/tests/test_status_logger.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a9a994a..c60b6195 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- Added Status Logger + ([#217](https://github.com/microsoft/ApplicationInsights-Python/pull/217)) - Added Diagnostic Logging for App Service ([#212](https://github.com/microsoft/ApplicationInsights-Python/pull/212)) - Updated main and distro READMEs diff --git a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_status_logger.py b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_status_logger.py new file mode 100644 index 00000000..c1148816 --- /dev/null +++ b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_status_logger.py @@ -0,0 +1,52 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License in the project root for +# license information. +# -------------------------------------------------------------------------- + +import socket +from json import dumps +from os import getpid, makedirs +from os.path import exists, join + +from azure.monitor.opentelemetry.distro._constants import ( + _CUSTOMER_IKEY, + _EXTENSION_VERSION, + _IS_DIAGNOSTICS_ENABLED, + _get_log_path +) +from azure.monitor.opentelemetry.distro._version import VERSION + +_MACHINE_NAME = socket.gethostname() +_STATUS_LOG_PATH = _get_log_path(status_log_path=True) + + +def _get_status_json(agent_initialized_successfully, pid, reason=None): + status_json = { + "AgentInitializedSuccessfully": agent_initialized_successfully, + "AppType": "python", + "MachineName": _MACHINE_NAME, + "PID": pid, + "SdkVersion": VERSION, + "Ikey": _CUSTOMER_IKEY, + "ExtensionVersion": _EXTENSION_VERSION, + } + if reason: + status_json["Reason"] = reason + return status_json + + +def log_status(agent_initialized_successfully, reason=None): + if _IS_DIAGNOSTICS_ENABLED and _STATUS_LOG_PATH : + pid = getpid() + status_json = _get_status_json( + agent_initialized_successfully, pid, reason + ) + if not exists(_STATUS_LOG_PATH): + makedirs(_STATUS_LOG_PATH) + # Change to be hostname and pid + status_logger_file_name = f"status_{_MACHINE_NAME}_{pid}.json" + with open(join(_STATUS_LOG_PATH, status_logger_file_name), "w") as f: + f.seek(0) + f.write(dumps(status_json)) + f.truncate() diff --git a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/distro.py b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/distro.py index 703bb361..c7ef95ef 100644 --- a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/distro.py +++ b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/distro.py @@ -9,6 +9,9 @@ from azure.monitor.opentelemetry.distro._diagnostic_logging import ( AzureDiagnosticLogging, ) +from azure.monitor.opentelemetry.distro._status_logger import ( + log_status, +) from opentelemetry.environment_variables import ( OTEL_METRICS_EXPORTER, OTEL_TRACES_EXPORTER, @@ -34,6 +37,7 @@ def _configure(self, **kwargs) -> None: def _configure_auto_instrumentation() -> None: try: + log_status(False, "Distro being configured.") AzureDiagnosticLogging.enable(_logger) AzureDiagnosticLogging.enable(_opentelemetry_logger) # TODO: Enabled when duplicate logging issue is solved @@ -51,10 +55,12 @@ def _configure_auto_instrumentation() -> None: environ.setdefault( OTEL_TRACES_EXPORTER, "azure_monitor_opentelemetry_exporter" ) + log_status(True) _logger.info( "Azure Monitor OpenTelemetry Distro configured successfully." ) except Exception as exc: + log_status(False, reason=exc) _logger.error( "Azure Monitor OpenTelemetry Distro failed during " + f"configuration: {exc}" diff --git a/azure-monitor-opentelemetry-distro/tests/test_status_logger.py b/azure-monitor-opentelemetry-distro/tests/test_status_logger.py new file mode 100644 index 00000000..b7718427 --- /dev/null +++ b/azure-monitor-opentelemetry-distro/tests/test_status_logger.py @@ -0,0 +1,267 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License in the project root for +# license information. +# -------------------------------------------------------------------------- + +from json import loads +from os.path import join +from pathlib import Path +from unittest import TestCase +from unittest.mock import patch + +from azure.monitor.opentelemetry.distro import status_logger + +TEST_LOGGER_PATH = str(Path.home()) +TEST_MACHINE_NAME = "TEST_MACHINE_NAME" +TEST_PID = 321 +TEST_STATUS_LOGGER_LOCATION = join( + TEST_LOGGER_PATH, f"status_{TEST_MACHINE_NAME}_{TEST_PID}.json" +) +TEST_OPERATION = "TEST_OPERATION" +TEST_OPERATION = "TEST_OPERATION" +TEST_SITE_NAME = "TEST_SITE_NAME" +TEST_CUSTOMER_IKEY = "TEST_CUSTOMER_IKEY" +TEST_EXTENSION_VERSION = "TEST_EXTENSION_VERSION" +TEST_VERSION = "TEST_VERSION" +TEST_SUBSCRIPTION_ID = "TEST_SUBSCRIPTION_ID" +MESSAGE1 = "MESSAGE1" +MESSAGE2 = "MESSAGE2" + + +def clear_file(): + with open(TEST_STATUS_LOGGER_LOCATION, "w") as f: + f.seek(0) + f.truncate() + + +def check_file_for_messages(agent_initialized_successfully, reason=None): + with open(TEST_STATUS_LOGGER_LOCATION, "r") as f: + f.seek(0) + json = loads(f.readline()) + assert ( + json["AgentInitializedSuccessfully"] + == agent_initialized_successfully + ) + assert json["AppType"] == "python" + assert json["MachineName"] == TEST_MACHINE_NAME + assert json["PID"] == TEST_PID + assert json["SdkVersion"] == TEST_VERSION + assert json["Ikey"] == TEST_CUSTOMER_IKEY + assert json["ExtensionVersion"] == TEST_EXTENSION_VERSION + if reason: + assert json["Reason"] == reason + else: + assert "Reason" not in json + assert not f.read() + + +def check_file_is_empty(): + with open(TEST_STATUS_LOGGER_LOCATION, "r") as f: + f.seek(0) + assert not f.read() + + +class TestStatusLogger(TestCase): + def setUp(self) -> None: + clear_file() + + @patch( + "azure.monitor.opentelemetry.distro.status_logger._STATUS_LOG_PATH", + TEST_LOGGER_PATH, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._MACHINE_NAME", + TEST_MACHINE_NAME, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._CUSTOMER_IKEY", + TEST_CUSTOMER_IKEY, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._EXTENSION_VERSION", + TEST_EXTENSION_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger.VERSION", + TEST_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._IS_ON_APP_SERVICE", + True, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger.getpid", + return_value=TEST_PID, + ) + def test_app_service_log_status_success(self, mock_getpid): + status_logger.log_status(False, MESSAGE1) + status_logger.log_status(True, MESSAGE2) + check_file_for_messages(True, MESSAGE2) + + @patch( + "azure.monitor.opentelemetry.distro.status_logger._STATUS_LOG_PATH", + TEST_LOGGER_PATH, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._MACHINE_NAME", + TEST_MACHINE_NAME, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._CUSTOMER_IKEY", + TEST_CUSTOMER_IKEY, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._EXTENSION_VERSION", + TEST_EXTENSION_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger.VERSION", + TEST_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._IS_ON_APP_SERVICE", + True, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger.getpid", + return_value=TEST_PID, + ) + def test_app_service_log_status_failed_initialization(self, mock_getpid): + status_logger.log_status(True, MESSAGE1) + status_logger.log_status(False, MESSAGE2) + check_file_for_messages(False, MESSAGE2) + + @patch( + "azure.monitor.opentelemetry.distro.status_logger._STATUS_LOG_PATH", + TEST_LOGGER_PATH, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._MACHINE_NAME", + TEST_MACHINE_NAME, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._CUSTOMER_IKEY", + TEST_CUSTOMER_IKEY, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._EXTENSION_VERSION", + TEST_EXTENSION_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger.VERSION", + TEST_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._IS_ON_APP_SERVICE", + True, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger.getpid", + return_value=TEST_PID, + ) + def test_app_service_log_status_no_reason(self, mock_getpid): + status_logger.log_status(False, MESSAGE1) + status_logger.log_status(True) + check_file_for_messages(True) + + @patch( + "azure.monitor.opentelemetry.distro.status_logger._STATUS_LOG_PATH", + TEST_LOGGER_PATH, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._MACHINE_NAME", + TEST_MACHINE_NAME, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._CUSTOMER_IKEY", + TEST_CUSTOMER_IKEY, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._EXTENSION_VERSION", + TEST_EXTENSION_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger.VERSION", + TEST_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._IS_ON_APP_SERVICE", + False, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger.getpid", + return_value=TEST_PID, + ) + def test_off_app_service_log_status_success(self, mock_getpid): + status_logger.log_status(False, MESSAGE1) + status_logger.log_status(True, MESSAGE2) + check_file_is_empty() + + @patch( + "azure.monitor.opentelemetry.distro.status_logger._STATUS_LOG_PATH", + TEST_LOGGER_PATH, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._MACHINE_NAME", + TEST_MACHINE_NAME, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._CUSTOMER_IKEY", + TEST_CUSTOMER_IKEY, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._EXTENSION_VERSION", + TEST_EXTENSION_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger.VERSION", + TEST_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._IS_ON_APP_SERVICE", + False, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger.getpid", + return_value=TEST_PID, + ) + def test_off_app_service_log_status_failed_initialization( + self, mock_getpid + ): + status_logger.log_status(True, MESSAGE1) + status_logger.log_status(False, MESSAGE2) + check_file_is_empty() + + @patch( + "azure.monitor.opentelemetry.distro.status_logger._STATUS_LOG_PATH", + TEST_LOGGER_PATH, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._MACHINE_NAME", + TEST_MACHINE_NAME, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._CUSTOMER_IKEY", + TEST_CUSTOMER_IKEY, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._EXTENSION_VERSION", + TEST_EXTENSION_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger.VERSION", + TEST_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger._IS_ON_APP_SERVICE", + False, + ) + @patch( + "azure.monitor.opentelemetry.distro.status_logger.getpid", + return_value=TEST_PID, + ) + def test_off_app_service_log_status_no_reason(self, mock_getpid): + status_logger.log_status(False, MESSAGE1) + status_logger.log_status(True) + check_file_is_empty() From e86f6c63874b49ebce5e3a5d833956b739b9f268 Mon Sep 17 00:00:00 2001 From: jerevoss Date: Wed, 18 Jan 2023 16:10:10 -0800 Subject: [PATCH 2/2] feedback --- .../distro/_diagnostics/__init__.py | 0 .../{ => _diagnostics}/_diagnostic_logging.py | 3 - .../distro/_diagnostics/_status_logger.py | 54 ++++ .../opentelemetry/distro/_status_logger.py | 52 ---- .../opentelemetry/distro/configurator.py | 2 +- .../monitor/opentelemetry/distro/distro.py | 12 +- .../test_diagnostic_logging.py | 14 +- .../tests/diagnostics/test_status_logger.py | 267 ++++++++++++++++++ .../tests/test_status_logger.py | 267 ------------------ 9 files changed, 335 insertions(+), 336 deletions(-) create mode 100644 azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_diagnostics/__init__.py rename azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/{ => _diagnostics}/_diagnostic_logging.py (97%) create mode 100644 azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_diagnostics/_status_logger.py delete mode 100644 azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_status_logger.py rename azure-monitor-opentelemetry-distro/tests/{ => diagnostics}/test_diagnostic_logging.py (90%) create mode 100644 azure-monitor-opentelemetry-distro/tests/diagnostics/test_status_logger.py delete mode 100644 azure-monitor-opentelemetry-distro/tests/test_status_logger.py diff --git a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_diagnostics/__init__.py b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_diagnostics/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_diagnostic_logging.py b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_diagnostics/_diagnostic_logging.py similarity index 97% rename from azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_diagnostic_logging.py rename to azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_diagnostics/_diagnostic_logging.py index 1796f7bd..e0f3ad4c 100644 --- a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_diagnostic_logging.py +++ b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_diagnostics/_diagnostic_logging.py @@ -27,9 +27,6 @@ if _SUBSCRIPTION_ID_ENV_VAR else None ) -_opentelemetry_logger = logging.getLogger( - _OPENTELEMETRY_DIAGNOSTIC_LOGGER_NAME -) _logger = logging.getLogger(__name__) _DIAGNOSTIC_LOG_PATH = _get_log_path() diff --git a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_diagnostics/_status_logger.py b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_diagnostics/_status_logger.py new file mode 100644 index 00000000..574ec64f --- /dev/null +++ b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_diagnostics/_status_logger.py @@ -0,0 +1,54 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License in the project root for +# license information. +# -------------------------------------------------------------------------- + +from json import dumps +from os import getpid, makedirs +from os.path import exists, join +from platform import node + +from azure.monitor.opentelemetry.distro._constants import ( + _CUSTOMER_IKEY, + _EXTENSION_VERSION, + _IS_DIAGNOSTICS_ENABLED, + _get_log_path, +) +from azure.monitor.opentelemetry.distro._version import VERSION + +_MACHINE_NAME = node() +_STATUS_LOG_PATH = _get_log_path(status_log_path=True) + + +class AzureStatusLogger: + def _get_status_json(agent_initialized_successfully, pid, reason=None): + status_json = { + "AgentInitializedSuccessfully": agent_initialized_successfully, + "AppType": "python", + "MachineName": _MACHINE_NAME, + "PID": pid, + "SdkVersion": VERSION, + "Ikey": _CUSTOMER_IKEY, + "ExtensionVersion": _EXTENSION_VERSION, + } + if reason: + status_json["Reason"] = reason + return status_json + + def log_status(agent_initialized_successfully, reason=None): + if _IS_DIAGNOSTICS_ENABLED and _STATUS_LOG_PATH: + pid = getpid() + status_json = AzureStatusLogger._get_status_json( + agent_initialized_successfully, pid, reason + ) + if not exists(_STATUS_LOG_PATH): + makedirs(_STATUS_LOG_PATH) + # Change to be hostname and pid + status_logger_file_name = f"status_{_MACHINE_NAME}_{pid}.json" + with open( + join(_STATUS_LOG_PATH, status_logger_file_name), "w" + ) as f: + f.seek(0) + f.write(dumps(status_json)) + f.truncate() diff --git a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_status_logger.py b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_status_logger.py deleted file mode 100644 index c1148816..00000000 --- a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/_status_logger.py +++ /dev/null @@ -1,52 +0,0 @@ -# ------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License in the project root for -# license information. -# -------------------------------------------------------------------------- - -import socket -from json import dumps -from os import getpid, makedirs -from os.path import exists, join - -from azure.monitor.opentelemetry.distro._constants import ( - _CUSTOMER_IKEY, - _EXTENSION_VERSION, - _IS_DIAGNOSTICS_ENABLED, - _get_log_path -) -from azure.monitor.opentelemetry.distro._version import VERSION - -_MACHINE_NAME = socket.gethostname() -_STATUS_LOG_PATH = _get_log_path(status_log_path=True) - - -def _get_status_json(agent_initialized_successfully, pid, reason=None): - status_json = { - "AgentInitializedSuccessfully": agent_initialized_successfully, - "AppType": "python", - "MachineName": _MACHINE_NAME, - "PID": pid, - "SdkVersion": VERSION, - "Ikey": _CUSTOMER_IKEY, - "ExtensionVersion": _EXTENSION_VERSION, - } - if reason: - status_json["Reason"] = reason - return status_json - - -def log_status(agent_initialized_successfully, reason=None): - if _IS_DIAGNOSTICS_ENABLED and _STATUS_LOG_PATH : - pid = getpid() - status_json = _get_status_json( - agent_initialized_successfully, pid, reason - ) - if not exists(_STATUS_LOG_PATH): - makedirs(_STATUS_LOG_PATH) - # Change to be hostname and pid - status_logger_file_name = f"status_{_MACHINE_NAME}_{pid}.json" - with open(join(_STATUS_LOG_PATH, status_logger_file_name), "w") as f: - f.seek(0) - f.write(dumps(status_json)) - f.truncate() diff --git a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/configurator.py b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/configurator.py index 4445149b..3593471c 100644 --- a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/configurator.py +++ b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/configurator.py @@ -5,7 +5,7 @@ # -------------------------------------------------------------------------- -from azure.monitor.opentelemetry.distro._diagnostic_logging import ( +from azure.monitor.opentelemetry.distro._diagnostics._diagnostic_logging import ( AzureDiagnosticLogging, ) from opentelemetry.sdk._configuration import _OTelSDKConfigurator diff --git a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/distro.py b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/distro.py index c7ef95ef..3b5b84ea 100644 --- a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/distro.py +++ b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/distro.py @@ -6,11 +6,11 @@ import logging from os import environ -from azure.monitor.opentelemetry.distro._diagnostic_logging import ( +from azure.monitor.opentelemetry.distro._diagnostics._diagnostic_logging import ( AzureDiagnosticLogging, ) -from azure.monitor.opentelemetry.distro._status_logger import ( - log_status, +from azure.monitor.opentelemetry.distro._diagnostics._status_logger import ( + AzureStatusLogger, ) from opentelemetry.environment_variables import ( OTEL_METRICS_EXPORTER, @@ -37,7 +37,7 @@ def _configure(self, **kwargs) -> None: def _configure_auto_instrumentation() -> None: try: - log_status(False, "Distro being configured.") + AzureStatusLogger.log_status(False, "Distro being configured.") AzureDiagnosticLogging.enable(_logger) AzureDiagnosticLogging.enable(_opentelemetry_logger) # TODO: Enabled when duplicate logging issue is solved @@ -55,12 +55,12 @@ def _configure_auto_instrumentation() -> None: environ.setdefault( OTEL_TRACES_EXPORTER, "azure_monitor_opentelemetry_exporter" ) - log_status(True) + AzureStatusLogger.log_status(True) _logger.info( "Azure Monitor OpenTelemetry Distro configured successfully." ) except Exception as exc: - log_status(False, reason=exc) + AzureStatusLogger.log_status(False, reason=exc) _logger.error( "Azure Monitor OpenTelemetry Distro failed during " + f"configuration: {exc}" diff --git a/azure-monitor-opentelemetry-distro/tests/test_diagnostic_logging.py b/azure-monitor-opentelemetry-distro/tests/diagnostics/test_diagnostic_logging.py similarity index 90% rename from azure-monitor-opentelemetry-distro/tests/test_diagnostic_logging.py rename to azure-monitor-opentelemetry-distro/tests/diagnostics/test_diagnostic_logging.py index 9a9beb15..d231d07c 100644 --- a/azure-monitor-opentelemetry-distro/tests/test_diagnostic_logging.py +++ b/azure-monitor-opentelemetry-distro/tests/diagnostics/test_diagnostic_logging.py @@ -12,7 +12,7 @@ from unittest import TestCase from unittest.mock import patch -import azure.monitor.opentelemetry.distro._diagnostic_logging as diagnostic_logger +import azure.monitor.opentelemetry.distro._diagnostics._diagnostic_logging as diagnostic_logger TEST_LOGGER_PATH = str(Path.home()) TEST_DIAGNOSTIC_LOGGER_FILE_NAME = "test-applicationinsights-extension.log" @@ -88,27 +88,27 @@ def set_up( reload(diagnostic_logger) assert not diagnostic_logger.AzureDiagnosticLogging._initialized patch( - "azure.monitor.opentelemetry.distro._diagnostic_logging._DIAGNOSTIC_LOG_PATH", + "azure.monitor.opentelemetry.distro._diagnostics._diagnostic_logging._DIAGNOSTIC_LOG_PATH", TEST_LOGGER_PATH, ).start() patch( - "azure.monitor.opentelemetry.distro._diagnostic_logging._DIAGNOSTIC_LOGGER_FILE_NAME", + "azure.monitor.opentelemetry.distro._diagnostics._diagnostic_logging._DIAGNOSTIC_LOGGER_FILE_NAME", TEST_DIAGNOSTIC_LOGGER_FILE_NAME, ).start() patch( - "azure.monitor.opentelemetry.distro._diagnostic_logging._CUSTOMER_IKEY", + "azure.monitor.opentelemetry.distro._diagnostics._diagnostic_logging._CUSTOMER_IKEY", TEST_CUSTOMER_IKEY, ).start() patch( - "azure.monitor.opentelemetry.distro._diagnostic_logging._EXTENSION_VERSION", + "azure.monitor.opentelemetry.distro._diagnostics._diagnostic_logging._EXTENSION_VERSION", TEST_EXTENSION_VERSION, ).start() patch( - "azure.monitor.opentelemetry.distro._diagnostic_logging.VERSION", + "azure.monitor.opentelemetry.distro._diagnostics._diagnostic_logging.VERSION", TEST_VERSION, ).start() patch( - "azure.monitor.opentelemetry.distro._diagnostic_logging._IS_DIAGNOSTICS_ENABLED", + "azure.monitor.opentelemetry.distro._diagnostics._diagnostic_logging._IS_DIAGNOSTICS_ENABLED", is_diagnostics_enabled, ).start() diagnostic_logger.AzureDiagnosticLogging.enable(logger) diff --git a/azure-monitor-opentelemetry-distro/tests/diagnostics/test_status_logger.py b/azure-monitor-opentelemetry-distro/tests/diagnostics/test_status_logger.py new file mode 100644 index 00000000..0df79142 --- /dev/null +++ b/azure-monitor-opentelemetry-distro/tests/diagnostics/test_status_logger.py @@ -0,0 +1,267 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License in the project root for +# license information. +# -------------------------------------------------------------------------- + +from json import loads +from os.path import join +from pathlib import Path +from unittest import TestCase +from unittest.mock import patch + +from azure.monitor.opentelemetry.distro._diagnostics._status_logger import ( + AzureStatusLogger, +) + +TEST_LOGGER_PATH = str(Path.home()) +TEST_MACHINE_NAME = "TEST_MACHINE_NAME" +TEST_PID = 321 +TEST_STATUS_LOGGER_LOCATION = join( + TEST_LOGGER_PATH, f"status_{TEST_MACHINE_NAME}_{TEST_PID}.json" +) +TEST_OPERATION = "TEST_OPERATION" +TEST_OPERATION = "TEST_OPERATION" +TEST_SITE_NAME = "TEST_SITE_NAME" +TEST_CUSTOMER_IKEY = "TEST_CUSTOMER_IKEY" +TEST_EXTENSION_VERSION = "TEST_EXTENSION_VERSION" +TEST_VERSION = "TEST_VERSION" +TEST_SUBSCRIPTION_ID = "TEST_SUBSCRIPTION_ID" +MESSAGE1 = "MESSAGE1" +MESSAGE2 = "MESSAGE2" + + +def clear_file(): + with open(TEST_STATUS_LOGGER_LOCATION, "w") as f: + f.seek(0) + f.truncate() + + +def check_file_for_messages(agent_initialized_successfully, reason=None): + with open(TEST_STATUS_LOGGER_LOCATION, "r") as f: + f.seek(0) + json = loads(f.readline()) + assert ( + json["AgentInitializedSuccessfully"] + == agent_initialized_successfully + ) + assert json["AppType"] == "python" + assert json["MachineName"] == TEST_MACHINE_NAME + assert json["PID"] == TEST_PID + assert json["SdkVersion"] == TEST_VERSION + assert json["Ikey"] == TEST_CUSTOMER_IKEY + assert json["ExtensionVersion"] == TEST_EXTENSION_VERSION + if reason: + assert json["Reason"] == reason + else: + assert "Reason" not in json + assert not f.read() + + +def check_file_is_empty(): + with open(TEST_STATUS_LOGGER_LOCATION, "r") as f: + f.seek(0) + assert not f.read() + + +class TestStatusLogger(TestCase): + def setUp(self) -> None: + clear_file() + + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._STATUS_LOG_PATH", + TEST_LOGGER_PATH, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._CUSTOMER_IKEY", + TEST_CUSTOMER_IKEY, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._EXTENSION_VERSION", + TEST_EXTENSION_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger.VERSION", + TEST_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._IS_DIAGNOSTICS_ENABLED", + True, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger.getpid", + return_value=TEST_PID, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._MACHINE_NAME", + TEST_MACHINE_NAME, + ) + def test_log_status_success(self, mock_getpid): + AzureStatusLogger.log_status(False, MESSAGE1) + AzureStatusLogger.log_status(True, MESSAGE2) + check_file_for_messages(True, MESSAGE2) + + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._STATUS_LOG_PATH", + TEST_LOGGER_PATH, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._CUSTOMER_IKEY", + TEST_CUSTOMER_IKEY, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._EXTENSION_VERSION", + TEST_EXTENSION_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger.VERSION", + TEST_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._IS_DIAGNOSTICS_ENABLED", + True, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger.getpid", + return_value=TEST_PID, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._MACHINE_NAME", + TEST_MACHINE_NAME, + ) + def test_log_status_failed_initialization(self, mock_getpid): + AzureStatusLogger.log_status(True, MESSAGE1) + AzureStatusLogger.log_status(False, MESSAGE2) + check_file_for_messages(False, MESSAGE2) + + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._STATUS_LOG_PATH", + TEST_LOGGER_PATH, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._CUSTOMER_IKEY", + TEST_CUSTOMER_IKEY, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._EXTENSION_VERSION", + TEST_EXTENSION_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger.VERSION", + TEST_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._IS_DIAGNOSTICS_ENABLED", + True, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger.getpid", + return_value=TEST_PID, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._MACHINE_NAME", + TEST_MACHINE_NAME, + ) + def test_log_status_no_reason(self, mock_getpid): + AzureStatusLogger.log_status(False, MESSAGE1) + AzureStatusLogger.log_status(True) + check_file_for_messages(True) + + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._STATUS_LOG_PATH", + TEST_LOGGER_PATH, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._CUSTOMER_IKEY", + TEST_CUSTOMER_IKEY, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._EXTENSION_VERSION", + TEST_EXTENSION_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger.VERSION", + TEST_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._IS_DIAGNOSTICS_ENABLED", + False, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger.getpid", + return_value=TEST_PID, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._MACHINE_NAME", + TEST_MACHINE_NAME, + ) + def test_disabled_log_status_success(self, mock_getpid): + AzureStatusLogger.log_status(False, MESSAGE1) + AzureStatusLogger.log_status(True, MESSAGE2) + check_file_is_empty() + + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._STATUS_LOG_PATH", + TEST_LOGGER_PATH, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._CUSTOMER_IKEY", + TEST_CUSTOMER_IKEY, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._EXTENSION_VERSION", + TEST_EXTENSION_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger.VERSION", + TEST_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._IS_DIAGNOSTICS_ENABLED", + False, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger.getpid", + return_value=TEST_PID, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._MACHINE_NAME", + TEST_MACHINE_NAME, + ) + def test_disabled_log_status_failed_initialization(self, mock_getpid): + AzureStatusLogger.log_status(True, MESSAGE1) + AzureStatusLogger.log_status(False, MESSAGE2) + check_file_is_empty() + + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._STATUS_LOG_PATH", + TEST_LOGGER_PATH, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._CUSTOMER_IKEY", + TEST_CUSTOMER_IKEY, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._EXTENSION_VERSION", + TEST_EXTENSION_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger.VERSION", + TEST_VERSION, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._IS_DIAGNOSTICS_ENABLED", + False, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger.getpid", + return_value=TEST_PID, + ) + @patch( + "azure.monitor.opentelemetry.distro._diagnostics._status_logger._MACHINE_NAME", + TEST_MACHINE_NAME, + ) + def test_disabled_log_status_no_reason(self, mock_getpid): + AzureStatusLogger.log_status(False, MESSAGE1) + AzureStatusLogger.log_status(True) + check_file_is_empty() diff --git a/azure-monitor-opentelemetry-distro/tests/test_status_logger.py b/azure-monitor-opentelemetry-distro/tests/test_status_logger.py deleted file mode 100644 index b7718427..00000000 --- a/azure-monitor-opentelemetry-distro/tests/test_status_logger.py +++ /dev/null @@ -1,267 +0,0 @@ -# ------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License in the project root for -# license information. -# -------------------------------------------------------------------------- - -from json import loads -from os.path import join -from pathlib import Path -from unittest import TestCase -from unittest.mock import patch - -from azure.monitor.opentelemetry.distro import status_logger - -TEST_LOGGER_PATH = str(Path.home()) -TEST_MACHINE_NAME = "TEST_MACHINE_NAME" -TEST_PID = 321 -TEST_STATUS_LOGGER_LOCATION = join( - TEST_LOGGER_PATH, f"status_{TEST_MACHINE_NAME}_{TEST_PID}.json" -) -TEST_OPERATION = "TEST_OPERATION" -TEST_OPERATION = "TEST_OPERATION" -TEST_SITE_NAME = "TEST_SITE_NAME" -TEST_CUSTOMER_IKEY = "TEST_CUSTOMER_IKEY" -TEST_EXTENSION_VERSION = "TEST_EXTENSION_VERSION" -TEST_VERSION = "TEST_VERSION" -TEST_SUBSCRIPTION_ID = "TEST_SUBSCRIPTION_ID" -MESSAGE1 = "MESSAGE1" -MESSAGE2 = "MESSAGE2" - - -def clear_file(): - with open(TEST_STATUS_LOGGER_LOCATION, "w") as f: - f.seek(0) - f.truncate() - - -def check_file_for_messages(agent_initialized_successfully, reason=None): - with open(TEST_STATUS_LOGGER_LOCATION, "r") as f: - f.seek(0) - json = loads(f.readline()) - assert ( - json["AgentInitializedSuccessfully"] - == agent_initialized_successfully - ) - assert json["AppType"] == "python" - assert json["MachineName"] == TEST_MACHINE_NAME - assert json["PID"] == TEST_PID - assert json["SdkVersion"] == TEST_VERSION - assert json["Ikey"] == TEST_CUSTOMER_IKEY - assert json["ExtensionVersion"] == TEST_EXTENSION_VERSION - if reason: - assert json["Reason"] == reason - else: - assert "Reason" not in json - assert not f.read() - - -def check_file_is_empty(): - with open(TEST_STATUS_LOGGER_LOCATION, "r") as f: - f.seek(0) - assert not f.read() - - -class TestStatusLogger(TestCase): - def setUp(self) -> None: - clear_file() - - @patch( - "azure.monitor.opentelemetry.distro.status_logger._STATUS_LOG_PATH", - TEST_LOGGER_PATH, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._MACHINE_NAME", - TEST_MACHINE_NAME, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._CUSTOMER_IKEY", - TEST_CUSTOMER_IKEY, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._EXTENSION_VERSION", - TEST_EXTENSION_VERSION, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger.VERSION", - TEST_VERSION, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._IS_ON_APP_SERVICE", - True, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger.getpid", - return_value=TEST_PID, - ) - def test_app_service_log_status_success(self, mock_getpid): - status_logger.log_status(False, MESSAGE1) - status_logger.log_status(True, MESSAGE2) - check_file_for_messages(True, MESSAGE2) - - @patch( - "azure.monitor.opentelemetry.distro.status_logger._STATUS_LOG_PATH", - TEST_LOGGER_PATH, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._MACHINE_NAME", - TEST_MACHINE_NAME, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._CUSTOMER_IKEY", - TEST_CUSTOMER_IKEY, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._EXTENSION_VERSION", - TEST_EXTENSION_VERSION, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger.VERSION", - TEST_VERSION, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._IS_ON_APP_SERVICE", - True, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger.getpid", - return_value=TEST_PID, - ) - def test_app_service_log_status_failed_initialization(self, mock_getpid): - status_logger.log_status(True, MESSAGE1) - status_logger.log_status(False, MESSAGE2) - check_file_for_messages(False, MESSAGE2) - - @patch( - "azure.monitor.opentelemetry.distro.status_logger._STATUS_LOG_PATH", - TEST_LOGGER_PATH, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._MACHINE_NAME", - TEST_MACHINE_NAME, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._CUSTOMER_IKEY", - TEST_CUSTOMER_IKEY, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._EXTENSION_VERSION", - TEST_EXTENSION_VERSION, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger.VERSION", - TEST_VERSION, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._IS_ON_APP_SERVICE", - True, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger.getpid", - return_value=TEST_PID, - ) - def test_app_service_log_status_no_reason(self, mock_getpid): - status_logger.log_status(False, MESSAGE1) - status_logger.log_status(True) - check_file_for_messages(True) - - @patch( - "azure.monitor.opentelemetry.distro.status_logger._STATUS_LOG_PATH", - TEST_LOGGER_PATH, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._MACHINE_NAME", - TEST_MACHINE_NAME, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._CUSTOMER_IKEY", - TEST_CUSTOMER_IKEY, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._EXTENSION_VERSION", - TEST_EXTENSION_VERSION, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger.VERSION", - TEST_VERSION, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._IS_ON_APP_SERVICE", - False, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger.getpid", - return_value=TEST_PID, - ) - def test_off_app_service_log_status_success(self, mock_getpid): - status_logger.log_status(False, MESSAGE1) - status_logger.log_status(True, MESSAGE2) - check_file_is_empty() - - @patch( - "azure.monitor.opentelemetry.distro.status_logger._STATUS_LOG_PATH", - TEST_LOGGER_PATH, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._MACHINE_NAME", - TEST_MACHINE_NAME, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._CUSTOMER_IKEY", - TEST_CUSTOMER_IKEY, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._EXTENSION_VERSION", - TEST_EXTENSION_VERSION, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger.VERSION", - TEST_VERSION, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._IS_ON_APP_SERVICE", - False, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger.getpid", - return_value=TEST_PID, - ) - def test_off_app_service_log_status_failed_initialization( - self, mock_getpid - ): - status_logger.log_status(True, MESSAGE1) - status_logger.log_status(False, MESSAGE2) - check_file_is_empty() - - @patch( - "azure.monitor.opentelemetry.distro.status_logger._STATUS_LOG_PATH", - TEST_LOGGER_PATH, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._MACHINE_NAME", - TEST_MACHINE_NAME, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._CUSTOMER_IKEY", - TEST_CUSTOMER_IKEY, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._EXTENSION_VERSION", - TEST_EXTENSION_VERSION, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger.VERSION", - TEST_VERSION, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger._IS_ON_APP_SERVICE", - False, - ) - @patch( - "azure.monitor.opentelemetry.distro.status_logger.getpid", - return_value=TEST_PID, - ) - def test_off_app_service_log_status_no_reason(self, mock_getpid): - status_logger.log_status(False, MESSAGE1) - status_logger.log_status(True) - check_file_is_empty()