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

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

Fix breaking changes from OT release 0.7b.0 #86

Merged
merged 7 commits into from
May 18, 2020
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
6 changes: 3 additions & 3 deletions azure_monitor/examples/traces/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
# pylint: disable=no-name-in-module
import requests
from opentelemetry import trace
from opentelemetry.ext import http_requests
from opentelemetry.ext.requests import RequestsInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor

from azure_monitor import AzureMonitorSpanExporter

trace.set_tracer_provider(TracerProvider())
tracer = trace.get_tracer(__name__)
http_requests.enable(trace.get_tracer_provider())
RequestsInstrumentor().instrument()
span_processor = BatchExportSpanProcessor(
AzureMonitorSpanExporter(
# connection_string="InstrumentationKey=<INSTRUMENTATION KEY HERE>"
connection_string="InstrumentationKey=<INSTRUMENTATION KEY HERE>"
)
)
trace.get_tracer_provider().add_span_processor(span_processor)
Expand Down
4 changes: 2 additions & 2 deletions azure_monitor/examples/traces/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
# pylint: disable=no-name-in-module
import requests
from opentelemetry import trace
from opentelemetry.ext import http_requests
from opentelemetry.ext.requests import RequestsInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor

from azure_monitor import AzureMonitorSpanExporter

trace.set_tracer_provider(TracerProvider())

