Skip to content
This repository was archived by the owner on Nov 16, 2023. It is now read-only.

Commit 7a8ca6d

Browse files
committed
2 parents a66b8d9 + 6af33e9 commit 7a8ca6d

File tree

19 files changed

+300
-97
lines changed

19 files changed

+300
-97
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
> **This repository has been moved to the [Azure SDK for Python](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/monitor/azure-opentelemetry-exporter-azuremonitor) repository.** In order to improve discoverability and share common dependencies/tests, the OpenTelemetry Azure Monitor exporters for Python has moved to a common location containing all Azure SDKs. Please submit all issues and inquiries in that repository.
2+
13
# OpenTelemetry Azure Monitor
24

35
[![Gitter chat](https://img.shields.io/gitter/room/Microsoft/azure-monitor-python)](https://gitter.im/Microsoft/azure-monitor-python)
@@ -47,11 +49,11 @@ with tracer.start_as_current_span('hello'):
4749
print('Hello World!')
4850
```
4951

50-
#### Integrations
52+
#### Instrumentations
5153

52-
OpenTelemetry also supports several [integrations](https://github.com/open-telemetry/opentelemetry-python/tree/master/ext) which allows to integrate with third party libraries.
54+
OpenTelemetry also supports several [instrumentations](https://github.com/open-telemetry/opentelemetry-python/tree/master/instrumentation) which allows to instrument with third party libraries.
5355

54-
This example shows how to integrate with the [requests](https://2.python-requests.org/en/master/)_ library.
56+
This example shows how to instrument with the [requests](https://2.python-requests.org/en/master/)_ library.
5557

5658
* Create an Azure Monitor resource and get the instrumentation key, more information can be found [here](https://docs.microsoft.com/azure/azure-monitor/app/create-new-resource).
5759
* Install the `requests` integration package using ``pip install opentelemetry-ext-http-requests``.

azure_monitor/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
## Unreleased
44

5+
## 0.6b.0
6+
Released 2021-01-28
7+
8+
- Remove request metrics from auto-collection
9+
([#124](https://github.com/microsoft/opentelemetry-azure-monitor-python/pull/124))
10+
- Implement standard metrics for http dependency telemetry
11+
([#125](https://github.com/microsoft/opentelemetry-azure-monitor-python/pull/125))
12+
513
## 0.5b.0
614
Released 2020-09-24
715

azure_monitor/README.md

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1 @@
1-
# OpenTelemetry Azure Monitor SDKs and Exporters (Private preview)
2-
3-
[![PyPI version](https://badge.fury.io/py/opentelemetry-azure-monitor.svg)](https://badge.fury.io/py/opentelemetry-azure-monitor)
4-
5-
The OpenTelemetry Azure Monitor SDK and exporter are in private preview. They are not recommended for a production environment.
6-
7-
## Installation
8-
9-
```sh
10-
pip install opentelemetry-azure-monitor
11-
```
12-
13-
# References
14-
15-
[Azure Monitor](https://docs.microsoft.com/azure/azure-monitor/)
16-
17-
[OpenTelemetry Project](https://opentelemetry.io/)
18-
19-
[OpenTelemetry Python Client](https://github.com/open-telemetry/opentelemetry-python)
20-
21-
[Azure Monitor Python Gitter](https://gitter.im/Microsoft/azure-monitor-python)
1+
Deprecated, go for official version https://pypi.org/project/azure-opentelemetry-exporter-azuremonitor/.

azure_monitor/examples/metrics/auto_collector.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
testing_label_set = {"environment": "testing"}
2121

22-
# Automatically collect standard metrics
22+
# Automatically collect performance counters
2323
auto_collection = AutoCollection(meter=meter, labels=testing_label_set)
2424

2525
metrics.get_meter_provider().start_pipeline(meter, exporter, 2)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
# pylint: disable=import-error
4+
# pylint: disable=no-member
5+
# pylint: disable=no-name-in-module
6+
import time
7+
8+
import requests
9+
from opentelemetry import metrics
10+
from opentelemetry.instrumentation.requests import RequestsInstrumentor
11+
from opentelemetry.sdk.metrics import MeterProvider
12+
13+
from azure_monitor import AzureMonitorMetricsExporter
14+
15+
# Use the default sdk implementation
16+
metrics.set_meter_provider(MeterProvider(stateful=False))
17+
18+
# Track telemetry from the requests library
19+
RequestsInstrumentor().instrument()
20+
meter = RequestsInstrumentor().meter
21+
exporter = AzureMonitorMetricsExporter(
22+
connection_string="InstrumentationKey=<INSTRUMENTATION KEY HERE>"
23+
)
24+
# Export standard metrics from requests library to Azure Monitor
25+
metrics.get_meter_provider().start_pipeline(meter, exporter, 5)
26+
27+
for x in range(10):
28+
for y in range(10):
29+
requests.get("http://example.com")
30+
time.sleep(2)
31+
time.sleep(5)
32+
33+
input("Press any key to exit...")

azure_monitor/src/azure_monitor/export/metrics/__init__.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ class AzureMonitorMetricsExporter(BaseExporter, MetricsExporter):
3838
options: :doc:`export.options` to allow configuration for the exporter
3939
"""
4040

41+
def __init__(self, **options):
42+
super().__init__(**options)
43+
self.add_telemetry_processor(standard_metrics_processor)
44+
4145
def export(
4246
self, metric_records: Sequence[MetricRecord]
4347
) -> MetricsExportResult:
@@ -73,13 +77,19 @@ def _metric_to_envelope(
7377
)
7478
envelope.name = "Microsoft.ApplicationInsights.Metric"
7579
value = 0
80+
_min = None
81+
_max = None
82+
count = None
7683
metric = metric_record.instrument
7784
if isinstance(metric, ValueObserver):
7885
# mmscl
7986
value = metric_record.aggregator.checkpoint.last
8087
elif isinstance(metric, ValueRecorder):
8188
# mmsc
82-
value = metric_record.aggregator.checkpoint.count
89+
value = metric_record.aggregator.checkpoint.sum
90+
_min = metric_record.aggregator.checkpoint.min
91+
_max = metric_record.aggregator.checkpoint.max
92+
count = metric_record.aggregator.checkpoint.count
8393
else:
8494
# sum or lv
8595
value = metric_record.aggregator.checkpoint
@@ -90,6 +100,9 @@ def _metric_to_envelope(
90100
ns=metric.description,
91101
name=metric.name,
92102
value=value,
103+
min=_min,
104+
max=_max,
105+
count=count,
93106
kind=protocol.DataPointType.MEASUREMENT.value,
94107
)
95108

@@ -99,3 +112,43 @@ def _metric_to_envelope(
99112
data = protocol.MetricData(metrics=[data_point], properties=properties)
100113
envelope.data = protocol.Data(base_data=data, base_type="MetricData")
101114
return envelope
115+
116+
117+
def standard_metrics_processor(envelope):
118+
data = envelope.data.base_data
119+
if data.metrics:
120+
properties = {}
121+
point = data.metrics[0]
122+
if point.name == "http.client.duration":
123+
point.name = "Dependency duration"
124+
point.kind = protocol.DataPointType.AGGREGATION.value
125+
properties["_MS.MetricId"] = "dependencies/duration"
126+
properties["_MS.IsAutocollected"] = "True"
127+
properties["cloud/roleInstance"] = utils.azure_monitor_context.get(
128+
"ai.cloud.roleInstance"
129+
)
130+
properties["cloud/roleName"] = utils.azure_monitor_context.get(
131+
"ai.cloud.role"
132+
)
133+
properties["Dependency.Success"] = "False"
134+
if data.properties.get("http.status_code"):
135+
try:
136+
code = int(data.properties.get("http.status_code"))
137+
if 200 <= code < 400:
138+
properties["Dependency.Success"] = "True"
139+
except ValueError:
140+
pass
141+
# TODO: Check other properties if url doesn't exist
142+
properties["dependency/target"] = data.properties.get("http.url")
143+
properties["Dependency.Type"] = "HTTP"
144+
properties["dependency/resultCode"] = data.properties.get(
145+
"http.status_code"
146+
)
147+
# Won't need this once Azure Monitor supports histograms
148+
# We can't actually get the individual buckets because the bucket
149+
# collection must happen on the SDK side
150+
properties["dependency/performanceBucket"] = ""
151+
# TODO: OT does not have this in semantic conventions for trace
152+
properties["operation/synthetic"] = ""
153+
# TODO: Add other std. metrics as implemented
154+
data.properties = properties

azure_monitor/src/azure_monitor/export/trace/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ class AzureMonitorSpanExporter(BaseExporter, SpanExporter):
2727
options: :doc:`export.options` to allow configuration for the exporter
2828
"""
2929

30+
def __init__(self, **options):
31+
super().__init__(**options)
32+
self.add_telemetry_processor(indicate_processed_by_metric_extractors)
33+
3034
def export(self, spans: Sequence[Span]) -> SpanExportResult:
3135
envelopes = list(map(self._span_to_envelope, spans))
3236
envelopes = list(
@@ -122,6 +126,7 @@ def convert_span_to_envelope(span: Span) -> protocol.Envelope:
122126
"component" in span.attributes
123127
and span.attributes["component"] == "http"
124128
):
129+
# TODO: check other component types (e.g. db)
125130
data.type = "HTTP"
126131
if "http.url" in span.attributes:
127132
url = span.attributes["http.url"]
@@ -157,3 +162,12 @@ def convert_span_to_envelope(span: Span) -> protocol.Envelope:
157162
data.properties["_MS.links"] = json.dumps(links)
158163
# TODO: tracestate, tags
159164
return envelope
165+
166+
167+
def indicate_processed_by_metric_extractors(envelope):
168+
name = "Requests"
169+
if envelope.data.base_type == "RemoteDependencyData":
170+
name = "Dependencies"
171+
envelope.data.base_data.properties["_MS.ProcessedByMetricExtractors"] = (
172+
"(Name:'" + name + "',Ver:'1.1')"
173+
)

azure_monitor/src/azure_monitor/sdk/auto_collection/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@
2424

2525

2626
class AutoCollection:
27-
"""Starts auto collection of standard metrics, including performance,
28-
dependency and request metrics.
27+
"""Starts auto collection of performance counters
2928
3029
Args:
3130
meter: OpenTelemetry Meter
@@ -35,4 +34,3 @@ class AutoCollection:
3534
def __init__(self, meter: Meter, labels: Dict[str, str]):
3635
col_type = AutoCollectionType.PERF_COUNTER
3736
self._performance_metrics = PerformanceMetrics(meter, labels, col_type)
38-
self._request_metrics = RequestMetrics(meter, labels, col_type)

azure_monitor/src/azure_monitor/sdk/auto_collection/dependency_metrics.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def __init__(self, meter: Meter, labels: Dict[str, str]):
9191
)
9292

9393
def _track_dependency_rate(self, observer: Observer) -> None:
94-
""" Track Dependency rate
94+
"""Track Dependency rate
9595
9696
Calculated by obtaining the number of outgoing requests made
9797
using the requests library within an elapsed time and dividing
@@ -121,7 +121,7 @@ def _track_dependency_rate(self, observer: Observer) -> None:
121121
observer.observe(last_result, self._labels)
122122

123123
def _track_dependency_duration(self, observer: Observer) -> None:
124-
""" Track Dependency average duration
124+
"""Track Dependency average duration
125125
126126
Calculated by getting the time it takes to make an outgoing request
127127
and dividing over the amount of outgoing requests over an elapsed time.
@@ -149,7 +149,7 @@ def _track_dependency_duration(self, observer: Observer) -> None:
149149
observer.observe(last_average_duration, self._labels)
150150

151151
def _track_failure_rate(self, observer: Observer) -> None:
152-
""" Track Failed Dependency rate
152+
"""Track Failed Dependency rate
153153
154154
Calculated by obtaining the number of failed outgoing requests made
155155
using the requests library within an elapsed time and dividing

azure_monitor/src/azure_monitor/sdk/auto_collection/live_metrics/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def __init__(
4242
col_type = AutoCollectionType.LIVE_METRICS
4343
self._performance_metrics = PerformanceMetrics(meter, labels, col_type)
4444
self._dependency_metrics = DependencyMetrics(meter, labels)
45-
self._request_metrics = RequestMetrics(meter, labels, col_type)
45+
self._request_metrics = RequestMetrics(meter, labels)
4646
self._manager = LiveMetricsManager(
4747
meter, instrumentation_key, span_processor
4848
)

0 commit comments

Comments
 (0)