diff --git a/CHANGELOG.md b/CHANGELOG.md index f862bdc5..5a9a994a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ ([#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)) ## [1.0.0b8](https://github.com/microsoft/ApplicationInsights-Python/releases/tag/v1.0.0b8) - 2022-09-26 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 ec52d899..32c6259d 100644 --- a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/__init__.py +++ b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/__init__.py @@ -4,7 +4,10 @@ # license information. # -------------------------------------------------------------------------- from azure.monitor.opentelemetry.distro.util import get_configurations -from azure.monitor.opentelemetry.exporter import AzureMonitorTraceExporter +from azure.monitor.opentelemetry.exporter import ( + ApplicationInsightsSampler, + AzureMonitorTraceExporter, +) from opentelemetry import trace from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider @@ -12,21 +15,22 @@ from opentelemetry.semconv.resource import ResourceAttributes -def configure_opentelemetry(**kwargs): +def configure_azure_monitor(**kwargs): """ This function works as a configuration layer that allows the end user to configure OpenTelemetry and Azure monitor components. The - configuration can be done via environment variables or - via arguments passed to this function. Each argument has a 1:1 - correspondence with an environment variable. + configuration can be done via arguments passed to this function. """ configurations = get_configurations(**kwargs) - connection_string = configurations["connection_string"] - service_name = configurations["service_name"] - service_namespace = configurations["service_namespace"] - service_instance_id = configurations["service_instance_id"] - disable_tracing = configurations["disable_tracing"] + 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", "") + sampling_ratio = configurations.get("sampling_ratio", 1.0) + tracing_export_interval_millis = configurations.get( + "tracing_export_interval_millis", 30000 + ) if not disable_tracing: resource = Resource.create( @@ -36,9 +40,14 @@ def configure_opentelemetry(**kwargs): ResourceAttributes.SERVICE_INSTANCE_ID: service_instance_id, } ) - trace.set_tracer_provider(TracerProvider(resource=resource)) - exporter = AzureMonitorTraceExporter( - connection_string=connection_string + tracer_provider = TracerProvider( + sampler=ApplicationInsightsSampler(sampling_ratio=sampling_ratio), + resource=resource, + ) + trace.set_tracer_provider(tracer_provider) + exporter = AzureMonitorTraceExporter(**kwargs) + span_processor = BatchSpanProcessor( + exporter, + export_timeout_millis=tracing_export_interval_millis, ) - span_processor = BatchSpanProcessor(exporter) trace.get_tracer_provider().add_span_processor(span_processor) diff --git a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/util/__init__.py b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/util/__init__.py index 46de6634..7ca337ae 100644 --- a/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/util/__init__.py +++ b/azure-monitor-opentelemetry-distro/azure/monitor/opentelemetry/distro/util/__init__.py @@ -10,17 +10,10 @@ def get_configurations(**kwargs) -> Dict[str, Any]: configurations = {} - # In-code configurations take priority - configurations["connection_string"] = kwargs.get("connection_string", None) - configurations["disable_tracing"] = kwargs.get("disable_tracing", False) - configurations["service_name"] = kwargs.get("service_name", "") - configurations["service_namespace"] = kwargs.get("service_namespace", "") - configurations["service_instance_id"] = kwargs.get( - "service_instance_id", "" - ) - - # TODO: Support addtional env vars configurations - # if configurations.get("disable_tracing") is None: - # configurations["disable_tracing"] = False + for key, val in kwargs.items(): + configurations[key] = val return configurations + + +# TODO: Add env var configuration diff --git a/azure-monitor-opentelemetry-distro/samples/simple.py b/azure-monitor-opentelemetry-distro/samples/tracing/simple.py similarity index 67% rename from azure-monitor-opentelemetry-distro/samples/simple.py rename to azure-monitor-opentelemetry-distro/samples/tracing/simple.py index f8d7178a..c2de31ea 100644 --- a/azure-monitor-opentelemetry-distro/samples/simple.py +++ b/azure-monitor-opentelemetry-distro/samples/tracing/simple.py @@ -4,10 +4,14 @@ # license information. # -------------------------------------------------------------------------- -from azure.monitor.opentelemetry.distro import configure_opentelemetry +from azure.monitor.opentelemetry.distro import configure_azure_monitor from opentelemetry import trace -configure_opentelemetry() +configure_azure_monitor( + connection_string="", + service_name="foo_service", + tracing_export_interval_millis=15000, +) 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 16173423..b41ae37f 100644 --- a/azure-monitor-opentelemetry-distro/tests/configuration/test_configure.py +++ b/azure-monitor-opentelemetry-distro/tests/configuration/test_configure.py @@ -15,7 +15,7 @@ import unittest from unittest.mock import Mock, patch -from azure.monitor.opentelemetry.distro import configure_opentelemetry +from azure.monitor.opentelemetry.distro import configure_azure_monitor from opentelemetry.semconv.resource import ResourceAttributes @@ -30,16 +30,20 @@ class TestConfigure(unittest.TestCase): "azure.monitor.opentelemetry.distro.TracerProvider", autospec=True, ) + @patch( + "azure.monitor.opentelemetry.distro.ApplicationInsightsSampler", + ) @patch( "azure.monitor.opentelemetry.distro.Resource", ) @patch( "azure.monitor.opentelemetry.distro.trace", ) - def test_configure_opentelemetry( + def test_configure_azure_monitor( self, trace_mock, resource_mock, + sampler_mock, tp_mock, exporter_mock, bsp_mock, @@ -50,14 +54,17 @@ def test_configure_opentelemetry( 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 bsp_init_mock = Mock() bsp_mock.return_value = bsp_init_mock - configure_opentelemetry( - connection_string="test_cs", + configure_azure_monitor( disable_tracing=False, 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( { @@ -66,10 +73,17 @@ def test_configure_opentelemetry( ResourceAttributes.SERVICE_INSTANCE_ID: "test_id", } ) - tp_mock.assert_called_once_with(resource=resource_init_mock) + tp_mock.assert_called_once_with( + sampler=sampler_init_mock, + resource=resource_init_mock, + ) trace_mock.set_tracer_provider.assert_called_once_with(tp_init_mock) - exporter_mock.assert_called_once_with(connection_string="test_cs") - bsp_mock.assert_called_once_with(exp_init_mock) + exporter_mock.assert_called_once() + sampler_mock.assert_called_once_with(sampling_ratio=0.5) + bsp_mock.assert_called_once_with( + exp_init_mock, + export_timeout_millis=15000, + ) @patch( "azure.monitor.opentelemetry.distro.BatchSpanProcessor", @@ -81,26 +95,87 @@ def test_configure_opentelemetry( "azure.monitor.opentelemetry.distro.TracerProvider", autospec=True, ) + @patch( + "azure.monitor.opentelemetry.distro.ApplicationInsightsSampler", + ) @patch( "azure.monitor.opentelemetry.distro.Resource", ) @patch( "azure.monitor.opentelemetry.distro.trace", ) - def test_configure_opentelemetry_disable_tracing( + def test_configure_azure_monitor_disable_tracing( self, trace_mock, resource_mock, + sampler_mock, tp_mock, exporter_mock, bsp_mock, ): - configure_opentelemetry( - connection_string="test_cs", + configure_azure_monitor( disable_tracing=True, ) resource_mock.assert_not_called() tp_mock.assert_not_called() trace_mock.set_tracer_provider.assert_not_called() + sampler_mock.assert_not_called() 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.TracerProvider", + autospec=True, + ) + @patch( + "azure.monitor.opentelemetry.distro.ApplicationInsightsSampler", + ) + @patch( + "azure.monitor.opentelemetry.distro.Resource", + ) + @patch( + "azure.monitor.opentelemetry.distro.trace", + ) + def test_configure_azure_monitor_exporter( + self, + trace_mock, + resource_mock, + sampler_mock, + tp_mock, + 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 + 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() diff --git a/azure-monitor-opentelemetry-distro/tests/configuration/test_util.py b/azure-monitor-opentelemetry-distro/tests/configuration/test_util.py index 9524cd1a..1d867d86 100644 --- a/azure-monitor-opentelemetry-distro/tests/configuration/test_util.py +++ b/azure-monitor-opentelemetry-distro/tests/configuration/test_util.py @@ -25,6 +25,8 @@ def test_get_configurations(self): service_name="test_service_name", service_namespace="test_namespace", service_instance_id="test_id", + sampling_ratio="test_sample_ratio", + tracing_export_interval="test_interval", ) self.assertEqual(configurations["connection_string"], "test_cs") @@ -32,11 +34,7 @@ def test_get_configurations(self): self.assertEqual(configurations["service_name"], "test_service_name") self.assertEqual(configurations["service_namespace"], "test_namespace") self.assertEqual(configurations["service_instance_id"], "test_id") - - def test_get_configurations_default(self): - configurations = get_configurations() - self.assertEqual(configurations["connection_string"], None) - self.assertEqual(configurations["disable_tracing"], False) - self.assertEqual(configurations["service_name"], "") - self.assertEqual(configurations["service_namespace"], "") - self.assertEqual(configurations["service_instance_id"], "") + self.assertEqual(configurations["sampling_ratio"], "test_sample_ratio") + self.assertEqual( + configurations["tracing_export_interval"], "test_interval" + )