Skip to content
This repository has been archived by the owner on Oct 27, 2020. It is now read-only.

Latest commit

 

History

History
243 lines (153 loc) · 7.07 KB

README.rst

File metadata and controls

243 lines (153 loc) · 7.07 KB

This is example is now deprecated. For up to date examples, see https://github.com/lightstep/opentelemetry-examples.

MicroDonuts: An OpenTelemetry Walkthrough

Welcome to MicroDonuts! This is a sample application and OpenTelemetry walkthrough, written in Python.

OpenTelemetry is a vendor-neutral, open standard for distributed tracing. To learn more, check out http://opentelemetry.io, and try the walkthrough below!

There are two versions of the example app, walkthrough/server.py does not contain tracing while walkthrough/server_instrumented.py does.

This guide has two exclusive steps:

Step 0: Setup MicroDonuts

Getting it

  1. Install virtualenv: sudo -H pip3 install virtualenv
  2. Create a virtual environment: mkdir microdonuts; virtualenv microdonuts
  3. Activate the virtual environment: source microdonuts/bin/activate
  4. Clone this repository: git clone [email protected]:lightstep/python-opentelemetry-walkthrough.git
  5. Install the dependencies pip3 install -r python-opentelemetry-walkthrough/requirements.txt

Running

  1. python python-opentelemetry-walkthrough/walkthrough/server.py
  2. Open your web browser, navigate to http://127.0.0.1:8082 and order yourself some µ-donuts.

MicroDonuts has 4 server endpoints:

  1. /order
  2. /status
  3. /kitchen/add_donuts
  4. /kitchen/get_donuts

The first 2 serve orders, the last 2 provide kitchen services.

Step 1, Alternative A: Add Tracing

When you go to add tracing to a system, the best place to start is by installing OpenTelemetry plugins for the OSS components you are using. Instrumenting your networking libraries, web frameworks, and service clients quickly gives you a lot of information about your distributed system, without requiring you to change a lot of code.

To do this, let's change the startup of the application to include tracing: cd python-opentelemetry-walkthrough/walkthrough

You can also run the already instrumented version of microdonuts:

::
python python-opentelemetry-walkthrough/walkthrough/server.py

Start the global tracer

In OpenTelemetry, there is a concept of a global tracer for everyone to access.

Accessing this global tracer is easy, just add these lines to server.py under BLOCK 0:

from opentelemetry import trace, propagators
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.propagation.b3_format import B3Format

Add these lines under BLOCK 2 too:

trace.set_tracer_provider(TracerProvider())

propagators.set_global_httptextformat(B3Format())

tracer = trace.get_tracer(__name__)

The global tracer is now available as tracer.

Instrument the HTTP requests

This is done in an automatic way by just adding this line under BLOCK 0:

from opentelemetry.ext.requests import RequestsInstrumentor

Add also this line under BLOCK 2:

RequestsInstrumentor().instrument()

Instrument Flask

This example uses Flask to expose the HTTP endpoints. Flask code can be traced automatically by adding this line under BLOCK 0:

from opentelemetry.ext.flask import FlaskInstrumentor

Add this line under BLOCK 1 also:

FlaskInstrumentor().instrument_app(app)

Add an exporter

An exporter is necessary for the span data to be displayed. We'll use the ConsoleExporter in this example, an exporter that simply prints the span data into the console. Add these lines under BLOCK 0:

from opentelemetry.sdk.trace.export import ConsoleSpanExporter
from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor

Add these lines under BLOCK 2:

trace.get_tracer_provider().add_span_processor(
    SimpleExportSpanProcessor(ConsoleSpanExporter())
)

Use the tracer

Now is time to use the tracer itself in the server code.

Change the order function to this:

@app.route('/order', methods=['POST'])
def order():

    order_id = str(uuid4())

    with tracer.start_span('root_span'):

        for donut_data in loads(next(request.form.keys()))['donuts']:

            for _ in range(donut_data['quantity']):

                kitchen_consumer.add_donut(donut_data, order_id)

        return kitchen_consumer.check_status(order_id)

Change the status function to this:

@app.route('/status', methods=['POST'])
def status():

    with tracer.start_span('status_span'):

        return kitchen_consumer.check_status(
            loads(next(request.form.keys()))['order_id']
        )

This will automatically create a span every time each of these functions are called.

Step 1, Alternative B: Use opentelemetry-instrumentation

opentelemetry-instrumentation allows to automatically instrument applications written in Python.

Installation

The opentelemetry-instrumentation package can be installed directly from PyPi. It is already provided in the requirements.txt file so no more installation is needed.

Configure OpenTelemetry

Add these lines to server.py under BLOCK 0:

from opentelemetry import trace
from opentelemetry.sdk.trace.export import ConsoleSpanExporter
from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor

Then add these lines under BLOCK 1:

tracer = trace.get_tracer(__name__)
span_processor = SimpleExportSpanProcessor(ConsoleSpanExporter())
trace.get_tracer_provider().add_span_processor(span_processor)

Running

The opentelemetry-instrument script loads all installed instrumentation libraries before your application runs, giving it a chance to instrument any calls to supported libraries. Start the application:

export OPENTELEMETRY_PYTHON_tracer_provider=sdk_tracer_provider
opentelemetry-instrument python python-opentelemetry-walkthrough/walkthrough/server.py

Step 2: Have Fun

You can run the walkthrough again as explained before. You should see the span data displayed in the console.

Thanks for playing, and welcome to OpenTelemetry!

Thanks for joining us in this walkthrough! Hope you enjoyed it. If you did, let us know, and consider spreading the love!

Aloha!