-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Implement quickpulse exporting functionality #34141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
943756c
ping
lzchen 0842b4a
qp
lzchen d8af4b2
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-python …
lzchen cfdeab7
spelling
lzchen 358d8ae
lint
lzchen 18f5caa
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-python …
lzchen 2ddb0f2
comments
lzchen 1ec3a54
rename
lzchen 6607f23
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-python …
lzchen 750e63d
tests
lzchen 16d9c28
ping
lzchen 8ff4b0d
tests
lzchen 4d6ee0b
Update CHANGELOG.md
lzchen 5c31282
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-python …
lzchen 92758ce
tests
lzchen 8a79419
Update CHANGELOG.md
lzchen 90024df
Update CHANGELOG.md
lzchen 18d9026
Update test_exporter.py
lzchen 31b658c
minversion
lzchen 356351b
tests
lzchen 0fd195e
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-python …
lzchen 187e87e
tests
lzchen dd30368
tests
lzchen 376679f
test
lzchen 25ab5bf
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-python …
lzchen dc66875
tests
lzchen 5a965ce
remove
lzchen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
tests
- Loading branch information
commit 750e63d42ec9491cce2b76d05bd6fbaa3e6037ed
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
sdk/monitor/azure-monitor-opentelemetry-exporter/tests/quickpulse/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. | ||
176 changes: 176 additions & 0 deletions
176
sdk/monitor/azure-monitor-opentelemetry-exporter/tests/quickpulse/test_exporter.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,176 @@ | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. | ||
|
|
||
| import unittest | ||
| from unittest import mock | ||
|
|
||
| from opentelemetry.sdk.metrics.export import ( | ||
| AggregationTemporality, | ||
| Histogram, | ||
| MetricExporter, | ||
| Metric, | ||
| MetricExportResult, | ||
| MetricsData as OTMetricsData, | ||
| MetricReader, | ||
| NumberDataPoint, | ||
| ResourceMetrics, | ||
| ScopeMetrics, | ||
| Sum, | ||
| ) | ||
| from opentelemetry.sdk.util.instrumentation import InstrumentationScope | ||
| from opentelemetry.sdk.resources import Resource, ResourceAttributes | ||
| from azure.monitor.opentelemetry.exporter._quickpulse._generated._client import QuickpulseClient | ||
| from azure.monitor.opentelemetry.exporter._quickpulse._generated.models import MonitoringDataPoint | ||
| from azure.monitor.opentelemetry.exporter._quickpulse._exporter import ( | ||
| _metric_to_quick_pulse_data_points, | ||
| _QuickpulseExporter, | ||
| _QuickpulseMetricReader, | ||
| _Response, | ||
| ) | ||
|
|
||
|
|
||
| def throw(exc_type, *args, **kwargs): | ||
| def func(*_args, **_kwargs): | ||
| raise exc_type(*args, **kwargs) | ||
|
|
||
| return func | ||
|
|
||
|
|
||
| class TestQuickpulseExporter(unittest.TestCase): | ||
| @classmethod | ||
| def setUpClass(cls): | ||
| cls._resource = Resource.create( | ||
| { | ||
| ResourceAttributes.SERVICE_INSTANCE_ID: "test_instance", | ||
| ResourceAttributes.SERVICE_NAME: "test_service", | ||
| } | ||
| ) | ||
| cls._metrics_data = OTMetricsData( | ||
| resource_metrics=ResourceMetrics( | ||
| resource=cls._resource, | ||
| scope_metrics=ScopeMetrics( | ||
| scope=InstrumentationScope("test_scope"), | ||
| metrics=[ | ||
| Metric( | ||
| name="azureMonitor.memoryCommittedBytes", | ||
| description="test_desc", | ||
| unit="test_unit", | ||
| data=Sum( | ||
| data_points=[ | ||
| NumberDataPoint( | ||
| attributes={}, | ||
| start_time_unix_nano=0, | ||
| time_unix_nano=0, | ||
| value=5, | ||
| ) | ||
| ], | ||
| aggregation_temporality=AggregationTemporality.DELTA, | ||
| is_monotonic=True, | ||
| ) | ||
| ) | ||
| ], | ||
| schema_url="test_url", | ||
| ), | ||
| schema_url="test_url", | ||
| ) | ||
| ) | ||
| cls._data_point = MonitoringDataPoint( | ||
| version="test_version", | ||
| invariant_version=1, | ||
| instance="test_instance", | ||
| role_name="test_role_name", | ||
| machine_name="test_machine_name", | ||
| stream_id="test_stream_id", | ||
| ) | ||
| cls._exporter = _QuickpulseExporter( | ||
| "InstrumentationKey=4321abcd-5678-4efa-8abc-1234567890ac;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/" | ||
| ) | ||
|
|
||
| # @mock.patch("azure.monitor.opentelemetry.exporter._quickpulse._generated._client.QuickpulseClient.__new__") | ||
| # def test_init(self, client_mock): | ||
| # client_inst_mock = mock.Mock() | ||
| # client_mock.return_value = client_inst_mock | ||
| # exporter = _QuickpulseExporter( | ||
| # connection_string="InstrumentationKey=4321abcd-5678-4efa-8abc-1234567890ab;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/" | ||
| # ) | ||
|
|
||
| # self.assertEqual(exporter._live_endpoint, "https://eastus.livediagnostics.monitor.azure.com/") | ||
| # self.assertEqual(exporter._instrumentation_key, "4321abcd-5678-4efa-8abc-1234567890ab") | ||
| # self.assertEqual(exporter._client, client_inst_mock) | ||
| # client_mock.assert_called_with( | ||
| # QuickpulseClient, | ||
| # host="https://eastus.livediagnostics.monitor.azure.com/" | ||
| # ) | ||
|
|
||
|
|
||
| # def test_export_missing_data_point(self): | ||
| # result = self._exporter.export(OTMetricsData(resource_metrics=[])) | ||
| # self.assertEqual(result, MetricExportResult.FAILURE) | ||
|
|
||
|
|
||
| @mock.patch("azure.monitor.opentelemetry.exporter._quickpulse._generated._client.QuickpulseClient.post") | ||
| @mock.patch("azure.monitor.opentelemetry.exporter._quickpulse._exporter._metric_to_quick_pulse_data_points") | ||
| def test_export_subscribed_false(self, convert_mock, post_mock): | ||
| post_response = _Response( | ||
| mock.Mock(), | ||
| None, | ||
| { | ||
| "x-ms-qps-subscribed": "false", | ||
| } | ||
| ) | ||
| convert_mock.return_value = [self._data_point] | ||
| post_mock.return_value = post_response | ||
| result = self._exporter.export( | ||
| self._metrics_data, | ||
| base_monitoring_data_point=self._data_point | ||
| ) | ||
| self.assertEqual(result, MetricExportResult.FAILURE) | ||
|
|
||
|
|
||
| @mock.patch("azure.monitor.opentelemetry.exporter._quickpulse._generated._client.QuickpulseClient.post") | ||
| @mock.patch("azure.monitor.opentelemetry.exporter._quickpulse._exporter._metric_to_quick_pulse_data_points") | ||
| def test_export_subscribed_none(self, convert_mock, post_mock): | ||
| post_response = None | ||
| convert_mock.return_value = [self._data_point] | ||
| post_mock.return_value = post_response | ||
| result = self._exporter.export( | ||
| self._metrics_data, | ||
| base_monitoring_data_point=self._data_point | ||
| ) | ||
| self.assertEqual(result, MetricExportResult.FAILURE) | ||
|
|
||
| # @mock.patch("azure.monitor.opentelemetry.exporter._quickpulse._exporter._metric_to_quick_pulse_data_points") | ||
| # def test_export_exception(self, convert_mock): | ||
| # post_response = _Response( | ||
| # mock.Mock(), | ||
| # None, | ||
| # {}, | ||
| # ) | ||
| # convert_mock.return_value = [self._data_point] | ||
| # with mock.patch( | ||
| # "azure.monitor.opentelemetry.exporter._quickpulse._generated._client.QuickpulseClient.post", | ||
| # throw(Exception), | ||
| # ): # noqa: E501 | ||
| # result = self._exporter.export( | ||
| # self._metrics_data, | ||
| # base_monitoring_data_point=self._data_point | ||
| # ) | ||
| # self.assertEqual(result, MetricExportResult.FAILURE) | ||
|
|
||
| @mock.patch("azure.monitor.opentelemetry.exporter._quickpulse._generated._client.QuickpulseClient.post") | ||
| @mock.patch("azure.monitor.opentelemetry.exporter._quickpulse._exporter._metric_to_quick_pulse_data_points") | ||
| def test_export_subscribed_true(self, convert_mock, post_mock): | ||
| post_response = _Response( | ||
| mock.Mock(), | ||
| None, | ||
| { | ||
| "x-ms-qps-subscribed": "true", | ||
| } | ||
| ) | ||
| convert_mock.return_value = [self._data_point] | ||
| post_mock.return_value = post_response | ||
| result = self._exporter.export( | ||
| self._metrics_data, | ||
| base_monitoring_data_point=self._data_point | ||
| ) | ||
| self.assertEqual(result, MetricExportResult.SUCCESS) |
84 changes: 84 additions & 0 deletions
84
sdk/monitor/azure-monitor-opentelemetry-exporter/tests/quickpulse/test_live_metrics.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. | ||
|
|
||
| import platform | ||
| import unittest | ||
| from unittest import mock | ||
|
|
||
| from opentelemetry.sdk.metrics import MeterProvider | ||
| from opentelemetry.sdk.resources import Resource, ResourceAttributes | ||
|
|
||
| from azure.monitor.opentelemetry.exporter._generated.models import ContextTagKeys | ||
| from azure.monitor.opentelemetry.exporter._quickpulse._generated.models import MonitoringDataPoint | ||
| from azure.monitor.opentelemetry.exporter._quickpulse._exporter import ( | ||
| _QuickpulseExporter, | ||
| _QuickpulseMetricReader, | ||
| ) | ||
| from azure.monitor.opentelemetry.exporter._quickpulse._live_metrics import ( | ||
| enable_live_metrics, | ||
| _QuickpulseManager, | ||
| ) | ||
| from azure.monitor.opentelemetry.exporter._utils import ( | ||
| _get_sdk_version, | ||
| _populate_part_a_fields, | ||
| ) | ||
|
|
||
|
|
||
| class TestLiveMetrics(unittest.TestCase): | ||
|
|
||
| @mock.patch("azure.monitor.opentelemetry.exporter._quickpulse._live_metrics._QuickpulseManager") | ||
| def test_enable_live_metrics(self, manager_mock): | ||
| mock_resource = mock.Mock() | ||
| enable_live_metrics( | ||
| connection_string="test_cs", | ||
| resource=mock_resource, | ||
| ) | ||
| manager_mock.assert_called_with("test_cs", mock_resource) | ||
|
|
||
|
|
||
| class TestQuickpulseManager(unittest.TestCase): | ||
|
|
||
| @mock.patch("opentelemetry.sdk.metrics.MeterProvider.__new__") | ||
| @mock.patch("azure.monitor.opentelemetry.exporter._quickpulse._exporter._QuickpulseMetricReader.__new__") | ||
| @mock.patch("opentelemetry.sdk.trace.id_generator.RandomIdGenerator.__new__") | ||
| @mock.patch("azure.monitor.opentelemetry.exporter._quickpulse._exporter._QuickpulseExporter.__new__") | ||
| @mock.patch("azure.monitor.opentelemetry.exporter._quickpulse._generated.models.MonitoringDataPoint.__new__") | ||
| def test_init(self, point_mock, exporter_mock, generator_mock, reader_mock, provider_mock): | ||
| point_inst_mock = mock.Mock() | ||
| point_mock.return_value = point_inst_mock | ||
| exporter_inst_mock = mock.Mock() | ||
| exporter_mock.return_value = exporter_inst_mock | ||
| reader_inst_mock = mock.Mock() | ||
| reader_mock.return_value = reader_inst_mock | ||
| provider_inst_mock = mock.Mock() | ||
| provider_mock.return_value = provider_inst_mock | ||
| generator_inst_mock = mock.Mock() | ||
| generator_mock.return_value = generator_inst_mock | ||
| generator_inst_mock.generate_trace_id.return_value = "test_trace_id" | ||
| resource = Resource.create( | ||
| { | ||
| ResourceAttributes.SERVICE_INSTANCE_ID: "test_instance", | ||
| ResourceAttributes.SERVICE_NAME: "test_service", | ||
| } | ||
| ) | ||
| part_a_fields = _populate_part_a_fields(resource) | ||
| qpm = _QuickpulseManager( | ||
| connection_string="test_cs", | ||
| resource=resource, | ||
| ) | ||
| self.assertEqual(qpm._base_monitoring_data_point, point_inst_mock) | ||
| self.assertEqual(qpm._exporter, exporter_inst_mock) | ||
| self.assertEqual(qpm._reader, reader_inst_mock) | ||
| self.assertEqual(qpm._meter_provider, provider_inst_mock) | ||
| point_mock.assert_called_with( | ||
| MonitoringDataPoint, | ||
| version=_get_sdk_version(), | ||
| invariant_version=1, | ||
| instance=part_a_fields.get(ContextTagKeys.AI_CLOUD_ROLE_INSTANCE, ""), | ||
| role_name=part_a_fields.get(ContextTagKeys.AI_CLOUD_ROLE, ""), | ||
| machine_name=platform.node(), | ||
| stream_id="test_trace_id", | ||
| ) | ||
| exporter_mock.assert_called_with(_QuickpulseExporter, "test_cs") | ||
| reader_mock.assert_called_with(_QuickpulseMetricReader, exporter_inst_mock, point_inst_mock) | ||
| provider_mock.assert_called_with(MeterProvider, [reader_inst_mock]) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.