44import os
55import platform
66import time
7- import six
87
98from aws_xray_sdk import global_sdk_config
109from aws_xray_sdk .version import VERSION
@@ -275,16 +274,10 @@ def current_segment(self):
275274 else :
276275 return entity
277276
278- def begin_subsegment (self , name , namespace = 'local' ):
279- """
280- Begin a new subsegment.
281- If there is open subsegment, the newly created subsegment will be the
282- child of latest opened subsegment.
283- If not, it will be the child of the current open segment.
284-
285- :param str name: the name of the subsegment.
286- :param str namespace: currently can only be 'local', 'remote', 'aws'.
287- """
277+ def _begin_subsegment_helper (self , name , namespace = 'local' , beginWithoutSampling = False ):
278+ '''
279+ Helper method to begin_subsegment and begin_subsegment_without_sampling
280+ '''
288281 # Generating the parent dummy segment is necessary.
289282 # We don't need to store anything in context. Assumption here
290283 # is that we only work with recorder-level APIs.
@@ -295,16 +288,42 @@ def begin_subsegment(self, name, namespace='local'):
295288 if not segment :
296289 log .warning ("No segment found, cannot begin subsegment %s." % name )
297290 return None
298-
299- if not segment .sampled :
291+
292+ current_entity = self .get_trace_entity ()
293+ if not current_entity .sampled or beginWithoutSampling :
300294 subsegment = DummySubsegment (segment , name )
301295 else :
302296 subsegment = Subsegment (name , namespace , segment )
303297
304298 self .context .put_subsegment (subsegment )
305-
306299 return subsegment
307300
301+
302+
303+ def begin_subsegment (self , name , namespace = 'local' ):
304+ """
305+ Begin a new subsegment.
306+ If there is open subsegment, the newly created subsegment will be the
307+ child of latest opened subsegment.
308+ If not, it will be the child of the current open segment.
309+
310+ :param str name: the name of the subsegment.
311+ :param str namespace: currently can only be 'local', 'remote', 'aws'.
312+ """
313+ return self ._begin_subsegment_helper (name , namespace )
314+
315+
316+ def begin_subsegment_without_sampling (self , name ):
317+ """
318+ Begin a new unsampled subsegment.
319+ If there is open subsegment, the newly created subsegment will be the
320+ child of latest opened subsegment.
321+ If not, it will be the child of the current open segment.
322+
323+ :param str name: the name of the subsegment.
324+ """
325+ return self ._begin_subsegment_helper (name , beginWithoutSampling = True )
326+
308327 def current_subsegment (self ):
309328 """
310329 Return the latest opened subsegment. In a multithreading environment,
@@ -436,10 +455,10 @@ def record_subsegment(self, wrapped, instance, args, kwargs, name,
436455 try :
437456 return_value = wrapped (* args , ** kwargs )
438457 return return_value
439- except Exception as exc :
440- exception = exc
458+ except Exception as e :
459+ exception = e
441460 stack = stacktrace .get_stacktrace (limit = self .max_trace_back )
442- six . raise_from ( exc , exc )
461+ raise
443462 finally :
444463 # No-op if subsegment is `None` due to `LOG_ERROR`.
445464 if subsegment is not None :
@@ -487,7 +506,8 @@ def _send_segment(self):
487506
488507 def _stream_subsegment_out (self , subsegment ):
489508 log .debug ("streaming subsegments..." )
490- self .emitter .send_entity (subsegment )
509+ if subsegment .sampled :
510+ self .emitter .send_entity (subsegment )
491511
492512 def _load_sampling_rules (self , sampling_rules ):
493513
0 commit comments