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
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

### Other Changes

- Update live metrics to use typespec generated swagger
([#34840](https://github.com/Azure/azure-sdk-for-python/pull/34840))

## 1.0.0b25 (2024-04-19)

### Features Added
Expand Down
9 changes: 9 additions & 0 deletions sdk/monitor/azure-monitor-opentelemetry/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

### Features Added

- Enable live metrics feature
([#35566](https://github.com/Azure/azure-sdk-for-python/pull/35566))

### Breaking Changes

### Bugs Fixed
Expand All @@ -17,6 +20,12 @@
- Add diagnostics for sdk detection and backoff
([#35610](https://github.com/Azure/azure-sdk-for-python/pull/35610))

### Breaking Changes

### Bugs Fixed

### Other Changes

## 1.4.1 (2024-04-25)

### Features Added
Expand Down
2 changes: 2 additions & 0 deletions sdk/monitor/azure-monitor-opentelemetry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ You can use `configure_azure_monitor` to set up instrumentation for your app to
| Parameter | Description | Environment Variable |
|-------------------|----------------------------------------------------|----------------------|
| `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. | `APPLICATIONINSIGHTS_CONNECTION_STRING` |
| `enable_live_metrics` | Enable [live metrics][application_insights_live_metrics] feature. Defaults to `False`. | `N/A` |
| `logger_name` | The name of the [Python logger][python_logger] under which telemetry is collected. | `N/A` |
| `instrumentation_options` | A nested dictionary that determines which instrumentations to enable or disable. Instrumentations are referred to by their [Library Names](#officially-supported-instrumentations). For example, `{"azure_sdk": {"enabled": False}, "flask": {"enabled": False}, "django": {"enabled": True}}` will disable Azure Core Tracing and the Flask instrumentation but leave Django and the other default instrumentations enabled. The `OTEL_PYTHON_DISABLED_INSTRUMENTATIONS` environment variable explained below can also be used to disable instrumentations. | `N/A` |
| `resource` | Specifies the OpenTelemetry [Resource][ot_spec_resource] associated with your application. Passed in [Resource Attributes][ot_spec_resource_attributes] take priority over default attributes and those from [Resource Detectors][ot_python_resource_detectors]. | [OTEL_SERVICE_NAME][ot_spec_service_name], [OTEL_RESOURCE_ATTRIBUTES][ot_spec_resource_attributes], [OTEL_EXPERIMENTAL_RESOURCE_DETECTORS][ot_python_resource_detectors] |
Expand Down Expand Up @@ -210,6 +211,7 @@ contact [[email protected]](mailto:[email protected]) with any additio
[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_live_metrics]: https://learn.microsoft.com/azure/azure-monitor/app/live-stream
[application_insights_namespace]: https://learn.microsoft.com/azure/azure-monitor/app/app-insights-overview
[application_insights_sampling]: https://learn.microsoft.com/azure/azure-monitor/app/sampling
[connection_string_doc]: https://learn.microsoft.com/azure/azure-monitor/app/sdk-connection-string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from logging import getLogger
from typing import Dict, cast

from opentelemetry._logs import get_logger_provider, set_logger_provider
from opentelemetry._logs import set_logger_provider
from opentelemetry.instrumentation.dependencies import (
get_dist_dependency_conflicts,
)
Expand All @@ -21,7 +21,7 @@
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.trace import get_tracer_provider, set_tracer_provider
from opentelemetry.trace import set_tracer_provider
from pkg_resources import iter_entry_points # type: ignore

from azure.core.settings import settings
Expand All @@ -32,12 +32,18 @@
DISABLE_LOGGING_ARG,
DISABLE_METRICS_ARG,
DISABLE_TRACING_ARG,
ENABLE_LIVE_METRICS_ARG,
LOGGER_NAME_ARG,
RESOURCE_ARG,
SAMPLING_RATIO_ARG,
SPAN_PROCESSORS_ARG,
)
from azure.monitor.opentelemetry._types import ConfigurationValue
from azure.monitor.opentelemetry.exporter._quickpulse import enable_live_metrics # pylint: disable=import-error,no-name-in-module
from azure.monitor.opentelemetry.exporter._quickpulse._processor import ( # pylint: disable=import-error,no-name-in-module
_QuickpulseLogRecordProcessor,
_QuickpulseSpanProcessor,
)
from azure.monitor.opentelemetry.exporter import ( # pylint: disable=import-error,no-name-in-module
ApplicationInsightsSampler,
AzureMonitorLogExporter,
Expand Down Expand Up @@ -78,6 +84,8 @@ def configure_azure_monitor(**kwargs) -> None: # pylint: disable=C4758
Attributes take priority over default attributes and those from Resource Detectors.
:keyword list[~opentelemetry.sdk.trace.SpanProcessor] span_processors: List of `SpanProcessor` objects
to process every span prior to exporting. Will be run sequentially.
:keyword bool enable_live_metrics: Boolean value to determine whether to enable live metrics feature.
Defaults to `False`.
:keyword str storage_directory: Storage directory in which to store retry files. Defaults to
`<tempfile.gettempdir()>/Microsoft/AzureMonitor/opentelemetry-python-<your-instrumentation-key>`.
:rtype: None
Expand All @@ -90,6 +98,7 @@ def configure_azure_monitor(**kwargs) -> None: # pylint: disable=C4758
disable_tracing = configurations[DISABLE_TRACING_ARG]
disable_logging = configurations[DISABLE_LOGGING_ARG]
disable_metrics = configurations[DISABLE_METRICS_ARG]
enable_live_metrics_config = configurations[ENABLE_LIVE_METRICS_ARG]

# Setup tracing pipeline
if not disable_tracing:
Expand All @@ -103,6 +112,10 @@ def configure_azure_monitor(**kwargs) -> None: # pylint: disable=C4758
if not disable_metrics:
_setup_metrics(configurations)

# Setup live metrics
if enable_live_metrics_config:
_setup_live_metrics(configurations)

# Setup instrumentations
# Instrumentations need to be setup last so to use the global providers
# instanstiated in the other setup steps
Expand All @@ -116,28 +129,34 @@ def _setup_tracing(configurations: Dict[str, ConfigurationValue]):
sampler=ApplicationInsightsSampler(sampling_ratio=cast(float, sampling_ratio)),
resource=resource
)
set_tracer_provider(tracer_provider)
for span_processor in configurations[SPAN_PROCESSORS_ARG]: # type: ignore
get_tracer_provider().add_span_processor(span_processor) # type: ignore
tracer_provider.add_span_processor(span_processor) # type: ignore
if configurations.get(ENABLE_LIVE_METRICS_ARG):
qsp = _QuickpulseSpanProcessor()
tracer_provider.add_span_processor(qsp)
trace_exporter = AzureMonitorTraceExporter(**configurations)
bsp = BatchSpanProcessor(
trace_exporter,
)
get_tracer_provider().add_span_processor(bsp) # type: ignore
tracer_provider.add_span_processor(bsp)
set_tracer_provider(tracer_provider)
if _is_instrumentation_enabled(configurations, _AZURE_SDK_INSTRUMENTATION_NAME):
settings.tracing_implementation = OpenTelemetrySpan


def _setup_logging(configurations: Dict[str, ConfigurationValue]):
resource: Resource = configurations[RESOURCE_ARG] # type: ignore
logger_provider = LoggerProvider(resource=resource)
set_logger_provider(logger_provider)
if configurations.get(ENABLE_LIVE_METRICS_ARG):
qlp = _QuickpulseLogRecordProcessor()
logger_provider.add_log_record_processor(qlp)
log_exporter = AzureMonitorLogExporter(**configurations)
log_record_processor = BatchLogRecordProcessor(
log_exporter,
)
get_logger_provider().add_log_record_processor(log_record_processor) # type: ignore
handler = LoggingHandler(logger_provider=get_logger_provider())
logger_provider.add_log_record_processor(log_record_processor)
set_logger_provider(logger_provider)
handler = LoggingHandler(logger_provider=logger_provider)
logger_name: str = configurations[LOGGER_NAME_ARG] # type: ignore
getLogger(logger_name).addHandler(handler)

Expand All @@ -153,6 +172,10 @@ def _setup_metrics(configurations: Dict[str, ConfigurationValue]):
set_meter_provider(meter_provider)


def _setup_live_metrics(configurations):
enable_live_metrics(**configurations)


def _setup_instrumentations(configurations: Dict[str, ConfigurationValue]):
# use pkg_resources for now until https://github.com/open-telemetry/opentelemetry-python/pull/3168 is merged
for entry_point in iter_entry_points(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# --------------------Configuration------------------------------------------

CONNECTION_STRING_ARG = "connection_string"
ENABLE_LIVE_METRICS_ARG = "enable_live_metrics"
DISABLE_AZURE_CORE_TRACING_ARG = "disable_azure_core_tracing"
DISABLE_LOGGING_ARG = "disable_logging"
DISABLE_METRICS_ARG = "disable_metrics"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
DISABLE_METRICS_ARG,
DISABLE_TRACING_ARG,
DISTRO_VERSION_ARG,
ENABLE_LIVE_METRICS_ARG,
INSTRUMENTATION_OPTIONS_ARG,
LOGGER_NAME_ARG,
RESOURCE_ARG,
Expand Down Expand Up @@ -68,6 +69,7 @@ def _get_configurations(**kwargs) -> Dict[str, ConfigurationValue]:
_default_sampling_ratio(configurations)
_default_instrumentation_options(configurations)
_default_span_processors(configurations)
_default_enable_live_metrics(configurations)

return configurations

Expand Down Expand Up @@ -97,8 +99,7 @@ def _default_disable_tracing(configurations):


def _default_logger_name(configurations):
if LOGGER_NAME_ARG not in configurations:
configurations[LOGGER_NAME_ARG] = ""
configurations.setdefault(LOGGER_NAME_ARG, "")


def _default_resource(configurations):
Expand Down Expand Up @@ -147,8 +148,11 @@ def _default_instrumentation_options(configurations):


def _default_span_processors(configurations):
if SPAN_PROCESSORS_ARG not in configurations:
configurations[SPAN_PROCESSORS_ARG] = []
configurations.setdefault(SPAN_PROCESSORS_ARG, [])


def _default_enable_live_metrics(configurations):
configurations.setdefault(ENABLE_LIVE_METRICS_ARG, False)


def _get_otel_disabled_instrumentations():
Expand Down
2 changes: 2 additions & 0 deletions sdk/monitor/azure-monitor-opentelemetry/samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ For guidance on the samples README, visit the [sample guide](https://github.com/
|[logging/basic.py][logging_basic] | Produce logs |
|[metrics/attributes.py][attributes] | Add attributes to custom metrics counters |
|[metrics/instruments.py][instruments] | Create observable instruments |
|[metrics/live_metrics.py][live_metrics] | Live metrics feature |
|[tracing/django/sample/manage.py][django] | Instrument a django app |
|[tracing/db_psycopg2.py][db_psycopg2] | Instrument the PsycoPG2 library |
|[tracing/http_fastapi.py][http_fastapi] | Instrument a FastAPI app |
Expand Down Expand Up @@ -68,6 +69,7 @@ To learn more, see the [Azure Monitor OpenTelemetry Distro documentation][distro
[logging_basic]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/monitor/azure-monitor-opentelemetry/samples/logging/basic.py
[attributes]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/monitor/azure-monitor-opentelemetry/samples/metrics/attributes.py
[instruments]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/monitor/azure-monitor-opentelemetry/samples/metrics/instruments.py
[instruments]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/monitor/azure-monitor-opentelemetry/samples/metrics/live_metrics.py
[django]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/monitor/azure-monitor-opentelemetry/samples/tracing/django/sample/manage.py
[db_psycopg2]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/monitor/azure-monitor-opentelemetry/samples/tracing/db_psycopg2.py
[http_fastapi]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/monitor/azure-monitor-opentelemetry/samples/tracing/http_fastapi.py
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
"""
This example shows how configure live metrics to be enabled. It sets up a minimal example of sending dependency,
trace and exception telemetry to demonstrate the capabilities and collection set of live metrics.
"""
import logging
import requests
import time

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

from opentelemetry.sdk.resources import Resource

configure_azure_monitor(
resource=Resource.create({
"service.name": "live_metrics_service",
"service.instance.id": "qp_instance_id",
}),
logger_name=__name__,
enable_live_metrics=True, # Enable live metrics configuration
)

tracer = trace.get_tracer(__name__)
logger = logging.getLogger(__name__)

# Continuously send metrics
while True:
with tracer.start_as_current_span("parent"):
logger.warning("sending request")
response = requests.get("https://azure.microsoft.com/", timeout=5)
try:
val = 1 / 0
print(val)
except ZeroDivisionError:
logger.error("Error: Division by zero", stack_info=True, exc_info=True)
time.sleep(2)
Loading