@@ -23,81 +23,6 @@ class InstanaSpan(BasicSpan):
2323 stack = None
2424 synthetic = False
2525
26- def __init__ (self , tracer , operation_name = None , context = None , parent_id = None , tags = None , start_time = None ):
27- # Tag validation
28- filtered_tags = {}
29- if tags is not None :
30- for key in tags .keys ():
31- validated_key , validated_value = self ._validate_tag (key , tags [key ])
32- if validated_key is not None :
33- filtered_tags [validated_key ] = validated_value
34-
35- super (InstanaSpan , self ).__init__ (tracer , operation_name , context , parent_id , filtered_tags , start_time )
36-
37- def _validate_tag (self , key , value ):
38- """
39- This method will assure that <key> and <value> are valid to set as a tag.
40- If <value> fails the check, an attempt will be made to convert it into
41- something useful.
42-
43- On check failure, this method will return None values indicating that the tag is
44- not valid and could not be converted into something useful
45-
46- :param key: The tag key
47- :param value: The tag value
48- :return: Tuple (key, value)
49- """
50- validated_key = None
51- validated_value = None
52-
53- try :
54- # Tag keys must be some type of text or string type
55- if isinstance (key , (six .text_type , six .string_types )):
56- validated_key = key [0 :1024 ] # Max key length of 1024 characters
57-
58- if isinstance (value , (bool , float , int , list , dict , six .text_type , six .string_types )):
59- validated_value = value
60- else :
61- validated_value = self ._convert_tag_value (value )
62- else :
63- logger .debug ("(non-fatal) tag names must be strings. tag discarded for %s" , type (key ))
64- except Exception :
65- logger .debug ("instana.span._validate_tag: " , exc_info = True )
66-
67- return (validated_key , validated_value )
68-
69- def _convert_tag_value (self , value ):
70- final_value = None
71-
72- try :
73- final_value = repr (value )
74- except Exception :
75- final_value = "(non-fatal) span.set_tag: values must be one of these types: bool, float, int, list, " \
76- "set, str or alternatively support 'repr'. tag discarded"
77- logger .debug (final_value , exc_info = True )
78- return None
79- return final_value
80-
81- def set_tag (self , key , value ):
82- validated_key , validated_value = self ._validate_tag (key , value )
83-
84- if validated_key is not None and validated_value is not None :
85- return super (InstanaSpan , self ).set_tag (validated_key , validated_value )
86-
87- return self
88-
89- def log_kv (self , key_values , timestamp = None ):
90- validated_key = None
91- validated_value = None
92-
93- for key in key_values .keys ():
94- validated_key , validated_value = self ._validate_tag (key , key_values [key ])
95-
96- if validated_key is not None and validated_value is not None :
97- return super (InstanaSpan , self ).log_kv ({validated_key : validated_value }, timestamp )
98-
99- return self
100-
10126 def mark_as_errored (self , tags = None ):
10227 """
10328 Mark this span as errored.
@@ -160,7 +85,6 @@ def log_exception(self, exc):
16085 logger .debug ("span.log_exception" , exc_info = True )
16186 raise
16287
163-
16488class BaseSpan (object ):
16589 sy = None
16690
@@ -188,6 +112,64 @@ def __init__(self, span, source, service_name, **kwargs):
188112 self .stack = span .stack
189113
190114 self .__dict__ .update (kwargs )
115+
116+ def _validate_tags (self , tags ):
117+ """
118+ This method will loop through a set of tags to validate each key and value.
119+
120+ :param tags: dict of tags
121+ :return: dict - a filtered set of tags
122+ """
123+ filtered_tags = {}
124+ for key in tags .keys ():
125+ validated_key , validated_value = self ._validate_tag (key , tags [key ])
126+ if validated_key is not None and validated_value is not None :
127+ filtered_tags [validated_key ] = validated_value
128+ return filtered_tags
129+
130+ def _validate_tag (self , key , value ):
131+ """
132+ This method will assure that <key> and <value> are valid to set as a tag.
133+ If <value> fails the check, an attempt will be made to convert it into
134+ something useful.
135+
136+ On check failure, this method will return None values indicating that the tag is
137+ not valid and could not be converted into something useful
138+
139+ :param key: The tag key
140+ :param value: The tag value
141+ :return: Tuple (key, value)
142+ """
143+ validated_key = None
144+ validated_value = None
145+
146+ try :
147+ # Tag keys must be some type of text or string type
148+ if isinstance (key , (six .text_type , six .string_types )):
149+ validated_key = key [0 :1024 ] # Max key length of 1024 characters
150+
151+ if isinstance (value , (bool , float , int , list , dict , six .text_type , six .string_types )):
152+ validated_value = value
153+ else :
154+ validated_value = self ._convert_tag_value (value )
155+ else :
156+ logger .debug ("(non-fatal) tag names must be strings. tag discarded for %s" , type (key ))
157+ except Exception :
158+ logger .debug ("instana.span._validate_tag: " , exc_info = True )
159+
160+ return (validated_key , validated_value )
161+
162+ def _convert_tag_value (self , value ):
163+ final_value = None
164+
165+ try :
166+ final_value = repr (value )
167+ except Exception :
168+ final_value = "(non-fatal) span.set_tag: values must be one of these types: bool, float, int, list, " \
169+ "set, str or alternatively support 'repr'. tag discarded"
170+ logger .debug (final_value , exc_info = True )
171+ return None
172+ return final_value
191173
192174
193175class SDKSpan (BaseSpan ):
@@ -208,12 +190,14 @@ def __init__(self, span, source, service_name, **kwargs):
208190
209191 self .data ["sdk" ]["name" ] = span .operation_name
210192 self .data ["sdk" ]["type" ] = span_kind [0 ]
211- self .data ["sdk" ]["custom" ]["tags" ] = span .tags
193+ self .data ["sdk" ]["custom" ]["tags" ] = self . _validate_tags ( span .tags )
212194
213195 if span .logs is not None and len (span .logs ) > 0 :
214196 logs = DictionaryOfStan ()
215197 for log in span .logs :
216- logs [repr (log .timestamp )] = log .key_values
198+ filtered_key_values = self ._validate_tags (log .key_values )
199+ if len (filtered_key_values .keys ()) > 0 :
200+ logs [repr (log .timestamp )] = filtered_key_values
217201 self .data ["sdk" ]["custom" ]["logs" ] = logs
218202
219203 if "arguments" in span .tags :
@@ -227,8 +211,8 @@ def __init__(self, span, source, service_name, **kwargs):
227211
228212 def get_span_kind (self , span ):
229213 """
230- Will retrieve the `span.kind` tag and return a tuple containing the appropriate string and integer
231- values for the Instana backend
214+ Will retrieve the `span.kind` tag and return a tuple containing the appropriate string and integer
215+ values for the Instana backend
232216
233217 :param span: The span to search for the `span.kind` tag
234218 :return: Tuple (String, Int)
@@ -277,7 +261,7 @@ def __init__(self, span, source, service_name, **kwargs):
277261
278262 # Store any leftover tags in the custom section
279263 if len (span .tags ) > 0 :
280- self .data ["custom" ]["tags" ] = span .tags
264+ self .data ["custom" ]["tags" ] = self . _validate_tags ( span .tags )
281265
282266 def _populate_entry_span_data (self , span ):
283267 if span .operation_name in self .HTTP_SPANS :
0 commit comments