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 @@ -13,6 +13,8 @@
([#23960](https://github.com/Azure/azure-sdk-for-python/pull/23960))

### Breaking Changes
- Update to OpenTelemetry api/sdk 1.12.0rc1
([#24619](https://github.com/Azure/azure-sdk-for-python/pull/24619))

### Bugs Fixed

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
import logging
from typing import Sequence, Any

from opentelemetry.sdk._metrics.export import MetricExporter, MetricExportResult
from opentelemetry.sdk._metrics.point import (
Gauge,
Histogram,
Metric,
Sum,

from typing import Optional, Any

from opentelemetry.sdk.metrics.export import (
DataPointT,
HistogramDataPoint,
MetricExporter,
MetricExportResult,
MetricsData as OTMetricsData,
NumberDataPoint,
)
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.util.instrumentation import InstrumentationScope

from azure.monitor.opentelemetry.exporter import _utils
from azure.monitor.opentelemetry.exporter._generated.models import (
Expand All @@ -32,14 +36,32 @@ class AzureMonitorMetricExporter(BaseExporter, MetricExporter):
"""Azure Monitor Metric exporter for OpenTelemetry."""

def export(
self, metrics: Sequence[Metric], **kwargs: Any # pylint: disable=unused-argument
self,
metrics_data: OTMetricsData,
timeout_millis: float = 10_000, # pylint: disable=unused-argument
**kwargs: Any, # pylint: disable=unused-argument
) -> MetricExportResult:
"""Exports a batch of metric data
:param metrics: Open Telemetry Metric(s) to export.
:type metrics: Sequence[~opentelemetry._metrics.point.Metric]
:rtype: ~opentelemetry.sdk._metrics.export.MetricExportResult
:type metrics_data: Sequence[~opentelemetry.sdk.metrics._internal.point.MetricsData]
:rtype: ~opentelemetry.sdk.metrics.export.MetricExportResult
"""
envelopes = [self._metric_to_envelope(metric) for metric in metrics]
envelopes = []
if metrics_data is None:
return MetricExportResult.SUCCESS
for resource_metric in metrics_data.resource_metrics:
for scope_metric in resource_metric.scope_metrics:
for metric in scope_metric.metrics:
for point in metric.data.data_points:
if point is not None:
envelopes.append(
self._point_to_envelope(
point,
metric.name,
resource_metric.resource,
scope_metric.scope
)
)
try:
result = self._transmit(envelopes)
if result == ExportResult.FAILED_RETRYABLE:
Expand All @@ -53,17 +75,25 @@ def export(
_logger.exception("Exception occurred while exporting the data.")
return _get_metric_export_result(ExportResult.FAILED_NOT_RETRYABLE)

def shutdown(self) -> None:
def shutdown(
self,
timeout_millis: float = 30_000, # pylint: disable=unused-argument
**kwargs: Any, # pylint: disable=unused-argument
) -> None:
"""Shuts down the exporter.

Called when the SDK is shut down.
"""
self.storage.close()

def _metric_to_envelope(self, metric: Metric) -> TelemetryItem:
if not metric:
return None
envelope = _convert_metric_to_envelope(metric)
def _point_to_envelope(
self,
point: DataPointT,
name: str,
resource: Optional[Resource] = None,
scope: Optional[InstrumentationScope] = None
) -> TelemetryItem:
envelope = _convert_point_to_envelope(point, name, resource, scope)
envelope.instrumentation_key = self._instrumentation_key
return envelope

Expand All @@ -86,33 +116,39 @@ def from_connection_string(


# pylint: disable=protected-access
def _convert_metric_to_envelope(metric: Metric) -> TelemetryItem:
point = metric.point
def _convert_point_to_envelope(
point: DataPointT,
name: str,
resource: Optional[Resource] = None,
scope: Optional[InstrumentationScope] = None # pylint: disable=unused-argument
) -> TelemetryItem:
envelope = _utils._create_telemetry_item(point.time_unix_nano)
envelope.name = "Microsoft.ApplicationInsights.Metric"
envelope.tags.update(_utils._populate_part_a_fields(metric.resource))
properties = metric.attributes
envelope.tags.update(_utils._populate_part_a_fields(resource))
value = 0
# TODO
count = 1
# min = None
# max = None
min_ = None
max_ = None
# std_dev = None

if isinstance(point, (Gauge, Sum)):
if isinstance(point, NumberDataPoint):
value = point.value
elif isinstance(point, Histogram):
value = sum(point.bucket_counts)
count = sum(point.bucket_counts)
elif isinstance(point, HistogramDataPoint):
value = point.sum
count = point.count
min_ = point.min
max_ = point.max

data_point = MetricDataPoint(
name=metric.name,
name=name,
value=value,
data_point_type="Aggregation",
count=count,
min=min_,
max=max_,
)
data = MetricsData(
properties=properties,
properties=dict(point.attributes),
metrics=[data_point],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,45 @@
AzureMonitorMetricsExporter.
"""
import os
from typing import Iterable

from opentelemetry import _metrics
from opentelemetry._metrics.measurement import Measurement
from opentelemetry.sdk._metrics import MeterProvider
from opentelemetry.sdk._metrics.export import PeriodicExportingMetricReader
from opentelemetry import metrics
from opentelemetry.metrics import CallbackOptions, Observation
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader

from azure.monitor.opentelemetry.exporter import AzureMonitorMetricExporter

exporter = AzureMonitorMetricExporter.from_connection_string(
os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)
reader = PeriodicExportingMetricReader(exporter, export_interval_millis=5000)
_metrics.set_meter_provider(MeterProvider(metric_readers=[reader]))
metrics.set_meter_provider(MeterProvider(metric_readers=[reader]))

# Create a namespaced meter
meter = _metrics.get_meter_provider().get_meter("sample")
meter = metrics.get_meter_provider().get_meter("sample")

# Callback functions for observable instruments
def observable_counter_func():
yield Measurement(1, {})
def observable_counter_func(options: CallbackOptions) -> Iterable[Observation]:
yield Observation(1, {})


def observable_up_down_counter_func():
yield Measurement(-10, {})
def observable_up_down_counter_func(
options: CallbackOptions,
) -> Iterable[Observation]:
yield Observation(-10, {})


def observable_gauge_func():
yield Measurement(9, {})
def observable_gauge_func(options: CallbackOptions) -> Iterable[Observation]:
yield Observation(9, {})

# Counter
counter = meter.create_counter("counter")
counter.add(1)

# Async Counter
observable_counter = meter.create_observable_counter(
"observable_counter", observable_counter_func
"observable_counter", [observable_counter_func]
)

# UpDownCounter
Expand All @@ -51,14 +54,12 @@ def observable_gauge_func():

# Async UpDownCounter
observable_updown_counter = meter.create_observable_up_down_counter(
"observable_updown_counter", observable_up_down_counter_func
"observable_updown_counter", [observable_up_down_counter_func]
)

# Histogram
histogram = meter.create_histogram("histogram")
histogram.record(99.9)

# Async Gauge
gauge = meter.create_observable_gauge("gauge", observable_gauge_func)

input(...)
gauge = meter.create_observable_gauge("gauge", [observable_gauge_func])
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@
"""
import os

from opentelemetry import _metrics
from opentelemetry.sdk._metrics import MeterProvider
from opentelemetry.sdk._metrics.export import PeriodicExportingMetricReader
from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader

from azure.monitor.opentelemetry.exporter import AzureMonitorMetricExporter

exporter = AzureMonitorMetricExporter.from_connection_string(
os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)
reader = PeriodicExportingMetricReader(exporter, export_interval_millis=5000)
_metrics.set_meter_provider(MeterProvider(metric_readers=[reader]))
metrics.set_meter_provider(MeterProvider(metric_readers=[reader]))

# Create a namespaced meter
meter = _metrics.get_meter_provider().get_meter("sample")
meter = metrics.get_meter_provider().get_meter("sample")

# Create Counter instrument with the meter
counter = meter.create_counter("counter")
Expand Down
4 changes: 2 additions & 2 deletions sdk/monitor/azure-monitor-opentelemetry-exporter/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@
install_requires=[
"azure-core<2.0.0,>=1.23.0",
"msrest>=0.6.10",
"opentelemetry-api<2.0.0,>=1.11.1,!=1.10a0",
"opentelemetry-sdk<2.0.0,>=1.11.1,!=1.10a0",
"opentelemetry-api<2.0.0,>=1.12.0rc1,!=1.10a0",
"opentelemetry-sdk<2.0.0,>=1.12.0rc1,!=1.10a0",
],
)

Loading