def __call__(self, environ, start_response): """The WSGI application Args: environ: A WSGI environment. start_response: The WSGI start_response callable. """ tracer = trace.tracer() path_info = environ["PATH_INFO"] or "/" parent_span = propagators.extract(get_header_from_environ, environ) with tracer.start_span(path_info, parent_span, kind=trace.SpanKind.SERVER) as span: self._add_request_attributes(span, environ) start_response = self._create_start_response(span, start_response) iterable = self.wsgi(environ, start_response) try: for yielded in iterable: yield yielded finally: if hasattr(iterable, "close"): iterable.close()
def setUp(self): self.span_attrs = {} self.tracer = trace.tracer() self.span_context_manager = mock.MagicMock() self.span = mock.create_autospec(trace.Span, spec_set=True) self.span_context_manager.__enter__.return_value = self.span def setspanattr(key, value): self.assertIsInstance(key, str) self.span_attrs[key] = value self.span.set_attribute = setspanattr self.start_span_patcher = mock.patch.object( self.tracer, "start_span", autospec=True, spec_set=True, return_value=self.span_context_manager, ) self.start_span = self.start_span_patcher.start() mocked_response = requests.models.Response() mocked_response.status_code = 200 mocked_response.reason = "Roger that!" self.send_patcher = mock.patch.object( requests.Session, "send", autospec=True, spec_set=True, return_value=mocked_response, ) self.send = self.send_patcher.start() opentelemetry.ext.http_requests.enable(self.tracer)
def configure_opentelemetry(flask_app: flask.Flask): """Configure a flask application to use OpenTelemetry. This activates the specific components: * sets tracer to the SDK's Tracer * enables requests integration on the Tracer * uses a WSGI middleware to enable configuration TODO: * processors? * exporters? """ # Start by configuring all objects required to ensure # a complete end to end workflow. # the preferred implementation of these objects must be set, # as the opentelemetry-api defines the interface with a no-op # implementation. trace.set_preferred_tracer_implementation(lambda _: Tracer()) # Next, we need to configure how the values that are used by # traces and metrics are propagated (such as what specific headers # carry this value). # TBD: can remove once default TraceContext propagators are installed. propagators.set_global_httptextformat(B3Format()) # Integrations are the glue that binds the OpenTelemetry API # and the frameworks and libraries that are used together, automatically # creating Spans and propagating context as appropriate. opentelemetry.ext.http_requests.enable(trace.tracer()) instrument_app(flask_app)
def __call__(self, environ, start_response): """The WSGI application Args: environ: A WSGI environment. start_response: The WSGI start_response callable. """ tracer = trace.tracer() parent_span = propagators.extract(get_header_from_environ, environ) span_name = get_default_span_name(environ) span = tracer.start_span( span_name, parent_span, kind=trace.SpanKind.SERVER ) try: with tracer.use_span(span): add_request_attributes(span, environ) start_response = self._create_start_response( span, start_response ) iterable = self.wsgi(environ, start_response) return _end_span_after_iterating(iterable, span, tracer) except: # noqa span.end() raise
def test_try_set_again(self): self.assertTrue(trace.tracer()) # Try setting after the tracer has already been created: with self.assertRaises(RuntimeError) as einfo: trace.set_preferred_tracer_implementation( get_opentelemetry_implementation) self.assertIn("already loaded", str(einfo.exception))
def do_test_get_envvar(self, envvar_suffix): global DUMMY_TRACER # pylint:disable=global-statement # Test is not runnable with this! self.assertFalse(sys.flags.ignore_environment) envname = "OPENTELEMETRY_PYTHON_IMPLEMENTATION_" + envvar_suffix os.environ[envname] = __name__ try: tracer = trace.tracer() self.assertIs(tracer, DUMMY_TRACER) finally: DUMMY_TRACER = None del os.environ[envname] self.assertIs(type(tracer), DummyTracer)
def setUp(self): tracer = trace_api.tracer() self.span = mock.create_autospec(trace_api.Span, spec_set=True) self.start_span_patcher = mock.patch.object( tracer, "start_span", autospec=True, spec_set=True, return_value=self.span, ) self.start_span = self.start_span_patcher.start() self.write_buffer = io.BytesIO() self.write = self.write_buffer.write self.environ = {} wsgiref_util.setup_testing_defaults(self.environ) self.status = None self.response_headers = None self.exc_info = None
def __call__(self, environ, start_response): """The WSGI application Args: environ: A WSGI environment. start_response: The WSGI start_response callable. """ tracer = trace.tracer() path_info = environ["PATH_INFO"] or "/" with tracer.start_span(path_info) as span: self._add_request_attributes(span, environ) start_response = self._create_start_response(span, start_response) iterable = self.wsgi(environ, start_response) try: for yielded in iterable: yield yielded finally: if hasattr(iterable, "close"): iterable.close()
def _before_flask_request(): environ = flask_request.environ span_name = flask_request.endpoint or otel_wsgi.get_default_span_name( environ) parent_span = propagators.extract(otel_wsgi.get_header_from_environ, environ) tracer = trace.tracer() span = tracer.start_span( span_name, parent_span, kind=trace.SpanKind.SERVER, start_time=environ.get(_ENVIRON_STARTTIME_KEY), ) activation = tracer.use_span(span, end_on_exit=True) activation.__enter__() environ[_ENVIRON_ACTIVATION_KEY] = activation environ[_ENVIRON_SPAN_KEY] = span otel_wsgi.add_request_attributes(span, environ) if flask_request.url_rule: # For 404 that result from no route found, etc, we don't have a url_rule. span.set_attribute("http.route", flask_request.url_rule.rule)
def get_current_tracer(cls): # type: () -> Tracer """ Get the current tracer from the execution context. Return None otherwise. """ return tracer()
from opentelemetry import trace, propagators from opentelemetry.sdk.trace import Tracer from opentelemetry.sdk.context.propagation.b3_format import B3Format from opentelemetry.ext.http_requests import enable from opentelemetry.ext.wsgi import OpenTelemetryMiddleware from opentelemetry.sdk.trace.export import ConsoleSpanExporter from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor from kitchen_service import KitchenService from kitchen_consumer import KitchenConsumer from donut import Donut from status import NEW_ORDER trace.set_preferred_tracer_implementation(lambda T: Tracer()) propagators.set_global_httptextformat(B3Format()) tracer = trace.tracer() enable(tracer) tracer.add_span_processor(SimpleExportSpanProcessor(ConsoleSpanExporter())) app = Flask(__name__) app.static_folder = 'static' app.wsgi_app = OpenTelemetryMiddleware(app.wsgi_app) kitchen_service = KitchenService() kitchen_consumer = KitchenConsumer() @app.route('/') def home():
def hello(): # emit a trace that measures how long the # sleep takes with trace.tracer().start_as_current_span("example-request"): requests.get("http://www.example.com") return "hello"
def tracer(): trace.set_preferred_tracer_implementation(lambda T: Tracer()) return trace.tracer()
def hello(): with trace.tracer().start_as_current_span("parent"): requests.get("https://www.wikipedia.org/wiki/Rabbit") return "hello"
from opentelemetry.ext import http_requests from opentelemetry.ext.wsgi import OpenTelemetryMiddleware from opentelemetry.sdk.trace import Tracer from opentelemetry.sdk.trace.export import ( ConsoleSpanExporter, SimpleExportSpanProcessor, ) # The preferred tracer implementation must be set, as the opentelemetry-api # defines the interface with a no-op implementation. trace.set_preferred_tracer_implementation(lambda T: Tracer()) # Integrations are the glue that binds the OpenTelemetry API and the # frameworks and libraries that are used together, automatically creating # Spans and propagating context as appropriate. http_requests.enable(trace.tracer()) # SpanExporter receives the spans and send them to the target location. span_processor = SimpleExportSpanProcessor(ConsoleSpanExporter()) trace.tracer().add_span_processor(span_processor) app = flask.Flask(__name__) app.wsgi_app = OpenTelemetryMiddleware(app.wsgi_app) @app.route("/") def hello(): with trace.tracer().start_as_current_span("parent"): requests.get("https://www.wikipedia.org/wiki/Rabbit") return "hello"
def test_get_default(self): tracer = trace.tracer() self.assertIs(type(tracer), trace.Tracer)
def setUp(self): """Create an OpenTelemetry tracer and a shim before every test case.""" self.tracer = trace.tracer() self.shim = opentracingshim.create_tracer(self.tracer)
def do_test_preferred_impl(self, setter): setter(get_opentelemetry_implementation) tracer = trace.tracer() self.assertIs(tracer, DUMMY_TRACER)
def test_preferred_impl(self): trace.set_preferred_tracer_implementation( get_opentelemetry_implementation) tracer = trace.tracer() self.assertIs(tracer, DUMMY_TRACER)