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
« 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.
15"""SpanContext encapsulates the current context within the request's trace."""
17import six
19import logging
20import random
21import re
23from opencensus.trace import trace_options as trace_options_module
25_INVALID_TRACE_ID = '0' * 32
26INVALID_SPAN_ID = '0' * 16
28TRACE_ID_PATTERN = re.compile('[0-9a-f]{32}?')
29SPAN_ID_PATTERN = re.compile('[0-9a-f]{16}?')
31# Default options, don't force sampling
32DEFAULT_OPTIONS = '0'
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.
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.
44 :type span_id: str
45 :param span_id: (Optional) Identifier for the span, unique within a trace.
47 :type trace_options: :class: `~opencensus.trace.trace_options.TraceOptions`
48 :param trace_options: (Optional) TraceOptions indicates 8 trace options.
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()
64 if trace_options is None:
65 trace_options = trace_options_module.TraceOptions(DEFAULT_OPTIONS)
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
73 def __repr__(self):
74 """Returns a string form of the SpanContext.
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 )
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
93 :type span_id: str
94 :param span_id: Identifier for the span, unique within a span.
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)
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
109 match = SPAN_ID_PATTERN.match(span_id)
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
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
125 :type trace_id: str
126 :param trace_id:
128 :rtype: str
129 :returns: Trace_id for the current context.
130 """
131 assert isinstance(trace_id, six.string_types)
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()
140 match = TRACE_ID_PATTERN.match(trace_id)
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()
152def generate_span_id():
153 """Return the random generated span ID for a span. Must be a 16 character
154 hexadecimal encoded string
156 :rtype: str
157 :returns: 16 digit randomly generated hex trace id.
158 """
159 return '{:016x}'.format(random.getrandbits(64))
162def generate_trace_id():
163 """Generate a random 32 char hex trace_id.
165 :rtype: str
166 :returns: 32 digit randomly generated hex trace id.
167 """
168 return '{:032x}'.format(random.getrandbits(128))