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 15from opencensus.trace import execution_context, print_exporter, samplers 16from opencensus.trace.propagation import trace_context_http_header_format 17from opencensus.trace.span_context import SpanContext 18from opencensus.trace.tracers import context_tracer, noop_tracer 19 20 21class Tracer(object): 22 """The Tracer is for tracing a request for web applications. 23 24 :type span_context: :class:`~opencensus.trace.span_context.SpanContext` 25 :param span_context: SpanContext encapsulates the current context within 26 the request's trace. 27 28 :type sampler: :class:`~opencensus.trace.samplers.base.Sampler` 29 :param sampler: Instances of Sampler objects. Defaults to 30 :class:`.ProbabilitySampler`. Other options include 31 :class:`.AlwaysOnSampler` and :class:`.AlwaysOffSampler`. 32 33 :type exporter: :class:`~opencensus.trace.base_exporter.exporter` 34 :param exporter: Instances of exporter objects. Default to 35 :class:`.Printexporter`. The rest options are 36 :class:`.Fileexporter`, :class:`.Printexporter`, 37 :class:`.Loggingexporter`, :class:`.Zipkinexporter`, 38 :class:`.GoogleCloudexporter` 39 """ 40 def __init__( 41 self, 42 span_context=None, 43 sampler=None, 44 exporter=None, 45 propagator=None): 46 if span_context is None: 47 span_context = SpanContext() 48 49 if sampler is None: 50 sampler = samplers.ProbabilitySampler() 51 52 if exporter is None: 53 exporter = print_exporter.PrintExporter() 54 55 if propagator is None: 56 propagator = \ 57 trace_context_http_header_format.TraceContextPropagator() 58 59 self.span_context = span_context 60 self.sampler = sampler 61 self.exporter = exporter 62 self.propagator = propagator 63 self.tracer = self.get_tracer() 64 self.store_tracer() 65 66 def should_sample(self): 67 """Determine whether to sample this request or not. 68 If the context enables tracing, return True. 69 Else follow the decision of the sampler. 70 71 :rtype: bool 72 :returns: Whether to trace the request or not. 73 """ 74 return self.sampler.should_sample(self.span_context) 75 76 def get_tracer(self): 77 """Return a tracer according to the sampling decision.""" 78 sampled = self.should_sample() 79 80 if sampled: 81 self.span_context.trace_options.set_enabled(True) 82 return context_tracer.ContextTracer( 83 exporter=self.exporter, 84 span_context=self.span_context) 85 return noop_tracer.NoopTracer() 86 87 def store_tracer(self): 88 """Add the current tracer to thread_local""" 89 execution_context.set_opencensus_tracer(self) 90 91 def finish(self): 92 """End all spans.""" 93 self.tracer.finish() 94 95 def span(self, name='span'): 96 """Create a new span with the trace using the context information. 97 98 :type name: str 99 :param name: The name of the span. 100 101 :rtype: :class:`~opencensus.trace.span.Span` 102 :returns: The Span object. 103 """ 104 return self.tracer.span(name) 105 106 def start_span(self, name='span'): 107 return self.tracer.start_span(name) 108 109 def end_span(self): 110 """End a span. Update the span_id in SpanContext to the current span's 111 parent span id; Update the current span; Send the span to exporter. 112 """ 113 self.tracer.end_span() 114 115 def current_span(self): 116 """Return the current span.""" 117 return self.tracer.current_span() 118 119 def add_attribute_to_current_span(self, attribute_key, attribute_value): 120 """Add attribute to current span. 121 122 :type attribute_key: str 123 :param attribute_key: Attribute key. 124 125 :type attribute_value:str 126 :param attribute_value: Attribute value. 127 """ 128 self.tracer.add_attribute_to_current_span( 129 attribute_key, attribute_value) 130 131 def trace_decorator(self): 132 """Decorator to trace a function.""" 133 134 def decorator(func): 135 136 def wrapper(*args, **kwargs): 137 self.tracer.start_span(name=func.__name__) 138 return_value = func(*args, **kwargs) 139 self.tracer.end_span() 140 return return_value 141 142 return wrapper 143 144 return decorator 145