Source code for opencensus.trace.propagation.google_cloud_format
# 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.
import logging
import re
from opencensus.trace.span_context import SpanContext
from opencensus.trace.trace_options import TraceOptions
_TRACE_CONTEXT_HEADER_NAME = 'X-Cloud-Trace-Context'
_TRACE_CONTEXT_HEADER_FORMAT = r'([0-9a-f]{32})(\/([0-9a-f]{16}))?(;o=(\d+))?'
_TRACE_CONTEXT_HEADER_RE = re.compile(_TRACE_CONTEXT_HEADER_FORMAT)
_TRACE_ID_DELIMETER = '/'
_SPAN_ID_DELIMETER = ';'
[docs]class GoogleCloudFormatPropagator(object):
"""This class is for converting the trace header in google cloud format
and generate a SpanContext, or converting a SpanContext to a google cloud
format header. Later we will add implementation for supporting other
format like binary format and zipkin, opencensus format.
"""
[docs] def from_header(self, header):
"""Generate a SpanContext object using the trace context header.
The value of enabled parsed from header is int. Need to convert to
bool.
:type header: str
:param header: Trace context header which was extracted from the HTTP
request headers.
:rtype: :class:`~opencensus.trace.span_context.SpanContext`
:returns: SpanContext generated from the trace context header.
"""
if header is None:
return SpanContext()
try:
match = re.search(_TRACE_CONTEXT_HEADER_RE, header)
except TypeError:
logging.warning(
'Header should be str, got %s. Cannot parse the header.',
header.__class__.__name__)
raise
if match:
trace_id = match.group(1)
span_id = match.group(3)
trace_options = match.group(5)
if trace_options is None:
trace_options = 1
span_context = SpanContext(
trace_id=trace_id,
span_id=span_id,
trace_options=TraceOptions(trace_options),
from_header=True)
return span_context
else:
logging.warning(
'Cannot parse the header %s, generate a new context instead.',
header)
return SpanContext()
[docs] def from_headers(self, headers):
"""Generate a SpanContext object using the trace context header.
:type headers: dict
:param headers: HTTP request headers.
:rtype: :class:`~opencensus.trace.span_context.SpanContext`
:returns: SpanContext generated from the trace context header.
"""
if headers is None:
return SpanContext()
header = headers.get(_TRACE_CONTEXT_HEADER_NAME)
if header is None:
return SpanContext()
header = str(header.encode('utf-8'))
return self.from_header(header)
[docs] def to_header(self, span_context):
"""Convert a SpanContext object to header string.
:type span_context:
:class:`~opencensus.trace.span_context.SpanContext`
:param span_context: SpanContext object.
:rtype: str
:returns: A trace context header string in google cloud format.
"""
trace_id = span_context.trace_id
span_id = span_context.span_id
trace_options = span_context.trace_options.trace_options_byte
header = '{}/{};o={}'.format(
trace_id,
span_id,
int(trace_options))
return header
[docs] def to_headers(self, span_context):
"""Convert a SpanContext object to HTTP request headers.
:type span_context:
:class:`~opencensus.trace.span_context.SpanContext`
:param span_context: SpanContext object.
:rtype: dict
:returns: Trace context headers in google cloud format.
"""
return {
_TRACE_CONTEXT_HEADER_NAME: self.to_header(span_context),
}