Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package 
python-opentelemetry-exporter-otlp-proto-common for openSUSE:Factory checked in 
at 2025-01-09 15:09:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing 
/work/SRC/openSUSE:Factory/python-opentelemetry-exporter-otlp-proto-common (Old)
 and      
/work/SRC/openSUSE:Factory/.python-opentelemetry-exporter-otlp-proto-common.new.1881
 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-opentelemetry-exporter-otlp-proto-common"

Thu Jan  9 15:09:51 2025 rev:8 rq:1235917 version:1.29.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-opentelemetry-exporter-otlp-proto-common/python-opentelemetry-exporter-otlp-proto-common.changes
  2024-09-05 15:48:18.470862227 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-opentelemetry-exporter-otlp-proto-common.new.1881/python-opentelemetry-exporter-otlp-proto-common.changes
        2025-01-09 15:11:30.070415085 +0100
@@ -1,0 +2,31 @@
+Wed Jan  8 10:15:49 UTC 2025 - John Paul Adrian Glaubitz 
<adrian.glaub...@suse.com>
+
+- Update to 1.29.0
+  * Fix crash exporting a log record with None body
+  * Fix metrics export with exemplar and no context and filtering observable 
instruments
+  * Fix recursion error with sdk disabled and handler added to root logger
+  * sdk: setup EventLogger when 
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED is set
+  * api: fix logging of duplicate EventLogger setup warning
+  * sdk: fix setting of process owner in ProcessResourceDetector
+  * sdk: fix serialization of logs severity_number field to int
+  * Remove `TestBase.assertEqualSpanInstrumentationInfo` method,
+    use `assertEqualSpanInstrumentationScope` instead
+  * sdk: instantiate lazily `ExemplarBucket`s in `ExemplarReservoir`s
+  * semantic-conventions: Bump to 1.29.0
+- from version 1.28.0
+  * Removed superfluous py.typed markers and added them where they were missing
+  * Include metric info in encoding exceptions
+  * sdk: Add support for log formatting
+  * sdk: Add Host resource detector
+  * sdk: Implementation of exemplars
+  * Implement events sdk
+  * Update semantic conventions to version 1.28.0
+  * Add support to protobuf 5+ and drop support to protobuf 3 and 4
+  * Update environment variable descriptions to match signal
+  * Record logger name as the instrumentation scope name
+  * Fix memory leak in exporter and reader
+  * Drop `OTEL_PYTHON_EXPERIMENTAL_DISABLE_PROMETHEUS_UNIT_NORMALIZATION` 
environment variable
+  * Improve compatibility with other logging libraries that override
+    `LogRecord.getMessage()` in order to customize message formatting
+
+-------------------------------------------------------------------

Old:
----
  opentelemetry_exporter_otlp_proto_common-1.27.0.tar.gz

New:
----
  opentelemetry_exporter_otlp_proto_common-1.29.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-opentelemetry-exporter-otlp-proto-common.spec ++++++
--- /var/tmp/diff_new_pack.Fycx1L/_old  2025-01-09 15:11:30.530434141 +0100
+++ /var/tmp/diff_new_pack.Fycx1L/_new  2025-01-09 15:11:30.530434141 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-opentelemetry-exporter-otlp-proto-common
 #
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2025 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-opentelemetry-exporter-otlp-proto-common
-Version:        1.27.0
+Version:        1.29.0
 Release:        0
 Summary:        OpenTelemetry Protobuf encoding
 License:        Apache-2.0

++++++ opentelemetry_exporter_otlp_proto_common-1.27.0.tar.gz -> 
opentelemetry_exporter_otlp_proto_common-1.29.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/PKG-INFO 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/PKG-INFO
--- old/opentelemetry_exporter_otlp_proto_common-1.27.0/PKG-INFO        
2020-02-02 01:00:00.000000000 +0100
+++ new/opentelemetry_exporter_otlp_proto_common-1.29.0/PKG-INFO        
2020-02-02 01:00:00.000000000 +0100
@@ -1,11 +1,10 @@
 Metadata-Version: 2.3
 Name: opentelemetry-exporter-otlp-proto-common
-Version: 1.27.0
+Version: 1.29.0
 Summary: OpenTelemetry Protobuf encoding
 Project-URL: Homepage, 
https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-proto-common
 Author-email: OpenTelemetry Authors 
<cncf-opentelemetry-contribut...@lists.cncf.io>
 License: Apache-2.0
-License-File: LICENSE
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Framework :: OpenTelemetry
 Classifier: Framework :: OpenTelemetry :: Exporters
@@ -19,7 +18,7 @@
 Classifier: Programming Language :: Python :: 3.11
 Classifier: Programming Language :: Python :: 3.12
 Requires-Python: >=3.8
