Source code for opencensus.trace.span_context
# Copyright 2017, OpenCensus Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""SpanContext encapsulates the current context within the request's trace."""
import logging
import re
import six
import random
from opencensus.trace import trace_options as trace_options_module
_INVALID_TRACE_ID = '0' * 32
INVALID_SPAN_ID = '0' * 16
TRACE_ID_PATTERN = re.compile('[0-9a-f]{32}?')
SPAN_ID_PATTERN = re.compile('[0-9a-f]{16}?')
# Default options, don't force sampling
DEFAULT_OPTIONS = '0'
[docs]class SpanContext(object):
"""SpanContext includes 3 fields: traceId, spanId, and an trace_options flag
which indicates whether or not the request is being traced. It contains the
current context to be propagated to the child spans.
:type trace_id: str
:param trace_id: (Optional) Trace_id is a 32 digits uuid for the trace.
If not given, will generate one automatically.
:type span_id: str
:param span_id: (Optional) Identifier for the span, unique within a trace.
If not given, will generate one automatically.
:type trace_options: :class: `~opencensus.trace.trace_options.TraceOptions`
:param trace_options: (Optional) TraceOptions indicates 8 trace options.
:type from_header: bool
:param from_header: (Optional) Indicates whether the trace context is
generated from request header.
"""
def __init__(
self,
trace_id=None,
span_id=None,
trace_options=None,
tracestate=None,
from_header=False):
if trace_id is None:
trace_id = generate_trace_id()
if trace_options is None:
trace_options = trace_options_module.TraceOptions(DEFAULT_OPTIONS)
self.from_header = from_header
self.trace_id = self._check_trace_id(trace_id)
self.span_id = self._check_span_id(span_id)
self.trace_options = trace_options
self.tracestate = tracestate
def __repr__(self):
"""Returns a string form of the SpanContext.
:rtype: str
:returns: String form of the SpanContext.
"""
fmt = '{}(trace_id={}, span_id={}, trace_options={}, tracestate={})'
return fmt.format(
type(self).__name__,
self.trace_id,
self.span_id,
self.trace_options,
self.tracestate,
)
def _check_span_id(self, span_id):
"""Check the format of the span_id to ensure it is 16-character hex
value representing a 64-bit number. If span_id is invalid, logs a
warning message and returns None
:type span_id: str
:param span_id: Identifier for the span, unique within a span.
:rtype: str
:returns: Span_id for the current span.
"""
if span_id is None:
return None
assert isinstance(span_id, six.string_types)
if span_id is INVALID_SPAN_ID:
logging.warning(
'Span_id %s is invalid (cannot be all zero)', span_id)
self.from_header = False
return None
match = SPAN_ID_PATTERN.match(span_id)
if match:
return span_id
else:
logging.warning(
'Span_id %s does not the match the '
'required format', span_id)
self.from_header = False
return None
def _check_trace_id(self, trace_id):
"""Check the format of the trace_id to ensure it is 32-character hex
value representing a 128-bit number. If trace_id is invalid, returns a
randomly generated trace id
:type trace_id: str
:param trace_id:
:rtype: str
:returns: Trace_id for the current context.
"""
assert isinstance(trace_id, six.string_types)
if trace_id is _INVALID_TRACE_ID:
logging.warning(
'Trace_id %s is invalid (cannot be all zero), '
'generating a new one.', trace_id)
self.from_header = False
return generate_trace_id()
match = TRACE_ID_PATTERN.match(trace_id)
if match:
return trace_id
else:
logging.warning(
'Trace_id %s does not the match the required format,'
'generating a new one instead.', trace_id)
self.from_header = False
return generate_trace_id()
[docs]def generate_span_id():
"""Return the random generated span ID for a span. Must be a 16 character
hexadecimal encoded string
:rtype: str
:returns: 16 digit randomly generated hex trace id.
"""
return '{:016x}'.format(random.getrandbits(64))
[docs]def generate_trace_id():
"""Generate a random 32 char hex trace_id.
:rtype: str
:returns: 32 digit randomly generated hex trace id.
"""
return '{:032x}'.format(random.getrandbits(128))