Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,33 @@
# 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
from opentelemetry.sdk.trace.export import BatchSpanProcessor
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"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove conn str?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are taking advantage of passing in the whole kwargs into the exporter so no need to explicitly extract the 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(
Expand All @@ -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)
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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="<your-connection-string>",
service_name="foo_service",
tracing_export_interval_millis=15000,
)

tracer = trace.get_tracer(__name__)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand All @@ -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,
Expand All @@ -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(
{
Expand All @@ -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",
Expand All @@ -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()
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,16 @@ 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")
self.assertEqual(configurations["disable_tracing"], "test_disable")
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"
)