1515"""SpanContext encapsulates the current context within the request's trace."""
1616
1717import logging
18- import random
1918import re
2019import uuid
2120
2221from opencensus .trace import trace_options
2322
2423_INVALID_TRACE_ID = '0' * 32
25- _INVALID_SPAN_ID = 0
24+ INVALID_SPAN_ID = '0' * 16
2625_TRACE_HEADER_KEY = 'X_CLOUD_TRACE_CONTEXT'
27- _TRACE_ID_FORMAT = '[0-9a-f]{32}?'
26+
27+ TRACE_ID_PATTERN = re .compile ('[0-9a-f]{32}?' )
28+ SPAN_ID_PATTERN = re .compile ('[0-9a-f]{16}?' )
2829
2930# Default options, enable tracing
3031DEFAULT_OPTIONS = 1
@@ -42,8 +43,9 @@ class SpanContext(object):
4243 :param trace_id: (Optional) Trace_id is a 32 digits uuid for the trace.
4344 If not given, will generate one automatically.
4445
45- :type span_id: int
46+ :type span_id: str
4647 :param span_id: (Optional) Identifier for the span, unique within a trace.
48+ If not given, will generate one automatically.
4749
4850 :type trace_options: :class: `~opencensus.trace.trace_options.TraceOptions`
4951 :param trace_options: (Optional) TraceOptions indicates 8 trace options.
@@ -64,10 +66,10 @@ def __init__(
6466 if trace_options is None :
6567 trace_options = DEFAULT
6668
67- self .trace_id = self .check_trace_id (trace_id )
68- self .span_id = self .check_span_id (span_id )
69- self .trace_options = trace_options
7069 self .from_header = from_header
70+ self .trace_id = self ._check_trace_id (trace_id )
71+ self .span_id = self ._check_span_id (span_id )
72+ self .trace_options = trace_options
7173
7274 def __str__ (self ):
7375 """Returns a string form of the SpanContext. This is the format of
@@ -84,41 +86,42 @@ def __str__(self):
8486 int (enabled ))
8587 return header
8688
87- def check_span_id (self , span_id ):
88- """Check the type of span_id to ensure it is int. If it is not int,
89- first try to convert it to int, if failed to convert, then log a
90- warning message and set the span_id to None.
89+ def _check_span_id (self , span_id ):
90+ """Check the format of the span_id to ensure it is 16-character hex
91+ value representing a 64-bit number. If span_id is invalid, logs a
92+ warning message and returns None
9193
92- :type span_id: int
93- :param span_id: Identifier for the span, unique within a trace .
94+ :type span_id: str
95+ :param span_id: Identifier for the span, unique within a span .
9496
95- :rtype: int
97+ :rtype: str
9698 :returns: Span_id for the current span.
9799 """
98100 if span_id is None :
99101 return None
102+ assert isinstance (span_id , str )
100103
101- if span_id == 0 :
104+ if span_id is INVALID_SPAN_ID :
102105 logging .warning (
103- 'Span_id {} is invalid, cannot be zero. ' .format (span_id ))
106+ 'Span_id {} is invalid ( cannot be all zero) ' .format (span_id ))
104107 self .from_header = False
105108 return None
106109
107- if not isinstance (span_id , int ):
108- try :
109- span_id = int (span_id )
110- except (TypeError , ValueError ):
111- logging .warning (
112- 'The type of span_id should be int, got {}.' .format (
113- span_id .__class__ .__name__ ))
114- self .from_header = False
115- span_id = None
110+ match = SPAN_ID_PATTERN .match (span_id )
116111
117- return span_id
112+ if match :
113+ return span_id
114+ else :
115+ logging .warning (
116+ 'Span_id {} does not the match the '
117+ 'required format' .format (span_id ))
118+ self .from_header = False
119+ return None
118120
119- def check_trace_id (self , trace_id ):
121+ def _check_trace_id (self , trace_id ):
120122 """Check the format of the trace_id to ensure it is 32-character hex
121- value representing a 128-bit number. Also the trace_id cannot be zero.
123+ value representing a 128-bit number. If trace_id is invalid, returns a
124+ randomly generated trace id
122125
123126 :type trace_id: str
124127 :param trace_id:
@@ -131,41 +134,39 @@ def check_trace_id(self, trace_id):
131134 if trace_id is _INVALID_TRACE_ID :
132135 logging .warning (
133136 'Trace_id {} is invalid (cannot be all zero), '
134- 'generate a new one.' .format (trace_id ))
137+ 'generating a new one.' .format (trace_id ))
135138 self .from_header = False
136139 return generate_trace_id ()
137140
138- trace_id_pattern = re .compile (_TRACE_ID_FORMAT )
139-
140- match = trace_id_pattern .match (trace_id )
141+ match = TRACE_ID_PATTERN .match (trace_id )
141142
142143 if match :
143144 return trace_id
144145 else :
145146 logging .warning (
146147 'Trace_id {} does not the match the required format,'
147- 'generate a new one instead.' .format (trace_id ))
148+ 'generating a new one instead.' .format (trace_id ))
148149 self .from_header = False
149150 return generate_trace_id ()
150151
151152
152153def generate_span_id ():
153- """Return the random generated span ID for a span. Must be 16 digits
154- as Stackdriver Trace V2 API only accepts 16 digits span ID.
154+ """Return the random generated span ID for a span. Must be a 16 character
155+ hexadecimal encoded string
155156
156- :rtype: int
157- :returns: Identifier for the span. Must be a 64-bit integer other
158- than 0 and unique within a trace.
157+ :rtype: str
158+ :returns: 16 digit randomly generated hex trace id.
159159 """
160- span_id = random . randint ( 10 ** 15 , 10 ** 16 - 1 )
160+ span_id = uuid . uuid4 (). hex [: 16 ]
161161 return span_id
162162
163163
164164def generate_trace_id ():
165- """Generate a trace_id randomly.
165+ """Generate a trace_id randomly. Must be a 32 character
166+ hexadecimal encoded string
166167
167168 :rtype: str
168- :returns: 32 digit randomly generated trace ID .
169+ :returns: 32 digit randomly generated hex trace id .
169170 """
170171 trace_id = uuid .uuid4 ().hex
171172 return trace_id
0 commit comments