예제 #1
0
    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()
예제 #2
0
    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)
예제 #3
0
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)
예제 #4
0
    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
예제 #5
0
 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))
예제 #6
0
    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)
예제 #7
0
    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
예제 #8
0
    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()
예제 #9
0
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)
예제 #10
0
 def get_current_tracer(cls):
     # type: () -> Tracer
     """
     Get the current tracer from the execution context. Return None otherwise.
     """
     return tracer()
예제 #11
0
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():
예제 #12
0
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"
예제 #13
0
def tracer():
    trace.set_preferred_tracer_implementation(lambda T: Tracer())
    return trace.tracer()
예제 #14
0
def hello():
    with trace.tracer().start_as_current_span("parent"):
        requests.get("https://www.wikipedia.org/wiki/Rabbit")
    return "hello"
예제 #15
0
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"
예제 #16
0
 def test_get_default(self):
     tracer = trace.tracer()
     self.assertIs(type(tracer), trace.Tracer)
예제 #17
0
    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)
예제 #18
0
 def do_test_preferred_impl(self, setter):
     setter(get_opentelemetry_implementation)
     tracer = trace.tracer()
     self.assertIs(tracer, DUMMY_TRACER)
예제 #19
0
 def test_preferred_impl(self):
     trace.set_preferred_tracer_implementation(
         get_opentelemetry_implementation)
     tracer = trace.tracer()
     self.assertIs(tracer, DUMMY_TRACER)