1414#
1515# This file has been modified from the original source code at
1616#
17- # https://github.com/open-telemetry/opentelemetry-python/tree/v1.26.0
17+ # https://github.com/open-telemetry/opentelemetry-python/tree/v1.33.1
1818#
1919# by Snowflake Inc.
2020
2121
22+ from __future__ import annotations
23+
2224import logging
2325from collections .abc import Sequence
2426from itertools import count
2527from typing import (
2628 Any ,
27- Mapping ,
28- Optional ,
29- List ,
3029 Callable ,
31- TypeVar ,
3230 Dict ,
3331 Iterator ,
32+ List ,
33+ Mapping ,
34+ Optional ,
35+ TypeVar ,
3436)
3537
36- from opentelemetry .sdk . util . instrumentation import InstrumentationScope
38+ from snowflake . telemetry . _internal . opentelemetry .proto . common . v1 . common_marshaler import AnyValue as PB2AnyValue
3739from snowflake .telemetry ._internal .opentelemetry .proto .common .v1 .common_marshaler import (
38- InstrumentationScope as PB2InstrumentationScope ,
40+ ArrayValue as PB2ArrayValue ,
3941)
40- from snowflake .telemetry ._internal .opentelemetry .proto .resource .v1 .resource_marshaler import (
41- Resource as PB2Resource ,
42+ from snowflake .telemetry ._internal .opentelemetry .proto .common .v1 .common_marshaler import (
43+ InstrumentationScope as PB2InstrumentationScope ,
4244)
43- from snowflake .telemetry ._internal .opentelemetry .proto .common .v1 .common_marshaler import AnyValue as PB2AnyValue
4445from snowflake .telemetry ._internal .opentelemetry .proto .common .v1 .common_marshaler import KeyValue as PB2KeyValue
4546from snowflake .telemetry ._internal .opentelemetry .proto .common .v1 .common_marshaler import (
4647 KeyValueList as PB2KeyValueList ,
4748)
48- from snowflake .telemetry ._internal .opentelemetry .proto .common .v1 .common_marshaler import (
49- ArrayValue as PB2ArrayValue ,
49+ from snowflake .telemetry ._internal .opentelemetry .proto .resource .v1 .resource_marshaler import (
50+ Resource as PB2Resource ,
5051)
5152from opentelemetry .sdk .trace import Resource
52- from opentelemetry .util .types import Attributes
53+ from opentelemetry .sdk .util .instrumentation import InstrumentationScope
54+ from opentelemetry .util .types import _ExtendedAttributes
5355
5456_logger = logging .getLogger (__name__ )
5557
@@ -65,14 +67,19 @@ def _encode_instrumentation_scope(
6567 return PB2InstrumentationScope (
6668 name = instrumentation_scope .name ,
6769 version = instrumentation_scope .version ,
70+ attributes = _encode_attributes (instrumentation_scope .attributes ),
6871 )
6972
7073
7174def _encode_resource (resource : Resource ) -> PB2Resource :
7275 return PB2Resource (attributes = _encode_attributes (resource .attributes ))
7376
7477
75- def _encode_value (value : Any ) -> PB2AnyValue :
78+ def _encode_value (
79+ value : Any , allow_null : bool = False
80+ ) -> Optional [PB2AnyValue ]:
81+ if allow_null is True and value is None :
82+ return None
7683 if isinstance (value , bool ):
7784 return PB2AnyValue (bool_value = value )
7885 if isinstance (value , str ):
@@ -81,21 +88,49 @@ def _encode_value(value: Any) -> PB2AnyValue:
8188 return PB2AnyValue (int_value = value )
8289 if isinstance (value , float ):
8390 return PB2AnyValue (double_value = value )
91+ if isinstance (value , bytes ):
92+ return PB2AnyValue (bytes_value = value )
8493 if isinstance (value , Sequence ):
8594 return PB2AnyValue (
86- array_value = PB2ArrayValue (values = [_encode_value (v ) for v in value ])
95+ array_value = PB2ArrayValue (
96+ values = _encode_array (value , allow_null = allow_null )
97+ )
8798 )
8899 elif isinstance (value , Mapping ):
89100 return PB2AnyValue (
90101 kvlist_value = PB2KeyValueList (
91- values = [_encode_key_value (str (k ), v ) for k , v in value .items ()]
102+ values = [
103+ _encode_key_value (str (k ), v , allow_null = allow_null )
104+ for k , v in value .items ()
105+ ]
92106 )
93107 )
94108 raise Exception (f"Invalid type { type (value )} of value { value } " )
95109
96110
97- def _encode_key_value (key : str , value : Any ) -> PB2KeyValue :
98- return PB2KeyValue (key = key , value = _encode_value (value ))
111+ def _encode_key_value (
112+ key : str , value : Any , allow_null : bool = False
113+ ) -> PB2KeyValue :
114+ return PB2KeyValue (
115+ key = key , value = _encode_value (value , allow_null = allow_null )
116+ )
117+
118+
119+ def _encode_array (
120+ array : Sequence [Any ], allow_null : bool = False
121+ ) -> Sequence [PB2AnyValue ]:
122+ if not allow_null :
123+ # Let the exception get raised by _encode_value()
124+ return [_encode_value (v , allow_null = allow_null ) for v in array ]
125+
126+ return [
127+ _encode_value (v , allow_null = allow_null )
128+ if v is not None
129+ # Use an empty AnyValue to represent None in an array. Behavior may change pending
130+ # https://github.com/open-telemetry/opentelemetry-specification/issues/4392
131+ else PB2AnyValue ()
132+ for v in array
133+ ]
99134
100135
101136def _encode_span_id (span_id : int ) -> bytes :
@@ -107,14 +142,17 @@ def _encode_trace_id(trace_id: int) -> bytes:
107142
108143
109144def _encode_attributes (
110- attributes : Attributes ,
145+ attributes : _ExtendedAttributes ,
146+ allow_null : bool = False ,
111147) -> Optional [List [PB2KeyValue ]]:
112148 if attributes :
113149 pb2_attributes = []
114150 for key , value in attributes .items ():
115151 # pylint: disable=broad-exception-caught
116152 try :
117- pb2_attributes .append (_encode_key_value (key , value ))
153+ pb2_attributes .append (
154+ _encode_key_value (key , value , allow_null = allow_null )
155+ )
118156 except Exception as error :
119157 _logger .exception ("Failed to encode key %s: %s" , key , error )
120158 else :
0 commit comments