Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/opencensus/trace/span_context.py: 76%

55 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-06 06:04 +0000

1# Copyright 2017, OpenCensus Authors 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15"""SpanContext encapsulates the current context within the request's trace.""" 

16 

17import six 

18 

19import logging 

20import random 

21import re 

22 

23from opencensus.trace import trace_options as trace_options_module 

24 

25_INVALID_TRACE_ID = '0' * 32 

26INVALID_SPAN_ID = '0' * 16 

27 

28TRACE_ID_PATTERN = re.compile('[0-9a-f]{32}?') 

29SPAN_ID_PATTERN = re.compile('[0-9a-f]{16}?') 

30 

31# Default options, don't force sampling 

32DEFAULT_OPTIONS = '0' 

33 

34 

35class SpanContext(object): 

36 """SpanContext includes 3 fields: traceId, spanId, and an trace_options flag 

37 which indicates whether or not the request is being traced. It contains the 

38 current context to be propagated to the child spans. 

39 

40 :type trace_id: str 

41 :param trace_id: (Optional) Trace_id is a 32 digits uuid for the trace. 

42 If not given, will generate one automatically. 

43 

44 :type span_id: str 

45 :param span_id: (Optional) Identifier for the span, unique within a trace. 

46 

47 :type trace_options: :class: `~opencensus.trace.trace_options.TraceOptions` 

48 :param trace_options: (Optional) TraceOptions indicates 8 trace options. 

49 

50 :type from_header: bool 

51 :param from_header: (Optional) Indicates whether the trace context is 

52 generated from request header. 

53 """ 

54 def __init__( 

55 self, 

56 trace_id=None, 

57 span_id=None, 

58 trace_options=None, 

59 tracestate=None, 

60 from_header=False): 

61 if trace_id is None: 

62 trace_id = generate_trace_id() 

63 

64 if trace_options is None: 

65 trace_options = trace_options_module.TraceOptions(DEFAULT_OPTIONS) 

66 

67 self.from_header = from_header 

68 self.trace_id = self._check_trace_id(trace_id) 

69 self.span_id = self._check_span_id(span_id) 

70 self.trace_options = trace_options 

71 self.tracestate = tracestate 

72 

73 def __repr__(self): 

74 """Returns a string form of the SpanContext. 

75 

76 :rtype: str 

77 :returns: String form of the SpanContext. 

78 """ 

79 fmt = '{}(trace_id={}, span_id={}, trace_options={}, tracestate={})' 

80 return fmt.format( 

81 type(self).__name__, 

82 self.trace_id, 

83 self.span_id, 

84 self.trace_options, 

85 self.tracestate, 

86 ) 

87 

88 def _check_span_id(self, span_id): 

89 """Check the format of the span_id to ensure it is 16-character hex 

90 value representing a 64-bit number. If span_id is invalid, logs a 

91 warning message and returns None 

92 

93 :type span_id: str 

94 :param span_id: Identifier for the span, unique within a span. 

95 

96 :rtype: str 

97 :returns: Span_id for the current span. 

98 """ 

99 if span_id is None: 

100 return None 

101 assert isinstance(span_id, six.string_types) 

102 

103 if span_id is INVALID_SPAN_ID: 

104 logging.warning( 

105 'Span_id %s is invalid (cannot be all zero)', span_id) 

106 self.from_header = False 

107 return None 

108 

109 match = SPAN_ID_PATTERN.match(span_id) 

110 

111 if match: 

112 return span_id 

113 else: 

114 logging.warning( 

115 'Span_id %s does not the match the ' 

116 'required format', span_id) 

117 self.from_header = False 

118 return None 

119 

120 def _check_trace_id(self, trace_id): 

121 """Check the format of the trace_id to ensure it is 32-character hex 

122 value representing a 128-bit number. If trace_id is invalid, returns a 

123 randomly generated trace id 

124 

125 :type trace_id: str 

126 :param trace_id: 

127 

128 :rtype: str 

129 :returns: Trace_id for the current context. 

130 """ 

131 assert isinstance(trace_id, six.string_types) 

132 

133 if trace_id is _INVALID_TRACE_ID: 

134 logging.warning( 

135 'Trace_id %s is invalid (cannot be all zero), ' 

136 'generating a new one.', trace_id) 

137 self.from_header = False 

138 return generate_trace_id() 

139 

140 match = TRACE_ID_PATTERN.match(trace_id) 

141 

142 if match: 

143 return trace_id 

144 else: 

145 logging.warning( 

146 'Trace_id %s does not the match the required format,' 

147 'generating a new one instead.', trace_id) 

148 self.from_header = False 

149 return generate_trace_id() 

150 

151 

152def generate_span_id(): 

153 """Return the random generated span ID for a span. Must be a 16 character 

154 hexadecimal encoded string 

155 

156 :rtype: str 

157 :returns: 16 digit randomly generated hex trace id. 

158 """ 

159 return '{:016x}'.format(random.getrandbits(64)) 

160 

161 

162def generate_trace_id(): 

163 """Generate a random 32 char hex trace_id. 

164 

165 :rtype: str 

166 :returns: 32 digit randomly generated hex trace id. 

167 """ 

168 return '{:032x}'.format(random.getrandbits(128))