-Requires-Dist: opentelemetry-proto==1.27.0
+Requires-Dist: opentelemetry-proto==1.29.0
 Description-Content-Type: text/x-rst
 
 OpenTelemetry Protobuf Encoding
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/pyproject.toml 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/pyproject.toml
--- old/opentelemetry_exporter_otlp_proto_common-1.27.0/pyproject.toml  
2020-02-02 01:00:00.000000000 +0100
+++ new/opentelemetry_exporter_otlp_proto_common-1.29.0/pyproject.toml  
2020-02-02 01:00:00.000000000 +0100
@@ -27,14 +27,14 @@
   "Programming Language :: Python :: 3.12",
 ]
 dependencies = [
-  "opentelemetry-proto == 1.27.0",
+  "opentelemetry-proto == 1.29.0",
 ]
 
 [project.urls]
 Homepage = 
"https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-proto-common";
 
 [tool.hatch.version]
-path = "src/opentelemetry/exporter/otlp/proto/common/version.py"
+path = "src/opentelemetry/exporter/otlp/proto/common/version/__init__.py"
 
 [tool.hatch.build.targets.sdist]
 include = [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py
 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py
--- 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py
      2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py
      2020-02-02 01:00:00.000000000 +0100
@@ -18,31 +18,31 @@
 from itertools import count
 from typing import (
     Any,
-    Mapping,
-    Optional,
-    List,
     Callable,
-    TypeVar,
     Dict,
     Iterator,
+    List,
+    Mapping,
+    Optional,
+    TypeVar,
 )
 
-from opentelemetry.sdk.util.instrumentation import InstrumentationScope
+from opentelemetry.proto.common.v1.common_pb2 import AnyValue as PB2AnyValue
 from opentelemetry.proto.common.v1.common_pb2 import (
-    InstrumentationScope as PB2InstrumentationScope,
+    ArrayValue as PB2ArrayValue,
 )
-from opentelemetry.proto.resource.v1.resource_pb2 import (
-    Resource as PB2Resource,
+from opentelemetry.proto.common.v1.common_pb2 import (
+    InstrumentationScope as PB2InstrumentationScope,
 )
-from opentelemetry.proto.common.v1.common_pb2 import AnyValue as PB2AnyValue
 from opentelemetry.proto.common.v1.common_pb2 import KeyValue as PB2KeyValue
 from opentelemetry.proto.common.v1.common_pb2 import (
     KeyValueList as PB2KeyValueList,
 )
-from opentelemetry.proto.common.v1.common_pb2 import (
-    ArrayValue as PB2ArrayValue,
+from opentelemetry.proto.resource.v1.resource_pb2 import (
+    Resource as PB2Resource,
 )
 from opentelemetry.sdk.trace import Resource
+from opentelemetry.sdk.util.instrumentation import InstrumentationScope
 from opentelemetry.util.types import Attributes
 
 _logger = logging.getLogger(__name__)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/src/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py
 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/src/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py
--- 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/src/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py
 2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/src/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py
 2020-02-02 01:00:00.000000000 +0100
@@ -12,25 +12,24 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 from collections import defaultdict
-from typing import Sequence, List
+from typing import List, Sequence
 
 from opentelemetry.exporter.otlp.proto.common._internal import (
+    _encode_attributes,
     _encode_instrumentation_scope,
     _encode_resource,
     _encode_span_id,
     _encode_trace_id,
     _encode_value,
-    _encode_attributes,
 )
 from opentelemetry.proto.collector.logs.v1.logs_service_pb2 import (
     ExportLogsServiceRequest,
 )
+from opentelemetry.proto.logs.v1.logs_pb2 import LogRecord as PB2LogRecord
 from opentelemetry.proto.logs.v1.logs_pb2 import (
-    ScopeLogs,
     ResourceLogs,
+    ScopeLogs,
 )
-from opentelemetry.proto.logs.v1.logs_pb2 import LogRecord as PB2LogRecord
-
 from opentelemetry.sdk._logs import LogData
 
 
@@ -49,13 +48,14 @@
         if log_data.log_record.trace_id == 0
         else _encode_trace_id(log_data.log_record.trace_id)
     )
+    body = log_data.log_record.body
     return PB2LogRecord(
         time_unix_nano=log_data.log_record.timestamp,
         observed_time_unix_nano=log_data.log_record.observed_timestamp,
         span_id=span_id,
         trace_id=trace_id,
         flags=int(log_data.log_record.trace_flags),
-        body=_encode_value(log_data.log_record.body),
+        body=_encode_value(body) if body is not None else None,
         severity_text=log_data.log_record.severity_text,
         attributes=_encode_attributes(log_data.log_record.attributes),
         dropped_attributes_count=log_data.log_record.dropped_attributes,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/src/opentelemetry/exporter/otlp/proto/common/_internal/metrics_encoder/__init__.py
 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/src/opentelemetry/exporter/otlp/proto/common/_internal/metrics_encoder/__init__.py
--- 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/src/opentelemetry/exporter/otlp/proto/common/_internal/metrics_encoder/__init__.py
      2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/src/opentelemetry/exporter/otlp/proto/common/_internal/metrics_encoder/__init__.py
      2020-02-02 01:00:00.000000000 +0100
@@ -12,51 +12,52 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 import logging
+from os import environ
+from typing import Dict, List
 
-from opentelemetry.sdk.metrics.export import (
-    MetricExporter,
+from opentelemetry.exporter.otlp.proto.common._internal import (
+    _encode_attributes,
+    _encode_span_id,
+    _encode_trace_id,
+)
+from opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import (
+    ExportMetricsServiceRequest,
+)
+from opentelemetry.proto.common.v1.common_pb2 import InstrumentationScope
+from opentelemetry.proto.metrics.v1 import metrics_pb2 as pb2
+from opentelemetry.proto.resource.v1.resource_pb2 import (
+    Resource as PB2Resource,
+)
+from opentelemetry.sdk.environment_variables import (
+    OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION,
+    OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE,
 )
-from opentelemetry.sdk.metrics.view import Aggregation
-from os import environ
 from opentelemetry.sdk.metrics import (
     Counter,
+    Exemplar,
     Histogram,
     ObservableCounter,
     ObservableGauge,
     ObservableUpDownCounter,
     UpDownCounter,
 )
-from opentelemetry.exporter.otlp.proto.common._internal import (
-    _encode_attributes,
-)
-from opentelemetry.sdk.environment_variables import (
-    OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE,
-)
 from opentelemetry.sdk.metrics.export import (
     AggregationTemporality,
-)
-from opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import (
-    ExportMetricsServiceRequest,
-)
-from opentelemetry.proto.common.v1.common_pb2 import InstrumentationScope
-from opentelemetry.proto.metrics.v1 import metrics_pb2 as pb2
-from opentelemetry.sdk.metrics.export import (
-    MetricsData,
     Gauge,
-    Histogram as HistogramType,
+    MetricExporter,
+    MetricsData,
     Sum,
-    ExponentialHistogram as ExponentialHistogramType,
 )
-from typing import Dict
-from opentelemetry.proto.resource.v1.resource_pb2 import (
-    Resource as PB2Resource,
+from opentelemetry.sdk.metrics.export import (
+    ExponentialHistogram as ExponentialHistogramType,
 )
-from opentelemetry.sdk.environment_variables import (
-    OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION,
+from opentelemetry.sdk.metrics.export import (
+    Histogram as HistogramType,
 )
 from opentelemetry.sdk.metrics.view import (
-    ExponentialBucketHistogramAggregation,
+    Aggregation,
     ExplicitBucketHistogramAggregation,
+    ExponentialBucketHistogramAggregation,
 )
 
 _logger = logging.getLogger(__name__)
@@ -68,7 +69,6 @@
         preferred_temporality: Dict[type, AggregationTemporality] = None,
         preferred_aggregation: Dict[type, Aggregation] = None,
     ) -> None:
-
         MetricExporter.__init__(
             self,
             preferred_temporality=self._get_temporality(preferred_temporality),
@@ -78,7 +78,6 @@
     def _get_temporality(
         self, preferred_temporality: Dict[type, AggregationTemporality]
     ) -> Dict[type, AggregationTemporality]:
-
         otel_exporter_otlp_metrics_temporality_preference = (
             environ.get(
                 OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE,
@@ -135,7 +134,6 @@
         self,
         preferred_aggregation: Dict[type, Aggregation],
     ) -> Dict[type, Aggregation]:
-
         otel_exporter_otlp_metrics_default_histogram_aggregation = environ.get(
             OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION,
             "explicit_bucket_histogram",
@@ -144,17 +142,14 @@
         if otel_exporter_otlp_metrics_default_histogram_aggregation == (
             "base2_exponential_bucket_histogram"
         ):
-
             instrument_class_aggregation = {
                 Histogram: ExponentialBucketHistogramAggregation(),
             }
 
         else:
-
             if otel_exporter_otlp_metrics_default_histogram_aggregation != (
                 "explicit_bucket_histogram"
             ):
-
                 _logger.warning(
                     (
                         "Invalid value for %s: %s, using explicit bucket "
@@ -173,152 +168,26 @@
         return instrument_class_aggregation
 
 
-def encode_metrics(data: MetricsData) -> ExportMetricsServiceRequest:
-    resource_metrics_dict = {}
-
-    for resource_metrics in data.resource_metrics:
-
-        resource = resource_metrics.resource
-
-        # It is safe to assume that each entry in data.resource_metrics is
-        # associated with an unique resource.
-        scope_metrics_dict = {}
-
-        resource_metrics_dict[resource] = scope_metrics_dict
-
-        for scope_metrics in resource_metrics.scope_metrics:
-
-            instrumentation_scope = scope_metrics.scope
-
-            # The SDK groups metrics in instrumentation scopes already so
-            # there is no need to check for existing instrumentation scopes
-            # here.
-            pb2_scope_metrics = pb2.ScopeMetrics(
-                scope=InstrumentationScope(
-                    name=instrumentation_scope.name,
-                    version=instrumentation_scope.version,
-                )
-            )
+class EncodingException(Exception):
+    """
+    Raised by encode_metrics() when an exception is caught during encoding. 
Contains the problematic metric so
+    the misbehaving metric name and details can be logged during exception 
handling.
+    """
+
+    def __init__(self, original_exception, metric):
+        super().__init__()
+        self.original_exception = original_exception
+        self.metric = metric
 
-            scope_metrics_dict[instrumentation_scope] = pb2_scope_metrics
+    def __str__(self):
+        return f"{self.metric}\n{self.original_exception}"
 
-            for metric in scope_metrics.metrics:
-                pb2_metric = pb2.Metric(
-                    name=metric.name,
-                    description=metric.description,
-                    unit=metric.unit,
-                )
 
-                if isinstance(metric.data, Gauge):
-                    for data_point in metric.data.data_points:
-                        pt = pb2.NumberDataPoint(
-                            attributes=_encode_attributes(
-                                data_point.attributes
-                            ),
-                            time_unix_nano=data_point.time_unix_nano,
-                        )
-                        if isinstance(data_point.value, int):
-                            pt.as_int = data_point.value
-                        else:
-                            pt.as_double = data_point.value
-                        pb2_metric.gauge.data_points.append(pt)
-
-                elif isinstance(metric.data, HistogramType):
-                    for data_point in metric.data.data_points:
-                        pt = pb2.HistogramDataPoint(
-                            attributes=_encode_attributes(
-                                data_point.attributes
-                            ),
-                            time_unix_nano=data_point.time_unix_nano,
-                            start_time_unix_nano=(
-                                data_point.start_time_unix_nano
-                            ),
-                            count=data_point.count,
-                            sum=data_point.sum,
-                            bucket_counts=data_point.bucket_counts,
-                            explicit_bounds=data_point.explicit_bounds,
-                            max=data_point.max,
-                            min=data_point.min,
-                        )
-                        pb2_metric.histogram.aggregation_temporality = (
-                            metric.data.aggregation_temporality
-                        )
-                        pb2_metric.histogram.data_points.append(pt)
-
-                elif isinstance(metric.data, Sum):
-                    for data_point in metric.data.data_points:
-                        pt = pb2.NumberDataPoint(
-                            attributes=_encode_attributes(
-                                data_point.attributes
-                            ),
-                            start_time_unix_nano=(
-                                data_point.start_time_unix_nano
-                            ),
-                            time_unix_nano=data_point.time_unix_nano,
-                        )
-                        if isinstance(data_point.value, int):
-                            pt.as_int = data_point.value
-                        else:
-                            pt.as_double = data_point.value
-                        # note that because sum is a message type, the
-                        # fields must be set individually rather than
-                        # instantiating a pb2.Sum and setting it once
-                        pb2_metric.sum.aggregation_temporality = (
-                            metric.data.aggregation_temporality
-                        )
-                        pb2_metric.sum.is_monotonic = metric.data.is_monotonic
-                        pb2_metric.sum.data_points.append(pt)
-
-                elif isinstance(metric.data, ExponentialHistogramType):
-                    for data_point in metric.data.data_points:
-
-                        if data_point.positive.bucket_counts:
-                            positive = 
pb2.ExponentialHistogramDataPoint.Buckets(
-                                offset=data_point.positive.offset,
-                                
bucket_counts=data_point.positive.bucket_counts,
-                            )
-                        else:
-                            positive = None
-
-                        if data_point.negative.bucket_counts:
-                            negative = 
pb2.ExponentialHistogramDataPoint.Buckets(
-                                offset=data_point.negative.offset,
-                                
bucket_counts=data_point.negative.bucket_counts,
-                            )
-                        else:
-                            negative = None
-
-                        pt = pb2.ExponentialHistogramDataPoint(
-                            attributes=_encode_attributes(
-                                data_point.attributes
-                            ),
-                            time_unix_nano=data_point.time_unix_nano,
-                            start_time_unix_nano=(
-                                data_point.start_time_unix_nano
-                            ),
-                            count=data_point.count,
-                            sum=data_point.sum,
-                            scale=data_point.scale,
-                            zero_count=data_point.zero_count,
-                            positive=positive,
-                            negative=negative,
-                            flags=data_point.flags,
-                            max=data_point.max,
-                            min=data_point.min,
-                        )
-                        
pb2_metric.exponential_histogram.aggregation_temporality = (
-                            metric.data.aggregation_temporality
-                        )
-                        pb2_metric.exponential_histogram.data_points.append(pt)
-
-                else:
-                    _logger.warning(
-                        "unsupported data type %s",
-                        metric.data.__class__.__name__,
-                    )
-                    continue
+def encode_metrics(data: MetricsData) -> ExportMetricsServiceRequest:
+    resource_metrics_dict = {}
 
-                pb2_scope_metrics.metrics.append(pb2_metric)
+    for resource_metrics in data.resource_metrics:
+        _encode_resource_metrics(resource_metrics, resource_metrics_dict)
 
     resource_data = []
     for (
@@ -334,5 +203,184 @@
                 schema_url=sdk_resource.schema_url,
             )
         )
-    resource_metrics = resource_data
-    return ExportMetricsServiceRequest(resource_metrics=resource_metrics)
+    return ExportMetricsServiceRequest(resource_metrics=resource_data)
+
+
+def _encode_resource_metrics(resource_metrics, resource_metrics_dict):
+    resource = resource_metrics.resource
+    # It is safe to assume that each entry in data.resource_metrics is
+    # associated with an unique resource.
+    scope_metrics_dict = {}
+    resource_metrics_dict[resource] = scope_metrics_dict
+    for scope_metrics in resource_metrics.scope_metrics:
+        instrumentation_scope = scope_metrics.scope
+
+        # The SDK groups metrics in instrumentation scopes already so
+        # there is no need to check for existing instrumentation scopes
+        # here.
+        pb2_scope_metrics = pb2.ScopeMetrics(
+            scope=InstrumentationScope(
+                name=instrumentation_scope.name,
+                version=instrumentation_scope.version,
+            )
+        )
+
+        scope_metrics_dict[instrumentation_scope] = pb2_scope_metrics
+
+        for metric in scope_metrics.metrics:
+            pb2_metric = pb2.Metric(
+                name=metric.name,
+                description=metric.description,
+                unit=metric.unit,
+            )
+
+            try:
+                _encode_metric(metric, pb2_metric)
+            except Exception as ex:
+                # `from None` so we don't get "During handling of the above 
exception, another exception occurred:"
+                raise EncodingException(ex, metric) from None
+
+            pb2_scope_metrics.metrics.append(pb2_metric)
+
+
+def _encode_metric(metric, pb2_metric):
+    if isinstance(metric.data, Gauge):
+        for data_point in metric.data.data_points:
+            pt = pb2.NumberDataPoint(
+                attributes=_encode_attributes(data_point.attributes),
+                time_unix_nano=data_point.time_unix_nano,
+                exemplars=_encode_exemplars(data_point.exemplars),
+            )
+            if isinstance(data_point.value, int):
+                pt.as_int = data_point.value
+            else:
+                pt.as_double = data_point.value
+            pb2_metric.gauge.data_points.append(pt)
+
+    elif isinstance(metric.data, HistogramType):
+        for data_point in metric.data.data_points:
+            pt = pb2.HistogramDataPoint(
+                attributes=_encode_attributes(data_point.attributes),
+                time_unix_nano=data_point.time_unix_nano,
+                start_time_unix_nano=data_point.start_time_unix_nano,
+                exemplars=_encode_exemplars(data_point.exemplars),
+                count=data_point.count,
+                sum=data_point.sum,
+                bucket_counts=data_point.bucket_counts,
+                explicit_bounds=data_point.explicit_bounds,
+                max=data_point.max,
+                min=data_point.min,
+            )
+            pb2_metric.histogram.aggregation_temporality = (
+                metric.data.aggregation_temporality
+            )
+            pb2_metric.histogram.data_points.append(pt)
+
+    elif isinstance(metric.data, Sum):
+        for data_point in metric.data.data_points:
+            pt = pb2.NumberDataPoint(
+                attributes=_encode_attributes(data_point.attributes),
+                start_time_unix_nano=data_point.start_time_unix_nano,
+                time_unix_nano=data_point.time_unix_nano,
+                exemplars=_encode_exemplars(data_point.exemplars),
+            )
+            if isinstance(data_point.value, int):
+                pt.as_int = data_point.value
+            else:
+                pt.as_double = data_point.value
+            # note that because sum is a message type, the
+            # fields must be set individually rather than
+            # instantiating a pb2.Sum and setting it once
+            pb2_metric.sum.aggregation_temporality = (
+                metric.data.aggregation_temporality
+            )
+            pb2_metric.sum.is_monotonic = metric.data.is_monotonic
+            pb2_metric.sum.data_points.append(pt)
+
+    elif isinstance(metric.data, ExponentialHistogramType):
+        for data_point in metric.data.data_points:
+            if data_point.positive.bucket_counts:
+                positive = pb2.ExponentialHistogramDataPoint.Buckets(
+                    offset=data_point.positive.offset,
+                    bucket_counts=data_point.positive.bucket_counts,
+                )
+            else:
+                positive = None
+
+            if data_point.negative.bucket_counts:
+                negative = pb2.ExponentialHistogramDataPoint.Buckets(
+                    offset=data_point.negative.offset,
+                    bucket_counts=data_point.negative.bucket_counts,
+                )
+            else:
+                negative = None
+
+            pt = pb2.ExponentialHistogramDataPoint(
+                attributes=_encode_attributes(data_point.attributes),
+                time_unix_nano=data_point.time_unix_nano,
+                start_time_unix_nano=data_point.start_time_unix_nano,
+                exemplars=_encode_exemplars(data_point.exemplars),
+                count=data_point.count,
+                sum=data_point.sum,
+                scale=data_point.scale,
+                zero_count=data_point.zero_count,
+                positive=positive,
+                negative=negative,
+                flags=data_point.flags,
+                max=data_point.max,
+                min=data_point.min,
+            )
+            pb2_metric.exponential_histogram.aggregation_temporality = (
+                metric.data.aggregation_temporality
+            )
+            pb2_metric.exponential_histogram.data_points.append(pt)
+
+    else:
+        _logger.warning(
+            "unsupported data type %s",
+            metric.data.__class__.__name__,
+        )
+
+
+def _encode_exemplars(sdk_exemplars: List[Exemplar]) -> List[pb2.Exemplar]:
+    """
+    Converts a list of SDK Exemplars into a list of protobuf Exemplars.
+
+    Args:
+        sdk_exemplars (list): The list of exemplars from the OpenTelemetry SDK.
+
+    Returns:
+        list: A list of protobuf exemplars.
+    """
+    pb_exemplars = []
+    for sdk_exemplar in sdk_exemplars:
+        if (
+            sdk_exemplar.span_id is not None
+            and sdk_exemplar.trace_id is not None
+        ):
+            pb_exemplar = pb2.Exemplar(
+                time_unix_nano=sdk_exemplar.time_unix_nano,
+                span_id=_encode_span_id(sdk_exemplar.span_id),
+                trace_id=_encode_trace_id(sdk_exemplar.trace_id),
+                filtered_attributes=_encode_attributes(
+                    sdk_exemplar.filtered_attributes
+                ),
+            )
+        else:
+            pb_exemplar = pb2.Exemplar(
+                time_unix_nano=sdk_exemplar.time_unix_nano,
+                filtered_attributes=_encode_attributes(
+                    sdk_exemplar.filtered_attributes
+                ),
+            )
+
+        # Assign the value based on its type in the SDK exemplar
+        if isinstance(sdk_exemplar.value, float):
+            pb_exemplar.as_double = sdk_exemplar.value
+        elif isinstance(sdk_exemplar.value, int):
+            pb_exemplar.as_int = sdk_exemplar.value
+        else:
+            raise ValueError("Exemplar value must be an int or float")
+        pb_exemplars.append(pb_exemplar)
+
+    return pb_exemplars
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/src/opentelemetry/exporter/otlp/proto/common/version/__init__.py
 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/src/opentelemetry/exporter/otlp/proto/common/version/__init__.py
--- 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/src/opentelemetry/exporter/otlp/proto/common/version/__init__.py
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/src/opentelemetry/exporter/otlp/proto/common/version/__init__.py
        2020-02-02 01:00:00.000000000 +0100
@@ -0,0 +1,15 @@
+# Copyright The OpenTelemetry Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+__version__ = "1.29.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/src/opentelemetry/exporter/otlp/proto/common/version.py
 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/src/opentelemetry/exporter/otlp/proto/common/version.py
--- 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/src/opentelemetry/exporter/otlp/proto/common/version.py
 2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/src/opentelemetry/exporter/otlp/proto/common/version.py
 1970-01-01 01:00:00.000000000 +0100
@@ -1,15 +0,0 @@
-# Copyright The OpenTelemetry Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-__version__ = "1.27.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/tests/test_log_encoder.py 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/tests/test_log_encoder.py
--- 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/tests/test_log_encoder.py   
    2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/tests/test_log_encoder.py   
    2020-02-02 01:00:00.000000000 +0100
@@ -51,6 +51,18 @@
         sdk_logs, expected_encoding = self.get_test_logs()
         self.assertEqual(encode_logs(sdk_logs), expected_encoding)
 
+    def test_encode_no_body(self):
+        sdk_logs, expected_encoding = self.get_test_logs()
+        for log in sdk_logs:
+            log.log_record.body = None
+
+        for resource_log in expected_encoding.resource_logs:
+            for scope_log in resource_log.scope_logs:
+                for log_record in scope_log.log_records:
+                    log_record.ClearField("body")
+
+        self.assertEqual(encode_logs(sdk_logs), expected_encoding)
+
     def test_dropped_attributes_count(self):
         sdk_logs = self._get_test_logs_dropped_attributes()
         encoded_logs = encode_logs(sdk_logs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/tests/test_metrics_encoder.py
 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/tests/test_metrics_encoder.py
--- 
old/opentelemetry_exporter_otlp_proto_common-1.27.0/tests/test_metrics_encoder.py
   2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_common-1.29.0/tests/test_metrics_encoder.py
   2020-02-02 01:00:00.000000000 +0100
@@ -12,9 +12,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# pylint: disable=protected-access
+# pylint: disable=protected-access,too-many-lines
 import unittest
 
+from opentelemetry.exporter.otlp.proto.common._internal.metrics_encoder import 
(
+    EncodingException,
+)
 from opentelemetry.exporter.otlp.proto.common.metrics_encoder import (
     encode_metrics,
 )
@@ -30,19 +33,21 @@
 from opentelemetry.proto.resource.v1.resource_pb2 import (
     Resource as OTLPResource,
 )
-from opentelemetry.sdk.metrics.export import AggregationTemporality, Buckets
-from opentelemetry.sdk.metrics.export import (
-    ExponentialHistogram as ExponentialHistogramType,
-)
-from opentelemetry.sdk.metrics.export import ExponentialHistogramDataPoint
-from opentelemetry.sdk.metrics.export import Histogram as HistogramType
+from opentelemetry.sdk.metrics import Exemplar
 from opentelemetry.sdk.metrics.export import (
+    AggregationTemporality,
+    Buckets,
+    ExponentialHistogramDataPoint,
     HistogramDataPoint,
     Metric,
     MetricsData,
     ResourceMetrics,
     ScopeMetrics,
 )
+from opentelemetry.sdk.metrics.export import (
+    ExponentialHistogram as ExponentialHistogramType,
+)
+from opentelemetry.sdk.metrics.export import Histogram as HistogramType
 from opentelemetry.sdk.resources import Resource
 from opentelemetry.sdk.util.instrumentation import (
     InstrumentationScope as SDKInstrumentationScope,
@@ -51,6 +56,9 @@
 
 
 class TestOTLPMetricsEncoder(unittest.TestCase):
+    span_id = int("6e0c63257de34c92", 16)
+    trace_id = int("d4cda95b652f4a1592b449d5929fda1b", 16)
+
     histogram = Metric(
         name="histogram",
         description="foo",
@@ -61,6 +69,22 @@
                     attributes={"a": 1, "b": True},
                     start_time_unix_nano=1641946016139533244,
                     time_unix_nano=1641946016139533244,
+                    exemplars=[
+                        Exemplar(
+                            {"filtered": "banana"},
+                            298.0,
+                            1641946016139533400,
+                            span_id,
+                            trace_id,
+                        ),
+                        Exemplar(
+                            {"filtered": "banana"},
+                            298.0,
+                            1641946016139533400,
+                            None,
+                            None,
+                        ),
+                    ],
                     count=5,
                     sum=67,
                     bucket_counts=[1, 4],
@@ -456,7 +480,34 @@
                                                 sum=67,
                                                 bucket_counts=[1, 4],
                                                 explicit_bounds=[10.0, 20.0],
-                                                exemplars=[],
+                                                exemplars=[
+                                                    pb2.Exemplar(
+                                                        
time_unix_nano=1641946016139533400,
+                                                        as_double=298,
+                                                        
span_id=b"n\x0cc%}\xe3L\x92",
+                                                        
trace_id=b"\xd4\xcd\xa9[e/J\x15\x92\xb4I\xd5\x92\x9f\xda\x1b",
+                                                        filtered_attributes=[
+                                                            KeyValue(
+                                                                key="filtered",
+                                                                value=AnyValue(
+                                                                    
string_value="banana"
+                                                                ),
+                                                            )
+                                                        ],
+                                                    ),
+                                                    pb2.Exemplar(
+                                                        
time_unix_nano=1641946016139533400,
+                                                        as_double=298,
+                                                        filtered_attributes=[
+                                                            KeyValue(
+                                                                key="filtered",
+                                                                value=AnyValue(
+                                                                    
string_value="banana"
+                                                                ),
+                                                            )
+                                                        ],
+                                                    ),
+                                                ],
                                                 max=18.0,
                                                 min=8.0,
                                             )
@@ -559,7 +610,34 @@
                                                 sum=67,
                                                 bucket_counts=[1, 4],
                                                 explicit_bounds=[10.0, 20.0],
-                                                exemplars=[],
+                                                exemplars=[
+                                                    pb2.Exemplar(
+                                                        
time_unix_nano=1641946016139533400,
+                                                        as_double=298,
+                                                        
span_id=b"n\x0cc%}\xe3L\x92",
+                                                        
trace_id=b"\xd4\xcd\xa9[e/J\x15\x92\xb4I\xd5\x92\x9f\xda\x1b",
+                                                        filtered_attributes=[
+                                                            KeyValue(
+                                                                key="filtered",
+                                                                value=AnyValue(
+                                                                    
string_value="banana"
+                                                                ),
+                                                            )
+                                                        ],
+                                                    ),
+                                                    pb2.Exemplar(
+                                                        
time_unix_nano=1641946016139533400,
+                                                        as_double=298,
+                                                        filtered_attributes=[
+                                                            KeyValue(
+                                                                key="filtered",
+                                                                value=AnyValue(
+                                                                    
string_value="banana"
+                                                                ),
+                                                            )
+                                                        ],
+                                                    ),
+                                                ],
                                                 max=18.0,
                                                 min=8.0,
                                             )
@@ -594,7 +672,34 @@
                                                 sum=67,
                                                 bucket_counts=[1, 4],
                                                 explicit_bounds=[10.0, 20.0],
-                                                exemplars=[],
+                                                exemplars=[
+                                                    pb2.Exemplar(
+                                                        
time_unix_nano=1641946016139533400,
+                                                        as_double=298,
+                                                        
span_id=b"n\x0cc%}\xe3L\x92",
+                                                        
trace_id=b"\xd4\xcd\xa9[e/J\x15\x92\xb4I\xd5\x92\x9f\xda\x1b",
+                                                        filtered_attributes=[
+                                                            KeyValue(
+                                                                key="filtered",
+                                                                value=AnyValue(
+                                                                    
string_value="banana"
+                                                                ),
+                                                            )
+                                                        ],
+                                                    ),
+                                                    pb2.Exemplar(
+                                                        
time_unix_nano=1641946016139533400,
+                                                        as_double=298,
+                                                        filtered_attributes=[
+                                                            KeyValue(
+                                                                key="filtered",
+                                                                value=AnyValue(
+                                                                    
string_value="banana"
+                                                                ),
+                                                            )
+                                                        ],
+                                                    ),
+                                                ],
                                                 max=18.0,
                                                 min=8.0,
                                             )
@@ -636,7 +741,34 @@
                                                 sum=67,
                                                 bucket_counts=[1, 4],
                                                 explicit_bounds=[10.0, 20.0],
-                                                exemplars=[],
+                                                exemplars=[
+                                                    pb2.Exemplar(
+                                                        
time_unix_nano=1641946016139533400,
+                                                        as_double=298,
+                                                        
span_id=b"n\x0cc%}\xe3L\x92",
+                                                        
trace_id=b"\xd4\xcd\xa9[e/J\x15\x92\xb4I\xd5\x92\x9f\xda\x1b",
+                                                        filtered_attributes=[
+                                                            KeyValue(
+                                                                key="filtered",
+                                                                value=AnyValue(
+                                                                    
string_value="banana"
+                                                                ),
+                                                            )
+                                                        ],
+                                                    ),
+                                                    pb2.Exemplar(
+                                                        
time_unix_nano=1641946016139533400,
+                                                        as_double=298,
+                                                        filtered_attributes=[
+                                                            KeyValue(
+                                                                key="filtered",
+                                                                value=AnyValue(
+                                                                    
string_value="banana"
+                                                                ),
+                                                            )
+                                                        ],
+                                                    ),
+                                                ],
                                                 max=18.0,
                                                 min=8.0,
                                             )
@@ -678,7 +810,34 @@
                                                 sum=67,
                                                 bucket_counts=[1, 4],
                                                 explicit_bounds=[10.0, 20.0],
-                                                exemplars=[],
+                                                exemplars=[
+                                                    pb2.Exemplar(
+                                                        
time_unix_nano=1641946016139533400,
+                                                        as_double=298,
+                                                        
span_id=b"n\x0cc%}\xe3L\x92",
+                                                        
trace_id=b"\xd4\xcd\xa9[e/J\x15\x92\xb4I\xd5\x92\x9f\xda\x1b",
+                                                        filtered_attributes=[
+                                                            KeyValue(
+                                                                key="filtered",
+                                                                value=AnyValue(
+                                                                    
string_value="banana"
+                                                                ),
+                                                            )
+                                                        ],
+                                                    ),
+                                                    pb2.Exemplar(
+                                                        
time_unix_nano=1641946016139533400,
+                                                        as_double=298,
+                                                        filtered_attributes=[
+                                                            KeyValue(
+                                                                key="filtered",
+                                                                value=AnyValue(
+                                                                    
string_value="banana"
+                                                                ),
+                                                            )
+                                                        ],
+                                                    ),
+                                                ],
                                                 max=18.0,
                                                 min=8.0,
                                             )
@@ -814,3 +973,35 @@
         # pylint: disable=protected-access
         actual = encode_metrics(metrics_data)
         self.assertEqual(expected, actual)
+
+    def test_encoding_exception_reraise(self):
+        # this number is too big to fit in a signed 64-bit proto field and 
causes a ValueError
+        big_number = 2**63
+        metrics_data = MetricsData(
+            resource_metrics=[
+                ResourceMetrics(
+                    resource=Resource(
+                        attributes={},
+                        schema_url="resource_schema_url",
+                    ),
+                    scope_metrics=[
+                        ScopeMetrics(
+                            scope=SDKInstrumentationScope(
+                                name="first_name",
+                                version="first_version",
+                                schema_url="insrumentation_scope_schema_url",
+                            ),
+                            metrics=[_generate_sum("sum_double", big_number)],
+                            schema_url="instrumentation_scope_schema_url",
+                        )
+                    ],
+                    schema_url="resource_schema_url",
+                )
+            ]
+        )
+        with self.assertRaises(EncodingException) as context:
+            encode_metrics(metrics_data)
+
+        # assert that the EncodingException wraps the metric and original 
exception
+        assert isinstance(context.exception.metric, Metric)
+        assert isinstance(context.exception.original_exception, ValueError)

Reply via email to