http_requests.enable(trace.get_tracer_provider())
RequestsInstrumentor().instrument()
span_processor = SimpleExportSpanProcessor(
AzureMonitorSpanExporter(
connection_string="InstrumentationKey=<INSTRUMENTATION KEY HERE>"
Expand Down
12 changes: 8 additions & 4 deletions azure_monitor/examples/traces/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
# pylint: disable=no-name-in-module
import requests
from opentelemetry import trace
from opentelemetry.ext import http_requests
from opentelemetry.ext.wsgi import OpenTelemetryMiddleware
from opentelemetry.ext.flask import FlaskInstrumentor
from opentelemetry.ext.requests import RequestsInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor

Expand All @@ -29,9 +29,13 @@
# Integrations are the glue that binds the OpenTelemetry API and the
# frameworks and libraries that are used together, automatically creating
# Spans and propagating context as appropriate.
http_requests.enable(trace.get_tracer_provider())

# Enable instrumentation in the requests library.
RequestsInstrumentor().instrument()

app = flask.Flask(__name__)
app.wsgi_app = OpenTelemetryMiddleware(app.wsgi_app)
# Enable instrumentation in the flask library.
FlaskInstrumentor().instrument_app(app)


@app.route("/")
Expand Down
4 changes: 2 additions & 2 deletions azure_monitor/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ package_dir=
=src
packages=find_namespace:
install_requires =
opentelemetry-api ~= 0.6b0
opentelemetry-sdk ~= 0.6b0
opentelemetry-api ~= 0.7b1
opentelemetry-sdk ~= 0.7b1
psutil >= 5.6.3
requests ~= 2.0

Expand Down
18 changes: 10 additions & 8 deletions azure_monitor/src/azure_monitor/export/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,18 +187,20 @@ def _transmit(self, envelopes: typing.List[Envelope]) -> ExportResult:
def get_trace_export_result(result: ExportResult) -> SpanExportResult:
if result == ExportResult.SUCCESS:
return SpanExportResult.SUCCESS
if result == ExportResult.FAILED_RETRYABLE:
return SpanExportResult.FAILED_RETRYABLE
if result == ExportResult.FAILED_NOT_RETRYABLE:
return SpanExportResult.FAILED_NOT_RETRYABLE
if result in (
ExportResult.FAILED_RETRYABLE,
ExportResult.FAILED_NOT_RETRYABLE,
):
return SpanExportResult.FAILURE
return None


def get_metrics_export_result(result: ExportResult) -> MetricsExportResult:
if result == ExportResult.SUCCESS:
return MetricsExportResult.SUCCESS
if result == ExportResult.FAILED_RETRYABLE:
return MetricsExportResult.FAILED_RETRYABLE
if result == ExportResult.FAILED_NOT_RETRYABLE:
return MetricsExportResult.FAILED_NOT_RETRYABLE
if result in (
ExportResult.FAILED_RETRYABLE,
ExportResult.FAILED_NOT_RETRYABLE,
):
return MetricsExportResult.FAILURE
return None
19 changes: 3 additions & 16 deletions azure_monitor/src/azure_monitor/export/metrics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
from typing import Sequence
from urllib.parse import urlparse

from opentelemetry.metrics import Metric
from opentelemetry.sdk.metrics import Counter, Observer
from opentelemetry.sdk.metrics import Counter, Metric, Observer
from opentelemetry.sdk.metrics.export import (
MetricRecord,
MetricsExporter,
Expand Down Expand Up @@ -36,12 +35,7 @@ def export(
self, metric_records: Sequence[MetricRecord]
) -> MetricsExportResult:
envelopes = list(map(self._metric_to_envelope, metric_records))
envelopes = list(
map(
lambda x: x.to_dict(),
self._apply_telemetry_processors(envelopes),
)
)
envelopes = self._apply_telemetry_processors(envelopes)
try:
result = self._transmit(envelopes)
if result == ExportResult.FAILED_RETRYABLE:
Expand All @@ -60,17 +54,10 @@ def _metric_to_envelope(

if not metric_record:
return None
# TODO: Opentelemetry has timestamp for Observer, awaiting release
# TODO: Timestamp info is also moved into aggregators
_time = time_ns()
if isinstance(metric_record.metric, Metric):
_time = metric_record.metric.bind(
dict(metric_record.labels)
).last_update_timestamp
envelope = protocol.Envelope(
ikey=self.options.instrumentation_key,
tags=dict(utils.azure_monitor_context),
time=ns_to_iso_str(_time),
time=ns_to_iso_str(metric_record.aggregator.last_update_timestamp),
)
envelope.name = "Microsoft.ApplicationInsights.Metric"
value = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def export(
except Exception: # pylint: disable=broad-except
logger.exception("Exception occurred while exporting the data.")

return MetricsExportResult.FAILED_NOT_RETRYABLE
return MetricsExportResult.FAILURE

def _metric_to_live_metrics_envelope(
self, metric_records: typing.Sequence[MetricRecord]
Expand Down
8 changes: 7 additions & 1 deletion azure_monitor/src/azure_monitor/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@
import threading
import time

from opentelemetry.sdk.version import __version__ as opentelemetry_version
# from opentelemetry.sdk.version import __version__ as opentelemetry_version
import pkg_resources

from azure_monitor.version import __version__ as ext_version

# Workaround for missing version file
Copy link
Member

Choose a reason for hiding this comment

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

Is this a temporary workaround?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I believe someone is trying to make the push in OT to remove version.py from the packages. If this happens, we will use this workaround, but if not, we will wait until the version.py file is put back in the release and use that instead.

opentelemetry_version = pkg_resources.get_distribution(
"opentelemetry-sdk"
).version

azure_monitor_context = {
"ai.cloud.role": os.path.basename(sys.argv[0]) or "Python Application",
"ai.cloud.roleInstance": platform.node(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def test_export_failed(self):
response.status_code = 400
request.return_value = response
result = exporter.export([record])
self.assertEqual(result, MetricsExportResult.FAILED_NOT_RETRYABLE)
self.assertEqual(result, MetricsExportResult.FAILURE)

def test_export_exception(self):
record = MetricRecord(
Expand All @@ -99,4 +99,4 @@ def test_export_exception(self):
throw(Exception),
):
result = exporter.export([record])
self.assertEqual(result, MetricsExportResult.FAILED_NOT_RETRYABLE)
self.assertEqual(result, MetricsExportResult.FAILURE)
96 changes: 45 additions & 51 deletions azure_monitor/tests/metrics/test_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,46 +96,58 @@ def test_constructor(self):
"4321abcd-5678-4efa-8abc-1234567890ab",
)

def test_export(self,):
@mock.patch(
"azure_monitor.export.metrics.AzureMonitorMetricsExporter._transmit"
)
@mock.patch(
"azure_monitor.export.metrics.AzureMonitorMetricsExporter._metric_to_envelope"
)
def test_export(self, mte, transmit):
record = MetricRecord(
CounterAggregator(), self._test_labels, self._test_metric
)
exporter = self._exporter
with mock.patch(
"azure_monitor.export.metrics.AzureMonitorMetricsExporter._transmit"
) as transmit: # noqa: E501
transmit.return_value = ExportResult.SUCCESS
result = exporter.export([record])
self.assertEqual(result, MetricsExportResult.SUCCESS)
mte.return_value = []
transmit.return_value = ExportResult.SUCCESS
result = exporter.export([record])
self.assertEqual(result, MetricsExportResult.SUCCESS)

def test_export_failed_retryable(self):
@mock.patch(
"azure_monitor.export.metrics.AzureMonitorMetricsExporter._transmit"
)
@mock.patch(
"azure_monitor.export.metrics.AzureMonitorMetricsExporter._metric_to_envelope"
)
def test_export_failed_retryable(self, mte, transmit):
record = MetricRecord(
CounterAggregator(), self._test_labels, self._test_metric
)
exporter = self._exporter
with mock.patch(
"azure_monitor.export.metrics.AzureMonitorMetricsExporter._transmit"
) as transmit: # noqa: E501
transmit.return_value = ExportResult.FAILED_RETRYABLE
storage_mock = mock.Mock()
exporter.storage.put = storage_mock
result = exporter.export([record])
self.assertEqual(result, MetricsExportResult.FAILED_RETRYABLE)
self.assertEqual(storage_mock.call_count, 1)
transmit.return_value = ExportResult.FAILED_RETRYABLE
mte.return_value = []
storage_mock = mock.Mock()
exporter.storage.put = storage_mock
result = exporter.export([record])
self.assertEqual(result, MetricsExportResult.FAILURE)
self.assertEqual(storage_mock.call_count, 1)

@mock.patch("azure_monitor.export.metrics.logger")
def test_export_exception(self, logger_mock):
@mock.patch(
"azure_monitor.export.metrics.AzureMonitorMetricsExporter._transmit"
)
@mock.patch(
"azure_monitor.export.metrics.AzureMonitorMetricsExporter._metric_to_envelope"
)
def test_export_exception(self, mte, transmit, logger_mock):
record = MetricRecord(
CounterAggregator(), self._test_labels, self._test_metric
)
exporter = self._exporter
with mock.patch(
"azure_monitor.export.metrics.AzureMonitorMetricsExporter._transmit",
throw(Exception),
): # noqa: E501
result = exporter.export([record])
self.assertEqual(result, MetricsExportResult.FAILED_NOT_RETRYABLE)
self.assertEqual(logger_mock.exception.called, True)
mte.return_value = []
transmit.side_effect = throw(Exception)
result = exporter.export([record])
self.assertEqual(result, MetricsExportResult.FAILURE)
self.assertEqual(logger_mock.exception.called, True)

def test_metric_to_envelope_none(self):
exporter = self._exporter
Expand All @@ -152,10 +164,7 @@ def test_metric_to_envelope(self):
self.assertEqual(envelope.ver, 1)
self.assertEqual(envelope.name, "Microsoft.ApplicationInsights.Metric")
self.assertEqual(
envelope.time,
ns_to_iso_str(
record.metric.bind(dict(record.labels)).last_update_timestamp
),
envelope.time, ns_to_iso_str(aggregator.last_update_timestamp)
)
self.assertEqual(envelope.sample_rate, None)
self.assertEqual(envelope.seq, None)
Expand Down Expand Up @@ -192,15 +201,9 @@ def test_observer_to_envelope(self):
self.assertIsInstance(envelope, Envelope)
self.assertEqual(envelope.ver, 1)
self.assertEqual(envelope.name, "Microsoft.ApplicationInsights.Metric")
# TODO: implement last updated timestamp for observer
# self.assertEqual(
# envelope.time,
# ns_to_iso_str(
# record.metric.bind(
# record.label_set
# ).last_update_timestamp
# ),
# )
self.assertEqual(
envelope.time, ns_to_iso_str(aggregator.last_update_timestamp)
)
self.assertEqual(envelope.sample_rate, None)
self.assertEqual(envelope.seq, None)
self.assertEqual(envelope.ikey, "1234abcd-5678-4efa-8abc-1234567890ab")
Expand Down Expand Up @@ -235,15 +238,9 @@ def test_observer_to_envelope_value_none(self):
self.assertIsInstance(envelope, Envelope)
self.assertEqual(envelope.ver, 1)
self.assertEqual(envelope.name, "Microsoft.ApplicationInsights.Metric")
# TODO: implement last updated timestamp for observer
# self.assertEqual(
# envelope.time,
# ns_to_iso_str(
# record.metric.bind(
# record.label_set
# ).last_update_timestamp
# ),
# )
self.assertEqual(
envelope.time, ns_to_iso_str(aggregator.last_update_timestamp)
)
self.assertEqual(envelope.sample_rate, None)
self.assertEqual(envelope.seq, None)
self.assertEqual(envelope.ikey, "1234abcd-5678-4efa-8abc-1234567890ab")
Expand Down Expand Up @@ -283,10 +280,7 @@ def test_measure_to_envelope(self, logger_mock):
self.assertEqual(envelope.ver, 1)
self.assertEqual(envelope.name, "Microsoft.ApplicationInsights.Metric")
self.assertEqual(
envelope.time,
ns_to_iso_str(
record.metric.bind(dict(record.labels)).last_update_timestamp
),
envelope.time, ns_to_iso_str(aggregator.last_update_timestamp)
)
self.assertEqual(envelope.sample_rate, None)
self.assertEqual(envelope.seq, None)
Expand Down
8 changes: 4 additions & 4 deletions azure_monitor/tests/test_base_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,11 +354,11 @@ def test_get_trace_export_result(self):
)
self.assertEqual(
get_trace_export_result(ExportResult.FAILED_NOT_RETRYABLE),
SpanExportResult.FAILED_NOT_RETRYABLE,
SpanExportResult.FAILURE,
)
self.assertEqual(
get_trace_export_result(ExportResult.FAILED_RETRYABLE),
SpanExportResult.FAILED_RETRYABLE,
SpanExportResult.FAILURE,
)
self.assertEqual(get_trace_export_result(None), None)

Expand All @@ -369,11 +369,11 @@ def test_get_metrics_export_result(self):
)
self.assertEqual(
get_metrics_export_result(ExportResult.FAILED_NOT_RETRYABLE),
MetricsExportResult.FAILED_NOT_RETRYABLE,
MetricsExportResult.FAILURE,
)
self.assertEqual(
get_metrics_export_result(ExportResult.FAILED_RETRYABLE),
MetricsExportResult.FAILED_RETRYABLE,
MetricsExportResult.FAILURE,
)
self.assertEqual(get_metrics_export_result(None), None)

Expand Down
4 changes: 2 additions & 2 deletions azure_monitor/tests/trace/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def test_export_exception(self, logger_mock):
throw(Exception),
): # noqa: E501
result = exporter.export([test_span])
self.assertEqual(result, SpanExportResult.FAILED_NOT_RETRYABLE)
self.assertEqual(result, SpanExportResult.FAILURE)
self.assertEqual(logger_mock.exception.called, True)

def test_export_not_retryable(self):
Expand All @@ -162,7 +162,7 @@ def test_export_not_retryable(self):
) as transmit: # noqa: E501
transmit.return_value = ExportResult.FAILED_NOT_RETRYABLE
result = exporter.export([test_span])
self.assertEqual(result, SpanExportResult.FAILED_NOT_RETRYABLE)
self.assertEqual(result, SpanExportResult.FAILURE)

def test_span_to_envelope_none(self):
exporter = self._exporter
Expand Down