diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 2281d05e176..48d109f5ef6 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -19,6 +19,25 @@ Please describe the tests that you ran to verify your changes. Provide instructi - [ ] Test A +# Does This PR Require a Contrib Repo Change? + +Answer the following question based on these examples of changes that would require a Contrib Repo Change: +- [The OTel specification](https://github.com/open-telemetry/opentelemetry-specification) has changed which prompted this PR to update the method interfaces of `opentelemetry-api/` or `opentelemetry-sdk/` +- The method interfaces of `opentelemetry-instrumentation/` have changed +- The method interfaces of `test/util` have changed +- Scripts in `scripts/` that were copied over to the Contrib repo have changed +- Configuration files that were copied over to the Contrib repo have changed (when consistency between repositories is applicable) such as in + - `pyproject.toml` + - `isort.cfg` + - `.flake8` +- When a new `.github/CODEOWNER` is added +- Major changes to project information, such as in: + - `README.md` + - `CONTRIBUTING.md` + +- [ ] Yes. - Link to PR: +- [ ] No. + # Checklist: - [ ] Followed the style guidelines of this project diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b54c1841a1a..ce3c100d0ae 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ env: # Otherwise, set variable to the commit of your branch on # opentelemetry-python-contrib which is compatible with these Core repo # changes. - CONTRIB_REPO_SHA: master + CONTRIB_REPO_SHA: bcec49cf2eccf8da66c9e63b9836ea8a20516efc jobs: build: diff --git a/docs/examples/error_hander/error_handler_0/setup.cfg b/docs/examples/error_hander/error_handler_0/setup.cfg index 3ea84d43d80..d0a7b6275e3 100644 --- a/docs/examples/error_hander/error_handler_0/setup.cfg +++ b/docs/examples/error_hander/error_handler_0/setup.cfg @@ -36,7 +36,7 @@ package_dir= =src packages=find_namespace: install_requires = - opentelemetry-sdk == 0.16.dev0 + opentelemetry-sdk == 0.17.dev0 [options.packages.find] where = src diff --git a/docs/examples/error_hander/error_handler_0/src/error_handler_0/version.py b/docs/examples/error_hander/error_handler_0/src/error_handler_0/version.py index 1f98d44fa88..86e1dbb17ab 100644 --- a/docs/examples/error_hander/error_handler_0/src/error_handler_0/version.py +++ b/docs/examples/error_hander/error_handler_0/src/error_handler_0/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.16.dev0" +__version__ = "0.17.dev0" diff --git a/docs/examples/error_hander/error_handler_1/setup.cfg b/docs/examples/error_hander/error_handler_1/setup.cfg index 6b9ab21e4b4..304b32fd5e9 100644 --- a/docs/examples/error_hander/error_handler_1/setup.cfg +++ b/docs/examples/error_hander/error_handler_1/setup.cfg @@ -36,7 +36,7 @@ package_dir= =src packages=find_namespace: install_requires = - opentelemetry-sdk == 0.16.dev0 + opentelemetry-sdk == 0.17.dev0 [options.packages.find] where = src diff --git a/docs/examples/error_hander/error_handler_1/src/error_handler_1/version.py b/docs/examples/error_hander/error_handler_1/src/error_handler_1/version.py index 1f98d44fa88..86e1dbb17ab 100644 --- a/docs/examples/error_hander/error_handler_1/src/error_handler_1/version.py +++ b/docs/examples/error_hander/error_handler_1/src/error_handler_1/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.16.dev0" +__version__ = "0.17.dev0" diff --git a/exporter/opentelemetry-exporter-jaeger/setup.cfg b/exporter/opentelemetry-exporter-jaeger/setup.cfg index 66d0d61cbbd..37d2402d5f7 100644 --- a/exporter/opentelemetry-exporter-jaeger/setup.cfg +++ b/exporter/opentelemetry-exporter-jaeger/setup.cfg @@ -40,8 +40,8 @@ package_dir= packages=find_namespace: install_requires = thrift >= 0.10.0 - opentelemetry-api == 0.16.dev0 - opentelemetry-sdk == 0.16.dev0 + opentelemetry-api == 0.17.dev0 + opentelemetry-sdk == 0.17.dev0 [options.packages.find] where = src diff --git a/exporter/opentelemetry-exporter-jaeger/src/opentelemetry/exporter/jaeger/version.py b/exporter/opentelemetry-exporter-jaeger/src/opentelemetry/exporter/jaeger/version.py index 7b04708d09a..203d035bb24 100644 --- a/exporter/opentelemetry-exporter-jaeger/src/opentelemetry/exporter/jaeger/version.py +++ b/exporter/opentelemetry-exporter-jaeger/src/opentelemetry/exporter/jaeger/version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.16.dev0" +__version__ = "0.17.dev0" diff --git a/exporter/opentelemetry-exporter-opencensus/CHANGELOG.md b/exporter/opentelemetry-exporter-opencensus/CHANGELOG.md index 33a182a3fd6..33ccae1d455 100644 --- a/exporter/opentelemetry-exporter-opencensus/CHANGELOG.md +++ b/exporter/opentelemetry-exporter-opencensus/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## Version 0.16b0 + +Released 2020-11-25 + - Update protobuf versions ([#1356](https://github.com/open-telemetry/opentelemetry-python/pull/1356)) diff --git a/exporter/opentelemetry-exporter-opencensus/setup.cfg b/exporter/opentelemetry-exporter-opencensus/setup.cfg index ad470e2b191..2ff3b2bc2b4 100644 --- a/exporter/opentelemetry-exporter-opencensus/setup.cfg +++ b/exporter/opentelemetry-exporter-opencensus/setup.cfg @@ -41,8 +41,8 @@ packages=find_namespace: install_requires = grpcio >= 1.0.0, < 2.0.0 opencensus-proto >= 0.1.0, < 1.0.0 - opentelemetry-api == 0.16.dev0 - opentelemetry-sdk == 0.16.dev0 + opentelemetry-api == 0.17.dev0 + opentelemetry-sdk == 0.17.dev0 protobuf >= 3.13.0 [options.packages.find] diff --git a/exporter/opentelemetry-exporter-opencensus/src/opentelemetry/exporter/opencensus/version.py b/exporter/opentelemetry-exporter-opencensus/src/opentelemetry/exporter/opencensus/version.py index 1f98d44fa88..86e1dbb17ab 100644 --- a/exporter/opentelemetry-exporter-opencensus/src/opentelemetry/exporter/opencensus/version.py +++ b/exporter/opentelemetry-exporter-opencensus/src/opentelemetry/exporter/opencensus/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.16.dev0" +__version__ = "0.17.dev0" diff --git a/exporter/opentelemetry-exporter-otlp/CHANGELOG.md b/exporter/opentelemetry-exporter-otlp/CHANGELOG.md index e467d8f78e9..4528c215345 100644 --- a/exporter/opentelemetry-exporter-otlp/CHANGELOG.md +++ b/exporter/opentelemetry-exporter-otlp/CHANGELOG.md @@ -2,6 +2,15 @@ ## Unreleased +- Add meter reference to observers + ([#1425](https://github.com/open-telemetry/opentelemetry-python/pull/1425)) + +## Version 0.16b0 + +Released 2020-11-25 + +- Add instrumentation library name and version to OTLP exported metrics + ([#1418](https://github.com/open-telemetry/opentelemetry-python/pull/1418)) - Change temporality for Counter and UpDownCounter ([#1384](https://github.com/open-telemetry/opentelemetry-python/pull/1384)) - Add Gzip compression for exporter diff --git a/exporter/opentelemetry-exporter-otlp/setup.cfg b/exporter/opentelemetry-exporter-otlp/setup.cfg index 7ba1b5c1f9f..20d724e8676 100644 --- a/exporter/opentelemetry-exporter-otlp/setup.cfg +++ b/exporter/opentelemetry-exporter-otlp/setup.cfg @@ -41,9 +41,9 @@ packages=find_namespace: install_requires = grpcio >= 1.0.0, < 2.0.0 googleapis-common-protos ~= 1.52.0 - opentelemetry-api == 0.16.dev0 - opentelemetry-sdk == 0.16.dev0 - opentelemetry-proto == 0.16.dev0 + opentelemetry-api == 0.17.dev0 + opentelemetry-sdk == 0.17.dev0 + opentelemetry-proto == 0.17.dev0 backoff ~= 1.10.0 [options.extras_require] diff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/metrics_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/metrics_exporter/__init__.py index c90dd47db27..559e313477d 100644 --- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/metrics_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/metrics_exporter/__init__.py @@ -304,9 +304,11 @@ def _translate_data( ) argument = type_class[value_type]["gauge"]["argument"] - sdk_resource_instrumentation_library_metrics[ + instrumentation_library_metrics = sdk_resource_instrumentation_library_metrics[ export_record.resource - ].metrics.append( + ] + + instrumentation_library_metrics.metrics.append( OTLPMetric( **{ "name": export_record.instrument.name, @@ -317,6 +319,19 @@ def _translate_data( ) ) + instrumentation_library_metrics.instrumentation_library.name = ( + export_record.instrument.meter.instrumentation_info.name + ) + + version = ( + export_record.instrument.meter.instrumentation_info.version + ) + + if version: + ( + instrumentation_library_metrics.instrumentation_library.version + ) = version + return ExportMetricsServiceRequest( resource_metrics=_get_resource_data( sdk_resource_instrumentation_library_metrics, diff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py index 5059e042c32..1af8d26aa91 100644 --- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py @@ -14,7 +14,6 @@ """OTLP Span Exporter""" import logging -import os from typing import Optional, Sequence from grpc import ChannelCredentials diff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/version.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/version.py index 1f98d44fa88..86e1dbb17ab 100644 --- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/version.py +++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.16.dev0" +__version__ = "0.17.dev0" diff --git a/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py b/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py index 308d217f21b..6d45e30d440 100644 --- a/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py +++ b/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py @@ -15,7 +15,7 @@ import os from collections import OrderedDict from unittest import TestCase -from unittest.mock import patch +from unittest.mock import Mock, patch from grpc import ChannelCredentials @@ -26,6 +26,7 @@ ) from opentelemetry.proto.common.v1.common_pb2 import ( AnyValue, + InstrumentationLibrary, KeyValue, StringKeyValue, ) @@ -40,7 +41,13 @@ from opentelemetry.proto.resource.v1.resource_pb2 import ( Resource as OTLPResource, ) -from opentelemetry.sdk.metrics import Counter, MeterProvider +from opentelemetry.sdk.metrics import ( + Counter, + MeterProvider, + SumObserver, + UpDownCounter, + UpDownSumObserver, +) from opentelemetry.sdk.metrics.export import ExportRecord from opentelemetry.sdk.metrics.export.aggregate import SumAggregator from opentelemetry.sdk.resources import Resource as SDKResource @@ -49,26 +56,12 @@ class TestOTLPMetricExporter(TestCase): - @patch("opentelemetry.sdk.metrics.export.aggregate.time_ns") - def setUp(self, mock_time_ns): # pylint: disable=arguments-differ - mock_time_ns.configure_mock(**{"return_value": 1}) + def setUp(self): # pylint: disable=arguments-differ self.exporter = OTLPMetricsExporter(insecure=True) - resource = SDKResource(OrderedDict([("a", 1), ("b", False)])) - - self.counter_export_record = ExportRecord( - Counter( - "c", - "d", - "e", - int, - MeterProvider(resource=resource,).get_meter(__name__), - ("f",), - ), - [("g", "h")], - SumAggregator(), - resource, + self.resource = SDKResource(OrderedDict([("a", 1), ("b", False)])) + self.meter = MeterProvider(resource=self.resource,).get_meter( + "name", "version" ) - Configuration._reset() # pylint: disable=protected-access def tearDown(self): @@ -101,12 +94,20 @@ def test_no_credentials_error(self): with self.assertRaises(ValueError): OTLPMetricsExporter() - def test_translate_metrics(self): - # pylint: disable=no-member + @patch("opentelemetry.sdk.metrics.export.aggregate.time_ns") + def test_translate_counter_export_record(self, mock_time_ns): + mock_time_ns.configure_mock(**{"return_value": 1}) + + counter_export_record = ExportRecord( + Counter("c", "d", "e", int, self.meter, ("f",),), + [("g", "h")], + SumAggregator(), + self.resource, + ) - self.counter_export_record.aggregator.checkpoint = 1 - self.counter_export_record.aggregator.initial_checkpoint_timestamp = 1 - self.counter_export_record.aggregator.last_update_timestamp = 1 + counter_export_record.aggregator.checkpoint = 1 + counter_export_record.aggregator.initial_checkpoint_timestamp = 1 + counter_export_record.aggregator.last_update_timestamp = 1 expected = ExportMetricsServiceRequest( resource_metrics=[ @@ -121,6 +122,9 @@ def test_translate_metrics(self): ), instrumentation_library_metrics=[ InstrumentationLibraryMetrics( + instrumentation_library=InstrumentationLibrary( + name="name", version="version", + ), metrics=[ OTLPMetric( name="c", @@ -145,7 +149,204 @@ def test_translate_metrics(self): is_monotonic=True, ), ) - ] + ], + ) + ], + ) + ] + ) + + # pylint: disable=protected-access + actual = self.exporter._translate_data([counter_export_record]) + + self.assertEqual(expected, actual) + + @patch("opentelemetry.sdk.metrics.export.aggregate.time_ns") + def test_translate_sum_observer_export_record(self, mock_time_ns): + mock_time_ns.configure_mock(**{"return_value": 1}) + counter_export_record = ExportRecord( + SumObserver(Mock(), "c", "d", "e", int, self.meter, ("f",),), + [("g", "h")], + SumAggregator(), + self.resource, + ) + + counter_export_record.aggregator.checkpoint = 1 + counter_export_record.aggregator.initial_checkpoint_timestamp = 1 + counter_export_record.aggregator.last_update_timestamp = 1 + + expected = ExportMetricsServiceRequest( + resource_metrics=[ + ResourceMetrics( + resource=OTLPResource( + attributes=[ + KeyValue(key="a", value=AnyValue(int_value=1)), + KeyValue( + key="b", value=AnyValue(bool_value=False) + ), + ] + ), + instrumentation_library_metrics=[ + InstrumentationLibraryMetrics( + instrumentation_library=InstrumentationLibrary( + name="name", version="version", + ), + metrics=[ + OTLPMetric( + name="c", + description="d", + unit="e", + int_sum=IntSum( + data_points=[ + IntDataPoint( + labels=[ + StringKeyValue( + key="g", value="h" + ) + ], + value=1, + time_unix_nano=1, + start_time_unix_nano=1, + ) + ], + aggregation_temporality=( + AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE + ), + is_monotonic=True, + ), + ) + ], + ) + ], + ) + ] + ) + + # pylint: disable=protected-access + actual = self.exporter._translate_data([counter_export_record]) + + self.assertEqual(expected, actual) + + @patch("opentelemetry.sdk.metrics.export.aggregate.time_ns") + def test_translate_updowncounter_export_record(self, mock_time_ns): + mock_time_ns.configure_mock(**{"return_value": 1}) + + counter_export_record = ExportRecord( + UpDownCounter("c", "d", "e", int, self.meter), + [("g", "h")], + SumAggregator(), + self.resource, + ) + + counter_export_record.aggregator.checkpoint = 1 + counter_export_record.aggregator.initial_checkpoint_timestamp = 1 + counter_export_record.aggregator.last_update_timestamp = 1 + + expected = ExportMetricsServiceRequest( + resource_metrics=[ + ResourceMetrics( + resource=OTLPResource( + attributes=[ + KeyValue(key="a", value=AnyValue(int_value=1)), + KeyValue( + key="b", value=AnyValue(bool_value=False) + ), + ] + ), + instrumentation_library_metrics=[ + InstrumentationLibraryMetrics( + instrumentation_library=InstrumentationLibrary( + name="name", version="version", + ), + metrics=[ + OTLPMetric( + name="c", + description="d", + unit="e", + int_sum=IntSum( + data_points=[ + IntDataPoint( + labels=[ + StringKeyValue( + key="g", value="h" + ) + ], + value=1, + time_unix_nano=1, + start_time_unix_nano=1, + ) + ], + aggregation_temporality=( + AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE + ), + ), + ) + ], + ) + ], + ) + ] + ) + + # pylint: disable=protected-access + actual = self.exporter._translate_data([counter_export_record]) + + self.assertEqual(expected, actual) + + @patch("opentelemetry.sdk.metrics.export.aggregate.time_ns") + def test_translate_updownsum_observer_export_record(self, mock_time_ns): + mock_time_ns.configure_mock(**{"return_value": 1}) + counter_export_record = ExportRecord( + UpDownSumObserver(Mock(), "c", "d", "e", int, self.meter, ("f",),), + [("g", "h")], + SumAggregator(), + self.resource, + ) + + counter_export_record.aggregator.checkpoint = 1 + counter_export_record.aggregator.initial_checkpoint_timestamp = 1 + counter_export_record.aggregator.last_update_timestamp = 1 + + expected = ExportMetricsServiceRequest( + resource_metrics=[ + ResourceMetrics( + resource=OTLPResource( + attributes=[ + KeyValue(key="a", value=AnyValue(int_value=1)), + KeyValue( + key="b", value=AnyValue(bool_value=False) + ), + ] + ), + instrumentation_library_metrics=[ + InstrumentationLibraryMetrics( + instrumentation_library=InstrumentationLibrary( + name="name", version="version", + ), + metrics=[ + OTLPMetric( + name="c", + description="d", + unit="e", + int_sum=IntSum( + data_points=[ + IntDataPoint( + labels=[ + StringKeyValue( + key="g", value="h" + ) + ], + value=1, + time_unix_nano=1, + start_time_unix_nano=1, + ) + ], + aggregation_temporality=( + AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE + ), + ), + ) + ], ) ], ) @@ -153,6 +354,6 @@ def test_translate_metrics(self): ) # pylint: disable=protected-access - actual = self.exporter._translate_data([self.counter_export_record]) + actual = self.exporter._translate_data([counter_export_record]) self.assertEqual(expected, actual) diff --git a/exporter/opentelemetry-exporter-prometheus/setup.cfg b/exporter/opentelemetry-exporter-prometheus/setup.cfg index 540f9fcc9ed..6ab2101f8cb 100644 --- a/exporter/opentelemetry-exporter-prometheus/setup.cfg +++ b/exporter/opentelemetry-exporter-prometheus/setup.cfg @@ -40,8 +40,8 @@ package_dir= packages=find_namespace: install_requires = prometheus_client >= 0.5.0, < 1.0.0 - opentelemetry-api == 0.16.dev0 - opentelemetry-sdk == 0.16.dev0 + opentelemetry-api == 0.17.dev0 + opentelemetry-sdk == 0.17.dev0 [options.packages.find] where = src diff --git a/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/version.py b/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/version.py index 1f98d44fa88..86e1dbb17ab 100644 --- a/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/version.py +++ b/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.16.dev0" +__version__ = "0.17.dev0" diff --git a/exporter/opentelemetry-exporter-zipkin/CHANGELOG.md b/exporter/opentelemetry-exporter-zipkin/CHANGELOG.md index 972096a8ef9..bb10a1a629b 100644 --- a/exporter/opentelemetry-exporter-zipkin/CHANGELOG.md +++ b/exporter/opentelemetry-exporter-zipkin/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## Version 0.16b0 + +Released 2020-11-25 + - Support for v2 api protobuf format ([#1318](https://github.com/open-telemetry/opentelemetry-python/pull/1318)) ## Version 0.14b0 diff --git a/exporter/opentelemetry-exporter-zipkin/setup.cfg b/exporter/opentelemetry-exporter-zipkin/setup.cfg index 1803eac14e8..6fda3370146 100644 --- a/exporter/opentelemetry-exporter-zipkin/setup.cfg +++ b/exporter/opentelemetry-exporter-zipkin/setup.cfg @@ -41,8 +41,8 @@ packages=find_namespace: install_requires = protobuf >= 3.12 requests ~= 2.7 - opentelemetry-api == 0.16.dev0 - opentelemetry-sdk == 0.16.dev0 + opentelemetry-api == 0.17.dev0 + opentelemetry-sdk == 0.17.dev0 [options.packages.find] where = src diff --git a/exporter/opentelemetry-exporter-zipkin/src/opentelemetry/exporter/zipkin/version.py b/exporter/opentelemetry-exporter-zipkin/src/opentelemetry/exporter/zipkin/version.py index 1f98d44fa88..86e1dbb17ab 100644 --- a/exporter/opentelemetry-exporter-zipkin/src/opentelemetry/exporter/zipkin/version.py +++ b/exporter/opentelemetry-exporter-zipkin/src/opentelemetry/exporter/zipkin/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.16.dev0" +__version__ = "0.17.dev0" diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.cfg b/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.cfg index 33cad7b9351..87def810899 100644 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.cfg +++ b/instrumentation/opentelemetry-instrumentation-opentracing-shim/setup.cfg @@ -41,11 +41,11 @@ packages=find_namespace: install_requires = Deprecated >= 1.2.6 opentracing ~= 2.0 - opentelemetry-api == 0.16.dev0 + opentelemetry-api == 0.17.dev0 [options.extras_require] test = - opentelemetry-test == 0.16.dev0 + opentelemetry-test == 0.17.dev0 opentracing ~= 2.2.0 [options.packages.find] diff --git a/instrumentation/opentelemetry-instrumentation-opentracing-shim/src/opentelemetry/instrumentation/opentracing_shim/version.py b/instrumentation/opentelemetry-instrumentation-opentracing-shim/src/opentelemetry/instrumentation/opentracing_shim/version.py index 1f98d44fa88..86e1dbb17ab 100644 --- a/instrumentation/opentelemetry-instrumentation-opentracing-shim/src/opentelemetry/instrumentation/opentracing_shim/version.py +++ b/instrumentation/opentelemetry-instrumentation-opentracing-shim/src/opentelemetry/instrumentation/opentracing_shim/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.16.dev0" +__version__ = "0.17.dev0" diff --git a/opentelemetry-api/CHANGELOG.md b/opentelemetry-api/CHANGELOG.md index a957b5e844f..ccf3f53e315 100644 --- a/opentelemetry-api/CHANGELOG.md +++ b/opentelemetry-api/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## Version 0.16b0 + +Released 2020-11-25 + - Add optional parameter to `record_exception` method ([#1314](https://github.com/open-telemetry/opentelemetry-python/pull/1314)) - Add pickle support to SpanContext class ([#1380](https://github.com/open-telemetry/opentelemetry-python/pull/1380)) diff --git a/opentelemetry-api/src/opentelemetry/version.py b/opentelemetry-api/src/opentelemetry/version.py index 1f98d44fa88..86e1dbb17ab 100644 --- a/opentelemetry-api/src/opentelemetry/version.py +++ b/opentelemetry-api/src/opentelemetry/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.16.dev0" +__version__ = "0.17.dev0" diff --git a/opentelemetry-instrumentation/CHANGELOG.md b/opentelemetry-instrumentation/CHANGELOG.md index 34366cb6b14..2a93c09ba5c 100644 --- a/opentelemetry-instrumentation/CHANGELOG.md +++ b/opentelemetry-instrumentation/CHANGELOG.md @@ -2,9 +2,17 @@ ## Unreleased +## Version 0.16b0 + +Released 2020-11-25 + - Add IDs Generator as Configurable Property of Auto Instrumentation ([#1404](https://github.com/open-telemetry/opentelemetry-python/pull/1404)) - Added support for `OTEL_EXPORTER` to the `opentelemetry-instrument` command ([#1036](https://github.com/open-telemetry/opentelemetry-python/pull/1036)) +- Add missing references to instrumented packages + ([#1416](https://github.com/open-telemetry/opentelemetry-python/pull/1416)) +- Instrumentation Package depends on the OTel SDK + ([#1405](https://github.com/open-telemetry/opentelemetry-python/pull/1405)) ## Version 0.14b0 diff --git a/opentelemetry-instrumentation/setup.cfg b/opentelemetry-instrumentation/setup.cfg index 6080af2526a..558e6a54e2f 100644 --- a/opentelemetry-instrumentation/setup.cfg +++ b/opentelemetry-instrumentation/setup.cfg @@ -41,7 +41,8 @@ packages=find_namespace: zip_safe = False include_package_data = True install_requires = - opentelemetry-api == 0.16.dev0 + opentelemetry-api == 0.17.dev0 + opentelemetry-sdk == 0.17.dev0 wrapt >= 1.0.0, < 2.0.0 [options.packages.find] diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py index 4b6a677a84f..44487a77947 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap.py @@ -23,8 +23,18 @@ logger = getLogger(__file__) -# target library to desired instrumentor path/versioned package name +# A mapping of "target library" to "desired instrumentor path/versioned package +# name". Used as part of the `opentelemetry-bootstrap` command which looks at +# libraries used by the application that is to be instrumented, and handles +# automatically installing the appropriate instrumentations for that app. +# This helps for those who prefer to turn on as much instrumentation as +# possible, and don't want to go through the manual process of combing through +# the libraries their application uses to figure which one can be +# instrumented. +# NOTE: system-metrics is not to be included. instrumentations = { + "aiohttp-client": "opentelemetry-instrumentation-aiohttp-client>=0.15b0", + "aiopg": "opentelemetry-instrumentation-aiopg>=0.15b0", "asgi": "opentelemetry-instrumentation-asgi>=0.11b0", "asyncpg": "opentelemetry-instrumentation-asyncpg>=0.11b0", "boto": "opentelemetry-instrumentation-boto>=0.11b0", @@ -33,8 +43,8 @@ "dbapi": "opentelemetry-instrumentation-dbapi>=0.8b0", "django": "opentelemetry-instrumentation-django>=0.8b0", "elasticsearch": "opentelemetry-instrumentation-elasticsearch>=0.11b0", - "fastapi": "opentelemetry-instrumentation-fastapi>=0.11b0", "falcon": "opentelemetry-instrumentation-falcon>=0.13b0", + "fastapi": "opentelemetry-instrumentation-fastapi>=0.11b0", "flask": "opentelemetry-instrumentation-flask>=0.8b0", "grpc": "opentelemetry-instrumentation-grpc>=0.8b0", "jinja2": "opentelemetry-instrumentation-jinja2>=0.8b0", @@ -46,6 +56,7 @@ "pyramid": "opentelemetry-instrumentation-pyramid>=0.11b0", "redis": "opentelemetry-instrumentation-redis>=0.8b0", "requests": "opentelemetry-instrumentation-requests>=0.8b0", + "sklearn": "opentelemetry-instrumentation-sklearn>=0.15b0", "sqlalchemy": "opentelemetry-instrumentation-sqlalchemy>=0.8b0", "sqlite3": "opentelemetry-instrumentation-sqlite3>=0.11b0", "starlette": "opentelemetry-instrumentation-starlette>=0.11b0", @@ -55,6 +66,8 @@ # relevant instrumentors and tracers to uninstall and check for conflicts for target libraries libraries = { + "aiohttp-client": ("opentelemetry-instrumentation-aiohttp-client",), + "aiopg": ("opentelemetry-instrumentation-aiopg",), "asgi": ("opentelemetry-instrumentation-asgi",), "asyncpg": ("opentelemetry-instrumentation-asyncpg",), "boto": ("opentelemetry-instrumentation-boto",), @@ -63,8 +76,8 @@ "dbapi": ("opentelemetry-instrumentation-dbapi",), "django": ("opentelemetry-instrumentation-django",), "elasticsearch": ("opentelemetry-instrumentation-elasticsearch",), - "fastapi": ("opentelemetry-instrumentation-fastapi",), "falcon": ("opentelemetry-instrumentation-falcon",), + "fastapi": ("opentelemetry-instrumentation-fastapi",), "flask": ("opentelemetry-instrumentation-flask",), "grpc": ("opentelemetry-instrumentation-grpc",), "jinja2": ("opentelemetry-instrumentation-jinja2",), @@ -76,6 +89,7 @@ "pyramid": ("opentelemetry-instrumentation-pyramid",), "redis": ("opentelemetry-instrumentation-redis",), "requests": ("opentelemetry-instrumentation-requests",), + "sklearn": ("opentelemetry-instrumentation-sklearn",), "sqlalchemy": ("opentelemetry-instrumentation-sqlalchemy",), "sqlite3": ("opentelemetry-instrumentation-sqlite3",), "starlette": ("opentelemetry-instrumentation-starlette",), diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py index 1f98d44fa88..86e1dbb17ab 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.16.dev0" +__version__ = "0.17.dev0" diff --git a/opentelemetry-proto/CHANGELOG.md b/opentelemetry-proto/CHANGELOG.md index b8e1d48ce58..9906bdee12c 100644 --- a/opentelemetry-proto/CHANGELOG.md +++ b/opentelemetry-proto/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## Version 0.16b0 + +Released 2020-11-25 + - Update protobuf versions ([#1356](https://github.com/open-telemetry/opentelemetry-python/pull/1356)) diff --git a/opentelemetry-proto/src/opentelemetry/proto/version.py b/opentelemetry-proto/src/opentelemetry/proto/version.py index 1f98d44fa88..86e1dbb17ab 100644 --- a/opentelemetry-proto/src/opentelemetry/proto/version.py +++ b/opentelemetry-proto/src/opentelemetry/proto/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.16.dev0" +__version__ = "0.17.dev0" diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index ffc04404ac5..0e0b0f550f9 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +- Add meter reference to observers + ([#1425](https://github.com/open-telemetry/opentelemetry-python/pull/1425)) + +## Version 0.16b0 + +Released 2020-11-25 + - Allow samplers to modify tracestate ([#1319](https://github.com/open-telemetry/opentelemetry-python/pull/1319)) - Add optional parameter to `record_exception` method @@ -14,8 +21,9 @@ ([#1373](https://github.com/open-telemetry/opentelemetry-python/pull/1373)) - Rename Meter class to Accumulator in Metrics SDK ([#1372](https://github.com/open-telemetry/opentelemetry-python/pull/1372)) -- Rename Meter class to Accumulator in Metrics SDK - ([#1372](https://github.com/open-telemetry/opentelemetry-python/pull/1372)) +- Fix `ParentBased` sampler for implicit parent spans. Fix also `trace_state` + erasure for dropped spans or spans sampled by the `TraceIdRatioBased` sampler. + ([#1394](https://github.com/open-telemetry/opentelemetry-python/pull/1394)) ## Version 0.15b0 diff --git a/opentelemetry-sdk/setup.cfg b/opentelemetry-sdk/setup.cfg index d27a24cf491..4acb6ca1fcb 100644 --- a/opentelemetry-sdk/setup.cfg +++ b/opentelemetry-sdk/setup.cfg @@ -41,7 +41,7 @@ packages=find_namespace: zip_safe = False include_package_data = True install_requires = - opentelemetry-api == 0.16.dev0 + opentelemetry-api == 0.17.dev0 [options.packages.find] where = src diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py index a2d16719a82..a09047e5231 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py @@ -241,6 +241,7 @@ def __init__( description: str, unit: str, value_type: Type[metrics_api.ValueT], + meter: "Accumulator", label_keys: Sequence[str] = (), enabled: bool = True, ): @@ -249,6 +250,7 @@ def __init__( self.description = description self.unit = unit self.value_type = value_type + self.meter = meter self.label_keys = label_keys self.enabled = enabled @@ -477,7 +479,14 @@ def register_sumobserver( enabled: bool = True, ) -> metrics_api.SumObserver: ob = SumObserver( - callback, name, description, unit, value_type, label_keys, enabled + callback, + name, + description, + unit, + value_type, + self, + label_keys, + enabled, ) with self.observers_lock: self.observers.add(ob) @@ -494,7 +503,14 @@ def register_updownsumobserver( enabled: bool = True, ) -> metrics_api.UpDownSumObserver: ob = UpDownSumObserver( - callback, name, description, unit, value_type, label_keys, enabled + callback, + name, + description, + unit, + value_type, + self, + label_keys, + enabled, ) with self.observers_lock: self.observers.add(ob) @@ -511,7 +527,14 @@ def register_valueobserver( enabled: bool = True, ) -> metrics_api.ValueObserver: ob = ValueObserver( - callback, name, description, unit, value_type, label_keys, enabled + callback, + name, + description, + unit, + value_type, + self, + label_keys, + enabled, ) with self.observers_lock: self.observers.add(ob) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/sampling.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/sampling.py index ffa51506ffa..82d2cebaa51 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/sampling.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/sampling.py @@ -151,7 +151,7 @@ def should_sample( trace_state: "TraceState" = None, ) -> "SamplingResult": if self._decision is Decision.DROP: - return SamplingResult(self._decision) + attributes = None return SamplingResult(self._decision, attributes, trace_state) def get_description(self) -> str: @@ -209,8 +209,8 @@ def should_sample( if trace_id & self.TRACE_ID_LIMIT < self.bound: decision = Decision.RECORD_AND_SAMPLE if decision is Decision.DROP: - return SamplingResult(decision) - return SamplingResult(decision, attributes) + attributes = None + return SamplingResult(decision, attributes, trace_state) def get_description(self) -> str: return "TraceIdRatioBased{{{}}}".format(self._rate) @@ -238,18 +238,16 @@ def should_sample( links: Sequence["Link"] = None, trace_state: "TraceState" = None, ) -> "SamplingResult": - if parent_context is not None: - parent_span_context = get_current_span( - parent_context - ).get_span_context() - # only drop if parent exists and is not a root span - if ( - parent_span_context is not None - and parent_span_context.is_valid - and not parent_span_context.trace_flags.sampled - ): - return SamplingResult(Decision.DROP) - return SamplingResult(Decision.RECORD_AND_SAMPLE, attributes) + parent_span_context = get_current_span( + parent_context + ).get_span_context() + # respect the sampling flag of the parent if present + if parent_span_context is not None and parent_span_context.is_valid: + decision = Decision.RECORD_AND_SAMPLE + if not parent_span_context.trace_flags.sampled: + decision = Decision.DROP + attributes = None + return SamplingResult(decision, attributes, trace_state) return self._delegate.should_sample( parent_context=parent_context, diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/version.py b/opentelemetry-sdk/src/opentelemetry/sdk/version.py index 1f98d44fa88..86e1dbb17ab 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/version.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "0.16.dev0" +__version__ = "0.17.dev0" diff --git a/opentelemetry-sdk/tests/metrics/test_metrics.py b/opentelemetry-sdk/tests/metrics/test_metrics.py index 58cc195cdfa..1697d8e6c85 100644 --- a/opentelemetry-sdk/tests/metrics/test_metrics.py +++ b/opentelemetry-sdk/tests/metrics/test_metrics.py @@ -13,7 +13,7 @@ # limitations under the License. import unittest -from unittest import mock +from unittest.mock import Mock, patch from opentelemetry import metrics as metrics_api from opentelemetry.sdk import metrics, resources @@ -41,7 +41,7 @@ def test_resource_empty(self): self.assertEqual(meter_provider.resource, resources._DEFAULT_RESOURCE) def test_start_pipeline(self): - exporter = mock.Mock() + exporter = Mock() meter_provider = metrics.MeterProvider() meter = meter_provider.get_meter(__name__) # pylint: disable=protected-access @@ -53,8 +53,8 @@ def test_start_pipeline(self): meter_provider.shutdown() def test_shutdown(self): - controller = mock.Mock() - exporter = mock.Mock() + controller = Mock() + exporter = Mock() meter_provider = metrics.MeterProvider() # pylint: disable=protected-access meter_provider._controllers = [controller] @@ -72,7 +72,7 @@ def test_extends_api(self): def test_collect_metrics(self): meter = metrics.MeterProvider().get_meter(__name__) - processor_mock = mock.Mock() + processor_mock = Mock() meter.processor = processor_mock counter = meter.create_counter("name", "desc", "unit", float,) labels = {"key1": "value1"} @@ -83,14 +83,14 @@ def test_collect_metrics(self): def test_collect_no_metrics(self): meter = metrics.MeterProvider().get_meter(__name__) - processor_mock = mock.Mock() + processor_mock = Mock() meter.processor = processor_mock meter.collect() self.assertFalse(processor_mock.process.called) def test_collect_not_registered(self): meter = metrics.MeterProvider().get_meter(__name__) - processor_mock = mock.Mock() + processor_mock = Mock() meter.processor = processor_mock counter = metrics.Counter("name", "desc", "unit", float, meter) labels = {"key1": "value1"} @@ -100,7 +100,7 @@ def test_collect_not_registered(self): def test_collect_disabled_metric(self): meter = metrics.MeterProvider().get_meter(__name__) - processor_mock = mock.Mock() + processor_mock = Mock() meter.processor = processor_mock counter = metrics.Counter("name", "desc", "unit", float, meter, False) labels = {"key1": "value1"} @@ -111,7 +111,7 @@ def test_collect_disabled_metric(self): def test_collect_observers(self): meter = metrics.MeterProvider().get_meter(__name__) - processor_mock = mock.Mock() + processor_mock = Mock() meter.processor = processor_mock def callback(observer): @@ -154,7 +154,7 @@ def test_record_batch(self): ) def test_create_counter(self): - resource = mock.Mock(spec=resources.Resource) + resource = Mock(spec=resources.Resource) meter_provider = metrics.MeterProvider(resource=resource) meter = meter_provider.get_meter(__name__) counter = meter.create_counter("name", "desc", "unit", int,) @@ -186,7 +186,7 @@ def test_create_valuerecorder(self): def test_register_sumobserver(self): meter = metrics.MeterProvider().get_meter(__name__) - callback = mock.Mock() + callback = Mock() observer = meter.register_sumobserver( callback, "name", "desc", "unit", int, @@ -206,7 +206,7 @@ def test_register_sumobserver(self): def test_register_updownsumobserver(self): meter = metrics.MeterProvider().get_meter(__name__) - callback = mock.Mock() + callback = Mock() observer = meter.register_updownsumobserver( callback, "name", "desc", "unit", int, @@ -226,7 +226,7 @@ def test_register_updownsumobserver(self): def test_register_valueobserver(self): meter = metrics.MeterProvider().get_meter(__name__) - callback = mock.Mock() + callback = Mock() observer = meter.register_valueobserver( callback, "name", "desc", "unit", int, @@ -246,7 +246,7 @@ def test_register_valueobserver(self): def test_unregister_observer(self): meter = metrics.MeterProvider().get_meter(__name__) - callback = mock.Mock() + callback = Mock() observer = meter.register_valueobserver( callback, "name", "desc", "unit", int, metrics.ValueObserver @@ -286,7 +286,7 @@ def test_add(self): metric.add(2, labels) self.assertEqual(bound_mock.view_datas.pop().aggregator.current, 5) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_add_non_decreasing_int_error(self, logger_mock): meter = metrics.MeterProvider().get_meter(__name__) metric = metrics.Counter("name", "desc", "unit", int, meter) @@ -300,7 +300,7 @@ def test_add_non_decreasing_int_error(self, logger_mock): self.assertEqual(bound_counter.view_datas.pop().aggregator.current, 3) self.assertEqual(logger_mock.warning.call_count, 1) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_add_non_decreasing_float_error(self, logger_mock): meter = metrics.MeterProvider().get_meter(__name__) metric = metrics.Counter("name", "desc", "unit", float, meter) @@ -351,7 +351,7 @@ def test_record(self): class TestSumObserver(unittest.TestCase): def test_observe(self): observer = metrics.SumObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} key_labels = metrics.get_dict_as_key(labels) @@ -363,26 +363,26 @@ def test_observe(self): def test_observe_disabled(self): observer = metrics.SumObserver( - None, "name", "desc", "unit", int, ("key",), False + None, "name", "desc", "unit", int, Mock(), ("key",), False ) labels = {"key": "value"} observer.observe(37, labels) self.assertEqual(len(observer.aggregators), 0) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_observe_incorrect_type(self, logger_mock): observer = metrics.SumObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} observer.observe(37.0, labels) self.assertEqual(len(observer.aggregators), 0) self.assertTrue(logger_mock.warning.called) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_observe_non_decreasing_error(self, logger_mock): observer = metrics.SumObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} observer.observe(37, labels) @@ -391,21 +391,21 @@ def test_observe_non_decreasing_error(self, logger_mock): self.assertTrue(logger_mock.warning.called) def test_run(self): - callback = mock.Mock() + callback = Mock() observer = metrics.SumObserver( - callback, "name", "desc", "unit", int, (), True + callback, "name", "desc", "unit", int, Mock(), (), True ) self.assertTrue(observer.run()) callback.assert_called_once_with(observer) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_run_exception(self, logger_mock): - callback = mock.Mock() + callback = Mock() callback.side_effect = Exception("We have a problem!") observer = metrics.SumObserver( - callback, "name", "desc", "unit", int, (), True + callback, "name", "desc", "unit", int, Mock(), (), True ) self.assertFalse(observer.run()) @@ -415,7 +415,7 @@ def test_run_exception(self, logger_mock): class TestUpDownSumObserver(unittest.TestCase): def test_observe(self): observer = metrics.UpDownSumObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} key_labels = metrics.get_dict_as_key(labels) @@ -427,16 +427,16 @@ def test_observe(self): def test_observe_disabled(self): observer = metrics.UpDownSumObserver( - None, "name", "desc", "unit", int, ("key",), False + None, "name", "desc", "unit", int, Mock(), ("key",), False ) labels = {"key": "value"} observer.observe(37, labels) self.assertEqual(len(observer.aggregators), 0) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_observe_incorrect_type(self, logger_mock): observer = metrics.UpDownSumObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} observer.observe(37.0, labels) @@ -444,21 +444,21 @@ def test_observe_incorrect_type(self, logger_mock): self.assertTrue(logger_mock.warning.called) def test_run(self): - callback = mock.Mock() + callback = Mock() observer = metrics.UpDownSumObserver( - callback, "name", "desc", "unit", int, (), True + callback, "name", "desc", "unit", int, Mock(), (), True ) self.assertTrue(observer.run()) callback.assert_called_once_with(observer) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_run_exception(self, logger_mock): - callback = mock.Mock() + callback = Mock() callback.side_effect = Exception("We have a problem!") observer = metrics.UpDownSumObserver( - callback, "name", "desc", "unit", int, (), True + callback, "name", "desc", "unit", int, Mock(), (), True ) self.assertFalse(observer.run()) @@ -468,7 +468,7 @@ def test_run_exception(self, logger_mock): class TestValueObserver(unittest.TestCase): def test_observe(self): observer = metrics.ValueObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} key_labels = metrics.get_dict_as_key(labels) @@ -484,16 +484,16 @@ def test_observe(self): def test_observe_disabled(self): observer = metrics.ValueObserver( - None, "name", "desc", "unit", int, ("key",), False + None, "name", "desc", "unit", int, Mock(), ("key",), False ) labels = {"key": "value"} observer.observe(37, labels) self.assertEqual(len(observer.aggregators), 0) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_observe_incorrect_type(self, logger_mock): observer = metrics.ValueObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} observer.observe(37.0, labels) @@ -501,21 +501,21 @@ def test_observe_incorrect_type(self, logger_mock): self.assertTrue(logger_mock.warning.called) def test_run(self): - callback = mock.Mock() + callback = Mock() observer = metrics.ValueObserver( - callback, "name", "desc", "unit", int, (), True + callback, "name", "desc", "unit", int, Mock(), (), True ) self.assertTrue(observer.run()) callback.assert_called_once_with(observer) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_run_exception(self, logger_mock): - callback = mock.Mock() + callback = Mock() callback.side_effect = Exception("We have a problem!") observer = metrics.ValueObserver( - callback, "name", "desc", "unit", int, (), True + callback, "name", "desc", "unit", int, Mock(), (), True ) self.assertFalse(observer.run()) @@ -525,40 +525,40 @@ def test_run_exception(self, logger_mock): # pylint: disable=no-self-use class TestBoundCounter(unittest.TestCase): def test_add(self): - meter_mock = mock.Mock() - metric_mock = mock.Mock() + meter_mock = Mock() + metric_mock = Mock() metric_mock.enabled = True metric_mock.value_type = int metric_mock.meter = meter_mock bound_metric = metrics.BoundCounter((), metric_mock) - view_datas_mock = mock.Mock() + view_datas_mock = Mock() bound_metric.view_datas = [view_datas_mock] bound_metric.add(3) view_datas_mock.record.assert_called_once_with(3) def test_add_disabled(self): - meter_mock = mock.Mock() - metric_mock = mock.Mock() + meter_mock = Mock() + metric_mock = Mock() metric_mock.enabled = False metric_mock.value_type = int metric_mock.meter = meter_mock bound_metric = metrics.BoundCounter((), metric_mock) - view_datas_mock = mock.Mock() + view_datas_mock = Mock() bound_metric.view_datas = [view_datas_mock] bound_metric.add(3) view_datas_mock.record.update_view.assert_not_called() - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_add_incorrect_type(self, logger_mock): - meter_mock = mock.Mock() - viewm_mock = mock.Mock() + meter_mock = Mock() + viewm_mock = Mock() meter_mock.view_manager = viewm_mock - metric_mock = mock.Mock() + metric_mock = Mock() metric_mock.enabled = True metric_mock.value_type = float metric_mock.meter = meter_mock bound_metric = metrics.BoundCounter((), metric_mock) - view_datas_mock = mock.Mock() + view_datas_mock = Mock() bound_metric.view_datas = [view_datas_mock] bound_metric.add(3) view_datas_mock.record.update_view.assert_not_called() @@ -567,38 +567,38 @@ def test_add_incorrect_type(self, logger_mock): class TestBoundValueRecorder(unittest.TestCase): def test_record(self): - meter_mock = mock.Mock() - metric_mock = mock.Mock() + meter_mock = Mock() + metric_mock = Mock() metric_mock.enabled = True metric_mock.value_type = int metric_mock.meter = meter_mock bound_valuerecorder = metrics.BoundValueRecorder((), metric_mock) - view_datas_mock = mock.Mock() + view_datas_mock = Mock() bound_valuerecorder.view_datas = [view_datas_mock] bound_valuerecorder.record(3) view_datas_mock.record.assert_called_once_with(3) def test_record_disabled(self): - meter_mock = mock.Mock() - metric_mock = mock.Mock() + meter_mock = Mock() + metric_mock = Mock() metric_mock.enabled = False metric_mock.value_type = int metric_mock.meter = meter_mock bound_valuerecorder = metrics.BoundValueRecorder((), metric_mock) - view_datas_mock = mock.Mock() + view_datas_mock = Mock() bound_valuerecorder.view_datas = [view_datas_mock] bound_valuerecorder.record(3) view_datas_mock.record.update_view.assert_not_called() - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_record_incorrect_type(self, logger_mock): - meter_mock = mock.Mock() - metric_mock = mock.Mock() + meter_mock = Mock() + metric_mock = Mock() metric_mock.enabled = True metric_mock.value_type = float metric_mock.meter = meter_mock bound_valuerecorder = metrics.BoundValueRecorder((), metric_mock) - view_datas_mock = mock.Mock() + view_datas_mock = Mock() bound_valuerecorder.view_datas = [view_datas_mock] bound_valuerecorder.record(3) view_datas_mock.record.update_view.assert_not_called() diff --git a/opentelemetry-sdk/tests/metrics/test_view.py b/opentelemetry-sdk/tests/metrics/test_view.py index 102db6da255..c20d6ed3c48 100644 --- a/opentelemetry-sdk/tests/metrics/test_view.py +++ b/opentelemetry-sdk/tests/metrics/test_view.py @@ -43,12 +43,14 @@ def test_default_aggregator(self, logger_mock): self.assertEqual( view.get_default_aggregator(ud_counter), aggregate.SumAggregator ) - observer = metrics.SumObserver(lambda: None, "", "", "1", int) + observer = metrics.SumObserver(lambda: None, "", "", "1", int, meter) self.assertEqual( view.get_default_aggregator(observer), aggregate.LastValueAggregator, ) - ud_observer = metrics.SumObserver(lambda: None, "", "", "1", int) + ud_observer = metrics.SumObserver( + lambda: None, "", "", "1", int, meter + ) self.assertEqual( view.get_default_aggregator(ud_observer), aggregate.LastValueAggregator, @@ -58,7 +60,9 @@ def test_default_aggregator(self, logger_mock): view.get_default_aggregator(recorder), aggregate.MinMaxSumCountAggregator, ) - v_observer = metrics.ValueObserver(lambda: None, "", "", "1", int) + v_observer = metrics.ValueObserver( + lambda: None, "", "", "1", int, meter + ) self.assertEqual( view.get_default_aggregator(v_observer), aggregate.ValueObserverAggregator, diff --git a/opentelemetry-sdk/tests/trace/test_sampling.py b/opentelemetry-sdk/tests/trace/test_sampling.py index d51a59c1066..f6d77ab04ba 100644 --- a/opentelemetry-sdk/tests/trace/test_sampling.py +++ b/opentelemetry-sdk/tests/trace/test_sampling.py @@ -12,9 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. +import contextlib import sys +import typing import unittest +from opentelemetry import context as context_api from opentelemetry import trace from opentelemetry.sdk.trace import sampling @@ -62,161 +65,173 @@ def test_ctr(self): class TestSampler(unittest.TestCase): - def test_always_on(self): - no_record_always_on = sampling.ALWAYS_ON.should_sample( + def _create_parent( + self, trace_flags: trace.TraceFlags, is_remote=False + ) -> typing.Optional[context_api.Context]: + if trace_flags is None: + return None + return trace.set_span_in_context( + self._create_parent_span(trace_flags, is_remote) + ) + + @staticmethod + def _create_parent_span( + trace_flags: trace.TraceFlags, is_remote=False + ) -> trace.DefaultSpan: + return trace.DefaultSpan( trace.SpanContext( - 0xDEADBEEF, 0xDEADBEF0, is_remote=False, trace_flags=TO_DEFAULT - ), - 0xDEADBEF1, - 0xDEADBEF2, - {"unsampled parent": "sampling on"}, - ) - self.assertTrue(no_record_always_on.decision.is_sampled()) - self.assertEqual( - no_record_always_on.attributes, {"unsampled parent": "sampling on"} + 0xDEADBEEF, + 0xDEADBEF0, + is_remote=is_remote, + trace_flags=trace_flags, + ) ) - sampled_always_on = sampling.ALWAYS_ON.should_sample( - trace.SpanContext( - 0xDEADBEEF, 0xDEADBEF0, is_remote=False, trace_flags=TO_SAMPLED - ), - 0xDEADBEF1, - 0xDEADBEF2, - {"sampled parent": "sampling on"}, - ) - self.assertTrue(no_record_always_on.decision.is_sampled()) - self.assertEqual( - sampled_always_on.attributes, {"sampled parent": "sampling on"} - ) + def test_always_on(self): + trace_state = trace.TraceState({"key": "value"}) + test_data = (TO_DEFAULT, TO_SAMPLED, None) + + for trace_flags in test_data: + with self.subTest(trace_flags=trace_flags): + context = self._create_parent(trace_flags) + sample_result = sampling.ALWAYS_ON.should_sample( + context, + 0xDEADBEF1, + "sampling on", + attributes={"sampled.expect": "true"}, + trace_state=trace_state, + ) + + self.assertTrue(sample_result.decision.is_sampled()) + self.assertEqual( + sample_result.attributes, {"sampled.expect": "true"} + ) + self.assertEqual(sample_result.trace_state, trace_state) def test_always_off(self): - no_record_always_off = sampling.ALWAYS_OFF.should_sample( - trace.SpanContext( - 0xDEADBEEF, 0xDEADBEF0, is_remote=False, trace_flags=TO_DEFAULT - ), - 0xDEADBEF1, - 0xDEADBEF2, - "unsampled parent, sampling off", - ) - self.assertFalse(no_record_always_off.decision.is_sampled()) - self.assertEqual(no_record_always_off.attributes, {}) + trace_state = trace.TraceState({"key": "value"}) + test_data = (TO_DEFAULT, TO_SAMPLED, None) + for trace_flags in test_data: + with self.subTest(trace_flags=trace_flags): + context = self._create_parent(trace_flags) + sample_result = sampling.ALWAYS_OFF.should_sample( + context, + 0xDEADBEF1, + "sampling off", + attributes={"sampled.expect": "false"}, + trace_state=trace_state, + ) + self.assertFalse(sample_result.decision.is_sampled()) + self.assertEqual(sample_result.attributes, {}) + self.assertEqual(sample_result.trace_state, trace_state) - sampled_always_on = sampling.ALWAYS_OFF.should_sample( - trace.SpanContext( - 0xDEADBEEF, 0xDEADBEF0, is_remote=False, trace_flags=TO_SAMPLED - ), + def test_default_on(self): + trace_state = trace.TraceState({"key": "value"}) + context = self._create_parent(trace_flags=TO_DEFAULT) + sample_result = sampling.DEFAULT_ON.should_sample( + context, 0xDEADBEF1, - 0xDEADBEF2, - "sampled parent, sampling off", + "unsampled parent, sampling on", + attributes={"sampled.expect": "false"}, + trace_state=trace_state, ) - self.assertFalse(sampled_always_on.decision.is_sampled()) - self.assertEqual(sampled_always_on.attributes, {}) + self.assertFalse(sample_result.decision.is_sampled()) + self.assertEqual(sample_result.attributes, {}) + self.assertEqual(sample_result.trace_state, trace_state) - def test_default_on(self): - context = trace.set_span_in_context( - trace.DefaultSpan( - trace.SpanContext( - 0xDEADBEEF, - 0xDEADBEF0, - is_remote=False, - trace_flags=TO_DEFAULT, - ) - ) - ) - no_record_default_on = sampling.DEFAULT_ON.should_sample( - context, 0xDEADBEF1, 0xDEADBEF2, "unsampled parent, sampling on", - ) - self.assertFalse(no_record_default_on.decision.is_sampled()) - self.assertEqual(no_record_default_on.attributes, {}) - - context = trace.set_span_in_context( - trace.DefaultSpan( - trace.SpanContext( - 0xDEADBEEF, - 0xDEADBEF0, - is_remote=False, - trace_flags=TO_SAMPLED, - ) - ) - ) - sampled_default_on = sampling.DEFAULT_ON.should_sample( - context, 0xDEADBEF1, 0xDEADBEF2, {"sampled parent": "sampling on"}, - ) - self.assertTrue(sampled_default_on.decision.is_sampled()) - self.assertEqual( - sampled_default_on.attributes, {"sampled parent": "sampling on"} + context = self._create_parent(trace_flags=TO_SAMPLED) + sample_result = sampling.DEFAULT_ON.should_sample( + context, + 0xDEADBEF1, + "sampled parent, sampling on", + attributes={"sampled.expect": "true"}, + trace_state=trace_state, ) + self.assertTrue(sample_result.decision.is_sampled()) + self.assertEqual(sample_result.attributes, {"sampled.expect": "true"}) + self.assertEqual(sample_result.trace_state, trace_state) - default_on = sampling.DEFAULT_ON.should_sample( - None, 0xDEADBEF1, 0xDEADBEF2, {"sampled parent": "sampling on"}, - ) - self.assertTrue(default_on.decision.is_sampled()) - self.assertEqual( - default_on.attributes, {"sampled parent": "sampling on"} + sample_result = sampling.DEFAULT_ON.should_sample( + None, + 0xDEADBEF1, + "no parent, sampling on", + attributes={"sampled.expect": "true"}, + trace_state=trace_state, ) + self.assertTrue(sample_result.decision.is_sampled()) + self.assertEqual(sample_result.attributes, {"sampled.expect": "true"}) + self.assertEqual(sample_result.trace_state, trace_state) def test_default_off(self): - context = trace.set_span_in_context( - trace.DefaultSpan( - trace.SpanContext( - 0xDEADBEEF, - 0xDEADBEF0, - is_remote=False, - trace_flags=TO_DEFAULT, - ) - ) - ) - no_record_default_off = sampling.DEFAULT_OFF.should_sample( - context, 0xDEADBEF1, 0xDEADBEF2, "unsampled parent, sampling off", - ) - self.assertFalse(no_record_default_off.decision.is_sampled()) - self.assertEqual(no_record_default_off.attributes, {}) - - context = trace.set_span_in_context( - trace.DefaultSpan( - trace.SpanContext( - 0xDEADBEEF, - 0xDEADBEF0, - is_remote=False, - trace_flags=TO_SAMPLED, - ) - ) - ) - sampled_default_off = sampling.DEFAULT_OFF.should_sample( - context, 0xDEADBEF1, 0xDEADBEF2, {"sampled parent": "sampling on"}, + trace_state = trace.TraceState({"key": "value"}) + context = self._create_parent(trace_flags=TO_DEFAULT) + sample_result = sampling.DEFAULT_OFF.should_sample( + context, + 0xDEADBEF1, + "unsampled parent, sampling off", + attributes={"sampled.expect", "false"}, + trace_state=trace_state, ) - self.assertTrue(sampled_default_off.decision.is_sampled()) - self.assertEqual( - sampled_default_off.attributes, {"sampled parent": "sampling on"} + self.assertFalse(sample_result.decision.is_sampled()) + self.assertEqual(sample_result.attributes, {}) + self.assertEqual(sample_result.trace_state, trace_state) + + context = self._create_parent(trace_flags=TO_SAMPLED) + sample_result = sampling.DEFAULT_OFF.should_sample( + context, + 0xDEADBEF1, + "sampled parent, sampling on", + attributes={"sampled.expect": "true"}, + trace_state=trace_state, ) + self.assertTrue(sample_result.decision.is_sampled()) + self.assertEqual(sample_result.attributes, {"sampled.expect": "true"}) + self.assertEqual(sample_result.trace_state, trace_state) default_off = sampling.DEFAULT_OFF.should_sample( - None, 0xDEADBEF1, 0xDEADBEF2, "unsampled parent, sampling off", + None, + 0xDEADBEF1, + "unsampled parent, sampling off", + attributes={"sampled.expect": "false"}, + trace_state=trace_state, ) self.assertFalse(default_off.decision.is_sampled()) self.assertEqual(default_off.attributes, {}) + self.assertEqual(default_off.trace_state, trace_state) def test_probability_sampler(self): + trace_state = trace.TraceState({"key": "value"}) sampler = sampling.TraceIdRatioBased(0.5) # Check that we sample based on the trace ID if the parent context is # null - self.assertTrue( - sampler.should_sample( - None, 0x7FFFFFFFFFFFFFFF, 0xDEADBEEF, "span name" - ).decision.is_sampled() - ) - self.assertFalse( - sampler.should_sample( - None, 0x8000000000000000, 0xDEADBEEF, "span name" - ).decision.is_sampled() - ) + sampled_result = sampler.should_sample( + None, + 0x7FFFFFFFFFFFFFFF, + "sampled true", + attributes={"sampled.expect": "true"}, + trace_state=trace_state, + ) + self.assertTrue(sampled_result.decision.is_sampled()) + self.assertEqual(sampled_result.attributes, {"sampled.expect": "true"}) + self.assertEqual(sampled_result.trace_state, trace_state) + + not_sampled_result = sampler.should_sample( + None, + 0x8000000000000000, + "sampled false", + attributes={"sampled.expect": "false"}, + trace_state=trace_state, + ) + self.assertFalse(not_sampled_result.decision.is_sampled()) + self.assertEqual(not_sampled_result.attributes, {}) + self.assertEqual(not_sampled_result.trace_state, trace_state) def test_probability_sampler_zero(self): default_off = sampling.TraceIdRatioBased(0.0) self.assertFalse( default_off.should_sample( - None, 0x0, 0xDEADBEEF, "span name" + None, 0x0, "span name" ).decision.is_sampled() ) @@ -224,7 +239,7 @@ def test_probability_sampler_one(self): default_off = sampling.TraceIdRatioBased(1.0) self.assertTrue( default_off.should_sample( - None, 0xFFFFFFFFFFFFFFFF, 0xDEADBEEF, "span name" + None, 0xFFFFFFFFFFFFFFFF, "span name" ).decision.is_sampled() ) @@ -236,12 +251,12 @@ def test_probability_sampler_limits(self): almost_always_off = sampling.TraceIdRatioBased(2 ** -64) self.assertTrue( almost_always_off.should_sample( - None, 0x0, 0xDEADBEEF, "span name" + None, 0x0, "span name" ).decision.is_sampled() ) self.assertFalse( almost_always_off.should_sample( - None, 0x1, 0xDEADBEEF, "span name" + None, 0x1, "span name" ).decision.is_sampled() ) self.assertEqual( @@ -259,7 +274,7 @@ def test_probability_sampler_limits(self): almost_always_on = sampling.TraceIdRatioBased(1 - 2 ** -64) self.assertTrue( almost_always_on.should_sample( - None, 0xFFFFFFFFFFFFFFFE, 0xDEADBEEF, "span name" + None, 0xFFFFFFFFFFFFFFFE, "span name" ).decision.is_sampled() ) @@ -271,9 +286,8 @@ def test_probability_sampler_limits(self): # almost_always_on.should_sample( # None, # 0xFFFFFFFFFFFFFFFF, - # 0xDEADBEEF, # "span name", - # ).sampled + # ).decision.is_sampled() # ) # self.assertEqual( # sampling.TraceIdRatioBased.get_bound_for_rate(1 - 2 ** -64)), @@ -287,7 +301,7 @@ def test_probability_sampler_limits(self): ) self.assertFalse( almost_almost_always_on.should_sample( - None, 0xFFFFFFFFFFFFFFFF, 0xDEADBEEF, "span name" + None, 0xFFFFFFFFFFFFFFFF, "span name" ).decision.is_sampled() ) # Check that the higest effective sampling rate is actually lower than @@ -297,47 +311,78 @@ def test_probability_sampler_limits(self): almost_almost_always_on.bound, 0xFFFFFFFFFFFFFFFF, ) - def test_parent_based(self): + def exec_parent_based(self, parent_sampling_context): + trace_state = trace.TraceState({"key": "value"}) sampler = sampling.ParentBased(sampling.ALWAYS_ON) - context = trace.set_span_in_context( - trace.DefaultSpan( - trace.SpanContext( - 0xDEADBEF0, - 0xDEADBEF1, - is_remote=False, - trace_flags=TO_DEFAULT, - ) + with parent_sampling_context( + self._create_parent_span(trace_flags=TO_DEFAULT) + ) as context: + # Check that the sampling decision matches the parent context if given + not_sampled_result = sampler.should_sample( + context, + 0x7FFFFFFFFFFFFFFF, + "unsampled parent, sampling on", + attributes={"sampled": "false"}, + trace_state=trace_state, ) - ) - # Check that the sampling decision matches the parent context if given - self.assertFalse( - sampler.should_sample( - context, 0x7FFFFFFFFFFFFFFF, 0xDEADBEEF, "span name", - ).decision.is_sampled() - ) - - context = trace.set_span_in_context( - trace.DefaultSpan( - trace.SpanContext( - 0xDEADBEF0, - 0xDEADBEF1, - is_remote=False, - trace_flags=TO_SAMPLED, - ) + self.assertFalse(not_sampled_result.decision.is_sampled()) + self.assertEqual(not_sampled_result.attributes, {}) + self.assertEqual(not_sampled_result.trace_state, trace_state) + + with parent_sampling_context( + self._create_parent_span(trace_flags=TO_SAMPLED) + ) as context: + sampler2 = sampling.ParentBased(sampling.ALWAYS_OFF) + sampled_result = sampler2.should_sample( + context, + 0x8000000000000000, + "sampled parent, sampling off", + attributes={"sampled": "true"}, + trace_state=trace_state, ) - ) - sampler2 = sampling.ParentBased(sampling.ALWAYS_OFF) - self.assertTrue( - sampler2.should_sample( - context, 0x8000000000000000, 0xDEADBEEF, "span name", - ).decision.is_sampled() - ) + self.assertTrue(sampled_result.decision.is_sampled()) + self.assertEqual(sampled_result.attributes, {"sampled": "true"}) + self.assertEqual(sampled_result.trace_state, trace_state) + + # for root span follow decision of delegate sampler + with parent_sampling_context(trace.INVALID_SPAN) as context: + sampler3 = sampling.ParentBased(sampling.ALWAYS_OFF) + not_sampled_result = sampler3.should_sample( + context, + 0x8000000000000000, + "parent, sampling off", + attributes={"sampled": "false"}, + trace_state=trace_state, + ) + self.assertFalse(not_sampled_result.decision.is_sampled()) + self.assertEqual(not_sampled_result.attributes, {}) + self.assertEqual(not_sampled_result.trace_state, trace_state) + + with parent_sampling_context(trace.INVALID_SPAN) as context: + sampler4 = sampling.ParentBased(sampling.ALWAYS_ON) + sampled_result = sampler4.should_sample( + context, + 0x8000000000000000, + "no parent, sampling on", + attributes={"sampled": "true"}, + trace_state=trace_state, + ) + self.assertTrue(sampled_result.decision.is_sampled()) + self.assertEqual(sampled_result.attributes, {"sampled": "true"}) + self.assertEqual(sampled_result.trace_state, trace_state) - # root span always sampled for parentbased - context = trace.set_span_in_context(trace.INVALID_SPAN) - sampler3 = sampling.ParentBased(sampling.ALWAYS_OFF) - self.assertTrue( - sampler3.should_sample( - context, 0x8000000000000000, 0xDEADBEEF, "span name", - ).decision.is_sampled() - ) + def test_parent_based_explicit_parent_context(self): + @contextlib.contextmanager + def explicit_parent_context(span: trace.Span): + yield trace.set_span_in_context(span) + + self.exec_parent_based(explicit_parent_context) + + def test_parent_based_implicit_parent_context(self): + @contextlib.contextmanager + def implicit_parent_context(span: trace.Span): + token = context_api.attach(trace.set_span_in_context(span)) + yield None + context_api.detach(token) + + self.exec_parent_based(implicit_parent_context) diff --git a/tests/util/setup.cfg b/tests/util/setup.cfg index 6d261009635..c788346791c 100644 --- a/tests/util/setup.cfg +++ b/tests/util/setup.cfg @@ -37,8 +37,8 @@ package_dir= =src packages=find_namespace: install_requires = - opentelemetry-api == 0.16.dev0 - opentelemetry-sdk == 0.16.dev0 + opentelemetry-api == 0.17.dev0 + opentelemetry-sdk == 0.17.dev0 [options.extras_require] test = flask~=1.0 diff --git a/tests/util/src/opentelemetry/test/version.py b/tests/util/src/opentelemetry/test/version.py index 4c4951dcda1..da85ff96db1 100644 --- a/tests/util/src/opentelemetry/test/version.py +++ b/tests/util/src/opentelemetry/test/version.py @@ -1 +1 @@ -__version__ = "0.16.dev0" +__version__ = "0.17.dev0"