diff --git a/CHANGELOG.md b/CHANGELOG.md index c60b6195..469b88e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,20 +2,22 @@ ## 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 ([#205](https://github.com/microsoft/ApplicationInsights-Python/pull/205)) - Update CONTRIBUTING.md, support Py3.11 ([#210](https://github.com/microsoft/ApplicationInsights-Python/pull/210)) +- Added Diagnostic Logging for App Service + ([#212](https://github.com/microsoft/ApplicationInsights-Python/pull/212)) - Updated setup.py, directory structure ([#214](https://github.com/microsoft/ApplicationInsights-Python/pull/214)) - Introduce Distro API ([#215](https://github.com/microsoft/ApplicationInsights-Python/pull/215)) - Rename to `configure_azure_monitor`, add sampler to config ([#216](https://github.com/microsoft/ApplicationInsights-Python/pull/216)) +- Added Status Logger + ([#217](https://github.com/microsoft/ApplicationInsights-Python/pull/217)) +- Add Logging configuration to Distro API + ([#218](https://github.com/microsoft/ApplicationInsights-Python/pull/218)) ## [1.0.0b8](https://github.com/microsoft/ApplicationInsights-Python/releases/tag/v1.0.0b8) - 2022-09-26 diff --git a/azure-monitor-opentelemetry-distro/README.md b/azure-monitor-opentelemetry-distro/README.md index c386967c..2e47ae79 100644 --- a/azure-monitor-opentelemetry-distro/README.md +++ b/azure-monitor-opentelemetry-distro/README.md @@ -14,7 +14,7 @@ This distro automatically installs the following libraries: ### Key Concepts -This package is simply a collection of OpenTelemetry and Azure Monitor components bundled together to enable the collection and sending of telemetry to Azure Monitor. For MANUAL instrumentation, it is equivalent to installing the above packages individually. AUTOMATIC instrumentation is not yet supported. +This package bundles a series of OpenTelemetry and Azure Monitor components to enable the collection and sending of telemetry to Azure Monitor. For MANUAL instrumentation, use the `configure_azure_monitor` function. AUTOMATIC instrumentation is not yet supported. The [Azure Monitor OpenTelemetry exporters][azure_monitor_opentelemetry_exporters] are the main components in accomplishing this. You will be able to use the exporters and their APIs directly through this package. Please go the exporter documentation to understand how OpenTelemetry and Azure Monitor components work in enabling telemetry collection and exporting. @@ -28,6 +28,23 @@ Install the Azure Monitor Opentelemetry Distro with [pip][pip]: pip install azure-monitor-opentelemetry-distro --pre ``` +### Usage + +You can use `configure_azure_monitor` to set up instrumentation for your app to Azure Monitor. `configure_azure_monitor` supports the following optional arguments: + +* connection_string - The [connection string][connection_string_doc] for your Application Insights resource. The connection string will be automatically populated from the `APPLICATIONINSIGHTS_CONNECTION_STRING` environment variable if not explicitly passed in. +* service_name = Specifies the [service][service_semantic_convention_doc] name. +* service_namespace = Specifies the [service][service_semantic_convention_doc] namespace. +* service_instance_id = Specifies the [service][service_semantic_convention_doc] instance id. +* disable_logging = If set to `True`, disables collection and export of logging telemetry. +* logging_level = Specifies the [logging level][logging_level] of the Opentelemetry Logging Handler. Ex: logging.WARNING. +* logging_export_interval_millis = Specifies the export interval of the logging exporter in milliseconds. Defaults to 30,000. +* disable_tracing = If set to `True`, disables collection and export of distributed tracing telemetry. +* sampling_ratio = Specifies the ratio of distributed tracing telemetry to be [sampled][application_insights_sampling]. Accepted values are in the range [0,1]. Defaults to 1.0, meaning no telemetry is sampled out. +* tracing_export_interval_millis = Specifies the export interval of the distributed tracing exporter in milliseconds. Defaults to 30,000. + +See additional [configuration related to exporting here][exporter_configuration_docs]. + ### Prerequisites: To use this package, you must have: * Azure subscription - [Create a free account][azure_sub] @@ -44,8 +61,11 @@ To use this package, you must have: [azure_monitor_opentelemetry_exporters]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/monitor/azure-monitor-opentelemetry-exporter#microsoft-opentelemetry-exporter-for-azure-monitor [azure_portal]: https://portal.azure.com [azure_sub]: https://azure.microsoft.com/free/ -[application_insights_namespace]: https://docs.microsoft.com/azure/azure-monitor/app/ -[pip]: https://pypi.org/project/pip/ +[application_insights_namespace]: https://learn.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview +[application_insights_sampling]: https://learn.microsoft.com/en-us/azure/azure-monitor/app/sampling +[connection_string_doc]: https://learn.microsoft.com/en-us/azure/azure-monitor/app/sdk-connection-string +[exporter_configuration_docs]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/monitor/azure-monitor-opentelemetry-exporter#configuration +[logging_level]: https://docs.python.org/3/library/logging.html#levels [ot_python_docs]: https://opentelemetry.io/docs/instrumentation/python/ [ot_sdk_python]: https://github.com/open-telemetry/opentelemetry-python [opentelemetry_instrumentation_requests]: https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-requests @@ -53,3 +73,5 @@ To use this package, you must have: [opentelemetry_instrumentation_flask]: https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-flask [opentelemetry_instrumentation_psycopg2]: https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-psycopg2 [python]: https://www.python.org/downloads/ +[pip]: https://pypi.org/project/pip/ +[service_semantic_convention_doc]: https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/resource/semantic_conventions#service \ No newline at end of file diff --git a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/__init__.py b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/__init__.py index 32c6259d..3154d187 100644 --- a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/__init__.py +++ b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/__init__.py @@ -3,16 +3,26 @@ # Licensed under the MIT License. See License in the project root for # license information. # -------------------------------------------------------------------------- +from logging import NOTSET, getLogger + from azure.monitor.opentelemetry.distro.util import get_configurations from azure.monitor.opentelemetry.exporter import ( ApplicationInsightsSampler, + AzureMonitorLogExporter, AzureMonitorTraceExporter, ) -from opentelemetry import trace +from opentelemetry.sdk._logs import ( + LoggerProvider, + LoggingHandler, + get_logger_provider, + set_logger_provider, +) +from opentelemetry.sdk._logs.export import BatchLogRecordProcessor from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.semconv.resource import ResourceAttributes +from opentelemetry.trace import get_tracer_provider, set_tracer_provider def configure_azure_monitor(**kwargs): @@ -23,16 +33,22 @@ def configure_azure_monitor(**kwargs): """ configurations = get_configurations(**kwargs) - disable_tracing = configurations.get("disable_tracing", False) service_name = configurations.get("service_name", "") service_namespace = configurations.get("service_namespace", "") service_instance_id = configurations.get("service_instance_id", "") + disable_logging = configurations.get("disable_logging", False) + logging_level = configurations.get("logging_level", NOTSET) + logging_export_interval_millis = configurations.get( + "logging_export_interval_millis", 30000 + ) + disable_tracing = configurations.get("disable_tracing", False) sampling_ratio = configurations.get("sampling_ratio", 1.0) tracing_export_interval_millis = configurations.get( "tracing_export_interval_millis", 30000 ) - if not disable_tracing: + resource = None + if not disable_logging or not disable_tracing: resource = Resource.create( { ResourceAttributes.SERVICE_NAME: service_name, @@ -40,14 +56,28 @@ def configure_azure_monitor(**kwargs): ResourceAttributes.SERVICE_INSTANCE_ID: service_instance_id, } ) + if not disable_logging: + logger_provider = LoggerProvider(resource=resource) + set_logger_provider(logger_provider) + log_exporter = AzureMonitorLogExporter(**kwargs) + log_record_processor = BatchLogRecordProcessor( + log_exporter, + export_timeout_millis=logging_export_interval_millis, + ) + get_logger_provider().add_log_record_processor(log_record_processor) + handler = LoggingHandler( + level=logging_level, logger_provider=get_logger_provider() + ) + getLogger().addHandler(handler) + if not disable_tracing: tracer_provider = TracerProvider( sampler=ApplicationInsightsSampler(sampling_ratio=sampling_ratio), resource=resource, ) - trace.set_tracer_provider(tracer_provider) - exporter = AzureMonitorTraceExporter(**kwargs) + set_tracer_provider(tracer_provider) + trace_exporter = AzureMonitorTraceExporter(**kwargs) span_processor = BatchSpanProcessor( - exporter, + trace_exporter, export_timeout_millis=tracing_export_interval_millis, ) - trace.get_tracer_provider().add_span_processor(span_processor) + get_tracer_provider().add_span_processor(span_processor) 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 3b5b84ea..7be1a631 100644 --- a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/distro.py +++ b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/distro.py @@ -13,6 +13,7 @@ AzureStatusLogger, ) from opentelemetry.environment_variables import ( + OTEL_LOGS_EXPORTER, OTEL_METRICS_EXPORTER, OTEL_TRACES_EXPORTER, ) @@ -55,6 +56,9 @@ def _configure_auto_instrumentation() -> None: environ.setdefault( OTEL_TRACES_EXPORTER, "azure_monitor_opentelemetry_exporter" ) + environ.setdefault( + OTEL_LOGS_EXPORTER, "azure_monitor_opentelemetry_exporter" + ) AzureStatusLogger.log_status(True) _logger.info( "Azure Monitor OpenTelemetry Distro configured successfully." diff --git a/azure-monitor-opentelemetry-distro/samples/logging/simple.py b/azure-monitor-opentelemetry-distro/samples/logging/simple.py new file mode 100644 index 00000000..75912efa --- /dev/null +++ b/azure-monitor-opentelemetry-distro/samples/logging/simple.py @@ -0,0 +1,30 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License in the project root for +# license information. +# -------------------------------------------------------------------------- + +from logging import WARN, getLogger + +from azure.monitor.opentelemetry.distro import configure_azure_monitor +from opentelemetry import trace + +configure_azure_monitor( + connection_string="", + service_name="foo_service", + logging_level=WARN, + disable_tracing=True, +) + +logger = getLogger(__name__) +tracer = trace.get_tracer(__name__) + +logger.info("info log") +logger.warning("warning log") +logger.error("error log") + +with tracer.start_as_current_span("hello"): + print("Hello, World!") + logger.info("Correlated info log") + logger.warning("Correlated warning log") + logger.error("Correlated error log") diff --git a/azure-monitor-opentelemetry-distro/samples/tracing/simple.py b/azure-monitor-opentelemetry-distro/samples/tracing/simple.py index c2de31ea..fbca7f1f 100644 --- a/azure-monitor-opentelemetry-distro/samples/tracing/simple.py +++ b/azure-monitor-opentelemetry-distro/samples/tracing/simple.py @@ -11,6 +11,7 @@ connection_string="", service_name="foo_service", tracing_export_interval_millis=15000, + disable_logging=True, ) tracer = trace.get_tracer(__name__) diff --git a/azure-monitor-opentelemetry-distro/tests/configuration/test_configure.py b/azure-monitor-opentelemetry-distro/tests/configuration/test_configure.py index b41ae37f..8bbfca25 100644 --- a/azure-monitor-opentelemetry-distro/tests/configuration/test_configure.py +++ b/azure-monitor-opentelemetry-distro/tests/configuration/test_configure.py @@ -26,6 +26,12 @@ class TestConfigure(unittest.TestCase): @patch( "azure.monitor.opentelemetry.distro.AzureMonitorTraceExporter", ) + @patch( + "azure.monitor.opentelemetry.distro.get_tracer_provider", + ) + @patch( + "azure.monitor.opentelemetry.distro.set_tracer_provider", + ) @patch( "azure.monitor.opentelemetry.distro.TracerProvider", autospec=True, @@ -34,32 +40,79 @@ class TestConfigure(unittest.TestCase): "azure.monitor.opentelemetry.distro.ApplicationInsightsSampler", ) @patch( - "azure.monitor.opentelemetry.distro.Resource", + "azure.monitor.opentelemetry.distro.getLogger", + ) + @patch( + "azure.monitor.opentelemetry.distro.LoggingHandler", + ) + @patch( + "azure.monitor.opentelemetry.distro.BatchLogRecordProcessor", + ) + @patch( + "azure.monitor.opentelemetry.distro.AzureMonitorLogExporter", ) @patch( - "azure.monitor.opentelemetry.distro.trace", + "azure.monitor.opentelemetry.distro.get_logger_provider", + ) + @patch( + "azure.monitor.opentelemetry.distro.set_logger_provider", + ) + @patch( + "azure.monitor.opentelemetry.distro.LoggerProvider", + autospec=True, + ) + @patch( + "azure.monitor.opentelemetry.distro.Resource", ) def test_configure_azure_monitor( self, - trace_mock, resource_mock, + lp_mock, + set_logger_provider_mock, + get_logger_provider_mock, + log_exporter_mock, + blrp_mock, + logging_handler_mock, + get_logger_mock, sampler_mock, tp_mock, - exporter_mock, + set_tracer_provider_mock, + get_tracer_provider_mock, + trace_exporter_mock, bsp_mock, ): - tp_init_mock = Mock() - tp_mock.return_value = tp_init_mock - exp_init_mock = Mock() - exporter_mock.return_value = exp_init_mock resource_init_mock = Mock() resource_mock.create.return_value = resource_init_mock + + lp_init_mock = Mock() + lp_mock.return_value = lp_init_mock + get_logger_provider_mock.return_value = lp_init_mock + log_exp_init_mock = Mock() + log_exporter_mock.return_value = log_exp_init_mock + blrp_init_mock = Mock() + blrp_mock.return_value = blrp_init_mock + logging_handler_init_mock = Mock() + logging_handler_mock.return_value = logging_handler_init_mock + logger_mock = Mock() + get_logger_mock.return_value = logger_mock + sampler_init_mock = Mock() sampler_mock.return_value = sampler_init_mock + tp_init_mock = Mock() + tp_mock.return_value = tp_init_mock + get_tracer_provider_mock.return_value = tp_init_mock + trace_exp_init_mock = Mock() + trace_exporter_mock.return_value = trace_exp_init_mock bsp_init_mock = Mock() bsp_mock.return_value = bsp_init_mock + configure_azure_monitor( + connection_string="test_cs", + console_exporting=False, + disable_logging=False, disable_tracing=False, + logging_export_interval_millis=10000, + logging_level="test_logging_level", service_name="test_service_name", service_namespace="test_namespace", service_instance_id="test_id", @@ -73,17 +126,37 @@ def test_configure_azure_monitor( ResourceAttributes.SERVICE_INSTANCE_ID: "test_id", } ) + + lp_mock.assert_called_once_with(resource=resource_init_mock) + set_logger_provider_mock.assert_called_once_with(lp_init_mock) + get_logger_provider_mock.assert_called() + log_exporter_mock.assert_called_once() + blrp_mock.assert_called_once_with( + log_exp_init_mock, export_timeout_millis=10000 + ) + lp_init_mock.add_log_record_processor.assert_called_once_with( + blrp_init_mock + ) + logging_handler_mock.assert_called_once_with( + level="test_logging_level", logger_provider=lp_init_mock + ) + get_logger_mock.assert_called_once_with() + logger_mock.addHandler.assert_called_once_with( + logging_handler_init_mock + ) + + sampler_mock.assert_called_once_with(sampling_ratio=0.5) tp_mock.assert_called_once_with( - sampler=sampler_init_mock, resource=resource_init_mock, + sampler=sampler_init_mock, ) - trace_mock.set_tracer_provider.assert_called_once_with(tp_init_mock) - exporter_mock.assert_called_once() - sampler_mock.assert_called_once_with(sampling_ratio=0.5) + set_tracer_provider_mock.assert_called_once_with(tp_init_mock) + get_tracer_provider_mock.assert_called() + trace_exporter_mock.assert_called_once() bsp_mock.assert_called_once_with( - exp_init_mock, - export_timeout_millis=15000, + trace_exp_init_mock, export_timeout_millis=15000 ) + tp_init_mock.add_span_processor(bsp_init_mock) @patch( "azure.monitor.opentelemetry.distro.BatchSpanProcessor", @@ -91,6 +164,12 @@ def test_configure_azure_monitor( @patch( "azure.monitor.opentelemetry.distro.AzureMonitorTraceExporter", ) + @patch( + "azure.monitor.opentelemetry.distro.get_tracer_provider", + ) + @patch( + "azure.monitor.opentelemetry.distro.set_tracer_provider", + ) @patch( "azure.monitor.opentelemetry.distro.TracerProvider", autospec=True, @@ -99,28 +178,67 @@ def test_configure_azure_monitor( "azure.monitor.opentelemetry.distro.ApplicationInsightsSampler", ) @patch( - "azure.monitor.opentelemetry.distro.Resource", + "azure.monitor.opentelemetry.distro.getLogger", ) @patch( - "azure.monitor.opentelemetry.distro.trace", + "azure.monitor.opentelemetry.distro.LoggingHandler", ) - def test_configure_azure_monitor_disable_tracing( + @patch( + "azure.monitor.opentelemetry.distro.BatchLogRecordProcessor", + ) + @patch( + "azure.monitor.opentelemetry.distro.AzureMonitorLogExporter", + ) + @patch( + "azure.monitor.opentelemetry.distro.get_logger_provider", + ) + @patch( + "azure.monitor.opentelemetry.distro.set_logger_provider", + ) + @patch( + "azure.monitor.opentelemetry.distro.LoggerProvider", + autospec=True, + ) + @patch( + "azure.monitor.opentelemetry.distro.Resource", + ) + def test_configure_azure_monitor_disable_tracing_and_logging( self, - trace_mock, resource_mock, + lp_mock, + set_logger_provider_mock, + get_logger_provider_mock, + log_exporter_mock, + blrp_mock, + logging_handler_mock, + get_logger_mock, sampler_mock, tp_mock, - exporter_mock, + set_tracer_provider_mock, + get_tracer_provider_mock, + trace_exporter_mock, bsp_mock, ): configure_azure_monitor( + connection_string="test_cs", + disable_logging=True, disable_tracing=True, ) resource_mock.assert_not_called() - tp_mock.assert_not_called() - trace_mock.set_tracer_provider.assert_not_called() + + lp_mock.assert_not_called() + set_logger_provider_mock.assert_not_called() + get_logger_provider_mock.assert_not_called() + log_exporter_mock.assert_not_called() + blrp_mock.assert_not_called() + logging_handler_mock.assert_not_called() + get_logger_mock.assert_not_called() + sampler_mock.assert_not_called() - exporter_mock.assert_not_called() + tp_mock.assert_not_called() + set_tracer_provider_mock.assert_not_called() + get_tracer_provider_mock.assert_not_called() + trace_exporter_mock.assert_not_called() bsp_mock.assert_not_called() @patch( @@ -129,6 +247,12 @@ def test_configure_azure_monitor_disable_tracing( @patch( "azure.monitor.opentelemetry.distro.AzureMonitorTraceExporter", ) + @patch( + "azure.monitor.opentelemetry.distro.get_tracer_provider", + ) + @patch( + "azure.monitor.opentelemetry.distro.set_tracer_provider", + ) @patch( "azure.monitor.opentelemetry.distro.TracerProvider", autospec=True, @@ -136,46 +260,218 @@ def test_configure_azure_monitor_disable_tracing( @patch( "azure.monitor.opentelemetry.distro.ApplicationInsightsSampler", ) + @patch( + "azure.monitor.opentelemetry.distro.getLogger", + ) + @patch( + "azure.monitor.opentelemetry.distro.LoggingHandler", + ) + @patch( + "azure.monitor.opentelemetry.distro.BatchLogRecordProcessor", + ) + @patch( + "azure.monitor.opentelemetry.distro.AzureMonitorLogExporter", + ) + @patch( + "azure.monitor.opentelemetry.distro.get_logger_provider", + ) + @patch( + "azure.monitor.opentelemetry.distro.set_logger_provider", + ) + @patch( + "azure.monitor.opentelemetry.distro.LoggerProvider", + autospec=True, + ) @patch( "azure.monitor.opentelemetry.distro.Resource", ) + def test_configure_azure_monitor_disable_tracing( + self, + resource_mock, + lp_mock, + set_logger_provider_mock, + get_logger_provider_mock, + log_exporter_mock, + blrp_mock, + logging_handler_mock, + get_logger_mock, + sampler_mock, + tp_mock, + set_tracer_provider_mock, + get_tracer_provider_mock, + trace_exporter_mock, + bsp_mock, + ): + resource_init_mock = Mock() + resource_mock.create.return_value = resource_init_mock + + lp_init_mock = Mock() + lp_mock.return_value = lp_init_mock + get_logger_provider_mock.return_value = lp_init_mock + log_exp_init_mock = Mock() + log_exporter_mock.return_value = log_exp_init_mock + blrp_init_mock = Mock() + blrp_mock.return_value = blrp_init_mock + logging_handler_init_mock = Mock() + logging_handler_mock.return_value = logging_handler_init_mock + logger_mock = Mock() + get_logger_mock.return_value = logger_mock + + configure_azure_monitor( + connection_string="test_cs", + console_exporting=False, + disable_logging=False, + disable_tracing=True, + logging_export_interval_millis=10000, + logging_level="test_logging_level", + service_name="test_service_name", + service_namespace="test_namespace", + service_instance_id="test_id", + ) + resource_mock.create.assert_called_once_with( + { + ResourceAttributes.SERVICE_NAME: "test_service_name", + ResourceAttributes.SERVICE_NAMESPACE: "test_namespace", + ResourceAttributes.SERVICE_INSTANCE_ID: "test_id", + } + ) + + lp_mock.assert_called_once_with(resource=resource_init_mock) + set_logger_provider_mock.assert_called_once_with(lp_init_mock) + get_logger_provider_mock.assert_called() + log_exporter_mock.assert_called_once() + blrp_mock.assert_called_once_with( + log_exp_init_mock, export_timeout_millis=10000 + ) + lp_init_mock.add_log_record_processor.assert_called_once_with( + blrp_init_mock + ) + logging_handler_mock.assert_called_once_with( + level="test_logging_level", logger_provider=lp_init_mock + ) + get_logger_mock.assert_called_once_with() + logger_mock.addHandler.assert_called_once_with( + logging_handler_init_mock + ) + + sampler_mock.assert_not_called() + tp_mock.assert_not_called() + set_tracer_provider_mock.assert_not_called() + get_tracer_provider_mock.assert_not_called() + trace_exporter_mock.assert_not_called() + bsp_mock.assert_not_called() + + @patch( + "azure.monitor.opentelemetry.distro.BatchSpanProcessor", + ) + @patch( + "azure.monitor.opentelemetry.distro.AzureMonitorTraceExporter", + ) + @patch( + "azure.monitor.opentelemetry.distro.get_tracer_provider", + ) + @patch( + "azure.monitor.opentelemetry.distro.set_tracer_provider", + ) + @patch( + "azure.monitor.opentelemetry.distro.TracerProvider", + autospec=True, + ) + @patch( + "azure.monitor.opentelemetry.distro.ApplicationInsightsSampler", + ) + @patch( + "azure.monitor.opentelemetry.distro.getLogger", + ) @patch( - "azure.monitor.opentelemetry.distro.trace", + "azure.monitor.opentelemetry.distro.LoggingHandler", ) - def test_configure_azure_monitor_exporter( + @patch( + "azure.monitor.opentelemetry.distro.BatchLogRecordProcessor", + ) + @patch( + "azure.monitor.opentelemetry.distro.AzureMonitorLogExporter", + ) + @patch( + "azure.monitor.opentelemetry.distro.get_logger_provider", + ) + @patch( + "azure.monitor.opentelemetry.distro.set_logger_provider", + ) + @patch( + "azure.monitor.opentelemetry.distro.LoggerProvider", + autospec=True, + ) + @patch( + "azure.monitor.opentelemetry.distro.Resource", + ) + def test_configure_azure_monitor_disable_logging( self, - trace_mock, resource_mock, + lp_mock, + set_logger_provider_mock, + get_logger_provider_mock, + log_exporter_mock, + blrp_mock, + logging_handler_mock, + get_logger_mock, sampler_mock, tp_mock, - exporter_mock, + set_tracer_provider_mock, + get_tracer_provider_mock, + trace_exporter_mock, bsp_mock, ): - tp_init_mock = Mock() - tp_mock.return_value = tp_init_mock - exp_init_mock = Mock() - exporter_mock.return_value = exp_init_mock resource_init_mock = Mock() resource_mock.create.return_value = resource_init_mock + sampler_init_mock = Mock() sampler_mock.return_value = sampler_init_mock + tp_init_mock = Mock() + tp_mock.return_value = tp_init_mock + get_tracer_provider_mock.return_value = tp_init_mock + trace_exp_init_mock = Mock() + trace_exporter_mock.return_value = trace_exp_init_mock bsp_init_mock = Mock() bsp_mock.return_value = bsp_init_mock - kwargs = { - "connection_string": "test_cs", - "api_version": "1.0", - "disable_offline_storage": True, - "storage_maintenance_period": 50, - "storage_max_size": 1024, - "storage_min_retry_interval": 30, - "storage_directory": "/tmp", - "storage_retention_period": 60, - "timeout": 30, - } - configure_azure_monitor(**kwargs) - resource_mock.create.assert_called_once() - tp_mock.assert_called_once() - trace_mock.set_tracer_provider.assert_called_once() - exporter_mock.assert_called_once_with(**kwargs) - sampler_mock.assert_called_once() - bsp_mock.assert_called_once() + + configure_azure_monitor( + connection_string="test_cs", + console_exporting=False, + disable_logging=True, + disable_tracing=False, + logging_level="test_logging_level", + service_name="test_service_name", + service_namespace="test_namespace", + service_instance_id="test_id", + sampling_ratio=0.5, + tracing_export_interval_millis=15000, + ) + resource_mock.create.assert_called_once_with( + { + ResourceAttributes.SERVICE_NAME: "test_service_name", + ResourceAttributes.SERVICE_NAMESPACE: "test_namespace", + ResourceAttributes.SERVICE_INSTANCE_ID: "test_id", + } + ) + + lp_mock.assert_not_called() + set_logger_provider_mock.assert_not_called() + get_logger_provider_mock.assert_not_called() + log_exporter_mock.assert_not_called() + blrp_mock.assert_not_called() + logging_handler_mock.assert_not_called() + get_logger_mock.assert_not_called() + + sampler_mock.assert_called_once_with(sampling_ratio=0.5) + tp_mock.assert_called_once_with( + resource=resource_init_mock, + sampler=sampler_init_mock, + ) + set_tracer_provider_mock.assert_called_once_with(tp_init_mock) + get_tracer_provider_mock.assert_called() + trace_exporter_mock.assert_called_once() + bsp_mock.assert_called_once_with( + trace_exp_init_mock, export_timeout_millis=15000 + ) + tp_init_mock.add_span_processor(bsp_init_mock) diff --git a/azure-monitor-opentelemetry-distro/tests/configuration/test_util.py b/azure-monitor-opentelemetry-distro/tests/configuration/test_util.py index 1d867d86..01678e9f 100644 --- a/azure-monitor-opentelemetry-distro/tests/configuration/test_util.py +++ b/azure-monitor-opentelemetry-distro/tests/configuration/test_util.py @@ -21,20 +21,32 @@ class TestUtil(unittest.TestCase): def test_get_configurations(self): configurations = get_configurations( connection_string="test_cs", - disable_tracing="test_disable", + disable_logging="test_disable_logging", + disable_tracing="test_disable_tracing", + logging_level="test_logging_level", service_name="test_service_name", service_namespace="test_namespace", service_instance_id="test_id", sampling_ratio="test_sample_ratio", - tracing_export_interval="test_interval", + tracing_export_interval="test_tracing_interval", + logging_export_interval="test_logging_interval", ) self.assertEqual(configurations["connection_string"], "test_cs") - self.assertEqual(configurations["disable_tracing"], "test_disable") + self.assertEqual( + configurations["disable_logging"], "test_disable_logging" + ) + self.assertEqual( + configurations["disable_tracing"], "test_disable_tracing" + ) + self.assertEqual(configurations["logging_level"], "test_logging_level") self.assertEqual(configurations["service_name"], "test_service_name") self.assertEqual(configurations["service_namespace"], "test_namespace") self.assertEqual(configurations["service_instance_id"], "test_id") self.assertEqual(configurations["sampling_ratio"], "test_sample_ratio") self.assertEqual( - configurations["tracing_export_interval"], "test_interval" + configurations["tracing_export_interval"], "test_tracing_interval" + ) + self.assertEqual( + configurations["logging_export_interval"], "test_logging_interval" )