Thanks to visit codestin.com
Credit goes to github.com

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 @@ -4,6 +4,8 @@

- Upgrade to exporter 1.0.0b14 and OTel 1.18
([#295](https://github.com/microsoft/ApplicationInsights-Python/pull/295))
- Enable Azure Core Tracing OpenTelemetry plugin
([#269](https://github.com/microsoft/ApplicationInsights-Python/pull/269))

## [1.0.0b13](https://github.com/microsoft/ApplicationInsights-Python/releases/tag/v1.0.0b13) - 2023-06-14

Expand Down
9 changes: 7 additions & 2 deletions azure-monitor-opentelemetry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ OpenTelemetry instrumentations allow automatic collection of requests sent from
| [OpenTelemetry UrlLib Instrumentation][ot_instrumentation_urllib] | [urllib][pypi_urllib] | All
| [OpenTelemetry UrlLib3 Instrumentation][ot_instrumentation_urllib3] | [urllib3][pypi_urllib3] | [link][ot_instrumentation_urllib3_version]

## Azure Core Distributed Tracing

Using the [Azure Core Tracing OpenTelemetry][azure_core_tracing_opentelemetry_plugin] library, you can automatically capture the distributed tracing from Azure Core libraries. See the associated [sample][azure_core_tracing_opentelemetry_plugin_sample] for more information. This feature is enabled automatically.

## Getting started

### Key Concepts
Expand Down Expand Up @@ -68,8 +72,7 @@ You can configure further with [OpenTelemetry environment variables][ot_env_vars
| `OTEL_BSP_SCHEDULE_DELAY` | Specifies the distributed tracing export interval in milliseconds. Defaults to 5000. |
| `OTEL_TRACES_SAMPLER_ARG` | 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. |
| `OTEL_PYTHON_DISABLED_INSTRUMENTATIONS` | Specifies which of the supported instrumentations to disable. Disabled instrumentations will not be instrumented as part of `configure_azure_monitor`. However, they can still be manually instrumented by users after the fact. Accepts a comma-separated list of lowercase entry point names for instrumentations. For example, set to `"psycopg2,fastapi"` to disable the Psycopg2 and FastAPI instrumentations. Defaults to an empty list, enabling all supported instrumentations. |
<!-- TODO: add once OTEL_LOG_LEVEL is supported in sdk -->
<!-- Specifies the [logging level][logging_level] of the logs you would like to collect for your logging pipeline. Defaults to 0 which is `logging.NOTSET`. | OTEL_LOG_LEVEL | -->


#### Azure monitor OpenTelemetry Exporter configurations

Expand All @@ -95,6 +98,8 @@ Samples are available [here][samples] to demonstrate how to utilize the above co
* [OpenTelemetry Python Official Docs][ot_python_docs]

<!-- LINKS -->
[azure_core_tracing_opentelemetry_plugin]:https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/core/azure-core-tracing-opentelemetry
[azure_core_tracing_opentelemetry_plugin_sample]: https://github.com/microsoft/ApplicationInsights-Python/tree/main/azure-monitor-opentelemetry/samples/tracing/azure_core.py
[azure_monitor_opentelemetry]: https://learn.microsoft.com/azure/azure-monitor/app/opentelemetry-enable?tabs=python
[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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
from logging import getLogger
from typing import Dict

from azure.core.settings import settings
from azure.core.tracing.ext.opentelemetry_span import OpenTelemetrySpan
from azure.monitor.opentelemetry._constants import (
DISABLE_AZURE_CORE_TRACING_ARG,
DISABLE_LOGGING_ARG,
DISABLE_METRICS_ARG,
DISABLE_TRACING_ARG,
Expand Down Expand Up @@ -104,6 +107,9 @@ def _setup_tracing(configurations: Dict[str, ConfigurationValue]):
trace_exporter,
)
get_tracer_provider().add_span_processor(span_processor)
disable_azure_core_tracing = configurations[DISABLE_AZURE_CORE_TRACING_ARG]
if not disable_azure_core_tracing:
settings.tracing_implementation = OpenTelemetrySpan


def _setup_logging(configurations: Dict[str, ConfigurationValue]):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# --------------------Configuration------------------------------------------

CONNECTION_STRING_ARG = "connection_string"
DISABLE_AZURE_CORE_TRACING_ARG = "disable_azure_core_tracing"
DISABLE_LOGGING_ARG = "disable_logging"
DISABLE_METRICS_ARG = "disable_metrics"
DISABLE_TRACING_ARG = "disable_tracing"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import logging
from os import environ

from azure.core.settings import settings
from azure.core.tracing.ext.opentelemetry_span import OpenTelemetrySpan
from azure.monitor.opentelemetry._vendor.v0_39b0.opentelemetry.instrumentation.distro import (
BaseDistro,
)
Expand Down Expand Up @@ -46,12 +48,6 @@ def _configure_auto_instrumentation() -> None:
AzureStatusLogger.log_status(False, "Distro being configured.")
AzureDiagnosticLogging.enable(_logger)
AzureDiagnosticLogging.enable(_opentelemetry_logger)
# TODO: Enabled when duplicate logging issue is solved
Copy link
Contributor

Choose a reason for hiding this comment

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

IS this TODO no longer needed?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah. Turns out diagnostic logging for attach is supposed to work differently. Has to do with AppLens.

# if _EXPORTER_DIAGNOSTICS_ENABLED:
# exporter_logger = logging.getLogger(
# "azure.monitor.opentelemetry.exporter"
# )
# AzureDiagnosticLogging.enable(_exporter_logger)
environ.setdefault(
OTEL_METRICS_EXPORTER, "azure_monitor_opentelemetry_exporter"
)
Expand All @@ -64,6 +60,7 @@ def _configure_auto_instrumentation() -> None:
environ.setdefault(
_OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED, "true"
)
settings.tracing_implementation = OpenTelemetrySpan
AzureStatusLogger.log_status(True)
_logger.info(
"Azure Monitor OpenTelemetry Distro configured successfully."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from typing import Dict

from azure.monitor.opentelemetry._constants import (
DISABLE_AZURE_CORE_TRACING_ARG,
DISABLE_LOGGING_ARG,
DISABLE_METRICS_ARG,
DISABLE_TRACING_ARG,
Expand Down Expand Up @@ -52,6 +53,7 @@ def _get_configurations(**kwargs) -> Dict[str, ConfigurationValue]:
_default_disabled_instrumentations(configurations)
_default_logging_export_interval_ms(configurations)
_default_sampling_ratio(configurations)
_default_disable_azure_core_tracing(configurations)

# TODO: remove when validation added to BLRP
if configurations[LOGGING_EXPORT_INTERVAL_MS_ARG] <= 0:
Expand Down Expand Up @@ -125,3 +127,8 @@ def _default_sampling_ratio(configurations):
_INVALID_FLOAT_MESSAGE, SAMPLING_RATIO_ENV_VAR, default, e
)
configurations[SAMPLING_RATIO_ARG] = default


# TODO: Placeholder for future configuration
def _default_disable_azure_core_tracing(configurations):
configurations[DISABLE_AZURE_CORE_TRACING_ARG] = False
18 changes: 18 additions & 0 deletions azure-monitor-opentelemetry/samples/tracing/azure_core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from os import environ

from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import trace

# Set up exporting to Azure Monitor
configure_azure_monitor()

# Example with Storage SDKs

from azure.storage.blob import BlobServiceClient

tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span(name="MyApplication"):
client = BlobServiceClient.from_connection_string(
environ["AZURE_STORAGE_ACCOUNT_CONNECTION_STRING"]
)
client.create_container("mycontainer") # Call will be traced
1 change: 1 addition & 0 deletions azure-monitor-opentelemetry/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
},
python_requires=">=3.7",
install_requires=[
"azure-core-tracing-opentelemetry==1.0.0b9",
"azure-monitor-opentelemetry-exporter>=1.0.0b14",
"opentelemetry-api==1.18.0",
"opentelemetry-sdk==1.18.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,21 @@
from unittest import TestCase
from unittest.mock import patch

from azure.core.tracing.ext.opentelemetry_span import OpenTelemetrySpan
from azure.monitor.opentelemetry.autoinstrumentation._distro import (
AzureMonitorDistro,
)


class TestDistro(TestCase):
@patch("azure.monitor.opentelemetry.autoinstrumentation._distro.settings")
@patch(
"azure.monitor.opentelemetry.autoinstrumentation._distro.AzureDiagnosticLogging.enable"
)
# TODO: Enabled when duplicate logging issue is solved
# @patch(
# "azure.monitor.opentelemetry.autoinstrumentation._diagnostic_logging._EXPORTER_DIAGNOSTICS_ENABLED",
# False,
# )
def test_configure(self, mock_diagnostics):
def test_configure(self, mock_diagnostics, azure_core_mock):
distro = AzureMonitorDistro()
distro.configure()
self.assertEqual(mock_diagnostics.call_count, 2)

# TODO: Enabled when duplicate logging issue is solved
# @patch(
# "azure.monitor.opentelemetry.autoinstrumentation._distro.AzureDiagnosticLogging.enable"
# )
# @patch(
# "azure.monitor.opentelemetry.autoinstrumentation._diagnostic_logging._EXPORTER_DIAGNOSTICS_ENABLED",
# True,
# )
# def test_configure_exporter_diagnostics(self, mock_diagnostics):
# distro = AzureMonitorDistro()
# distro.configure()
# self.assertEqual(mock_diagnostics.call_count, 3)
self.assertEqual(
azure_core_mock.tracing_implementation, OpenTelemetrySpan
)
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import unittest
from unittest.mock import Mock, patch

from azure.core.tracing.ext.opentelemetry_span import OpenTelemetrySpan
from azure.monitor.opentelemetry._configure import (
_SUPPORTED_INSTRUMENTED_LIBRARIES_DEPENDENCIES_MAP,
_setup_instrumentations,
Expand Down Expand Up @@ -162,6 +163,9 @@ def test_configure_azure_monitor_disable_metrics(
metrics_mock.assert_not_called()
instrumentation_mock.assert_called_once_with(configurations)

@patch(
"azure.monitor.opentelemetry._configure.settings",
)
@patch(
"azure.monitor.opentelemetry._configure.BatchSpanProcessor",
)
Expand Down Expand Up @@ -189,6 +193,7 @@ def test_setup_tracing(
get_tracer_provider_mock,
trace_exporter_mock,
bsp_mock,
azure_core_mock,
):
sampler_init_mock = Mock()
sampler_mock.return_value = sampler_init_mock
Expand All @@ -202,6 +207,7 @@ def test_setup_tracing(

configurations = {
"connection_string": "test_cs",
"disable_azure_core_tracing": False,
"sampling_ratio": 0.5,
}
_setup_tracing(configurations)
Expand All @@ -214,6 +220,9 @@ def test_setup_tracing(
trace_exporter_mock.assert_called_once_with(**configurations)
bsp_mock.assert_called_once_with(trace_exp_init_mock)
tp_init_mock.add_span_processor.assert_called_once_with(bsp_init_mock)
self.assertEqual(
azure_core_mock.tracing_implementation, OpenTelemetrySpan
)

@patch(
"azure.monitor.opentelemetry._configure.getLogger",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def test_get_configurations(self):
)

self.assertEqual(configurations["connection_string"], "test_cs")
self.assertEqual(configurations["disable_azure_core_tracing"], False)
self.assertEqual(configurations["disable_logging"], False)
self.assertEqual(configurations["disable_metrics"], False)
self.assertEqual(configurations["disable_tracing"], False)
Expand All @@ -52,6 +53,7 @@ def test_get_configurations_defaults(self):
configurations = _get_configurations()

self.assertTrue("connection_string" not in configurations)
self.assertEqual(configurations["disable_azure_core_tracing"], False)
self.assertEqual(configurations["disable_logging"], False)
self.assertEqual(configurations["disable_metrics"], False)
self.assertEqual(configurations["disable_tracing"], False)
Expand Down Expand Up @@ -87,6 +89,7 @@ def test_get_configurations_env_vars(self):
configurations = _get_configurations()

self.assertTrue("connection_string" not in configurations)
self.assertEqual(configurations["disable_azure_core_tracing"], False)
self.assertEqual(configurations["disable_logging"], True)
self.assertEqual(configurations["disable_metrics"], True)
self.assertEqual(configurations["disable_tracing"], True)
Expand All @@ -112,6 +115,7 @@ def test_get_configurations_env_vars_validation(self):
configurations = _get_configurations()

self.assertTrue("connection_string" not in configurations)
self.assertEqual(configurations["disable_azure_core_tracing"], False)
self.assertEqual(configurations["disable_logging"], False)
self.assertEqual(configurations["disable_metrics"], False)
self.assertEqual(configurations["disable_tracing"], False)
Expand Down