# Django Instrumentation

This shows how to use `opentelemetry-instrumentation-django` to automatically instrument a Django app.

The source files of these examples are available here.

## Preparation

This example will be executed in a separate virtual environment:

    $ mkdir django_auto_instrumentation
    $ virtualenv django_auto_instrumentation
    $ source django_auto_instrumentation/bin/activate

## Installation

    $ pip install opentelemetry-sdk
    $ pip install opentelemetry-instrumentation-django
    $ pip install requests

## Execution

### Execution of the Django app

This example uses Django features intended for development environment. The `runserver` option should not be used for production environments.

Set these environment variables first:

1. `export DJANGO_SETTINGS_MODULE=instrumentation_example.settings`

The way to achieve OpenTelemetry instrumentation for your Django app is to use an `opentelemetry.instrumentation.django.DjangoInstrumentor` to instrument the app.

Clone the `opentelemetry-python` repository and go to `opentelemetry-python/docs/examples/django`.

Once there, open the `manage.py` file. The call to `DjangoInstrumentor().instrument()` in `main` is all that is needed to make the app be instrumented.

Run the Django app with `python manage.py runserver --noreload`. The `--noreload` flag is needed to avoid Django from running `main` twice.

### Execution of the client

Open up a new console and activate the previous virtual environment there too:

`source django_auto_instrumentation/bin/activate`

Go to `opentelemetry-python/docs/examples/django`, once there run the client with:

`python client.py hello`

Go to the previous console, where the Django app is running. You should see output similar to this one:

    {
        "name": "home_page_view",
        "context": {
            "trace_id": "0xed88755c56d95d05a506f5f70e7849b9",
            "span_id": "0x0a94c7a60e0650d5",
            "trace_state": "{}"
        },
        "kind": "SpanKind.SERVER",
        "parent_id": "0x3096ef92e621c22d",
        "start_time": "2020-04-26T01:49:57.205833Z",
        "end_time": "2020-04-26T01:49:57.206214Z",
        "status": {
            "status_code": "OK"
        },
        "attributes": {
            "http.request.method": "GET",
            "server.address": "localhost",
            "url.scheme": "http",
            "server.port": 8000,
            "url.full": "http://localhost:8000/?param=hello",
            "server.socket.address": "127.0.0.1",
            "network.protocol.version": "1.1",
            "http.response.status_code": 200
        },
        "events": [],
        "links": []
    }

The last output shows spans automatically generated by the OpenTelemetry Django Instrumentation package.

## Disabling Django Instrumentation

Django’s instrumentation can be disabled by setting the following environment variable:

`export OTEL_PYTHON_DJANGO_INSTRUMENT=False`

## Auto Instrumentation

This same example can be run using auto instrumentation. Comment out the call to `DjangoInstrumentor().instrument()` in `main`, then Run the django app with `opentelemetry-instrument python manage.py runserver --noreload`. Repeat the steps with the client, the result should be the same.

## Usage with Auto Instrumentation and uWSGI

uWSGI and Django can be used together with auto instrumentation. To do so, first install uWSGI in the previous virtual environment:

`pip install uwsgi`

Once that is done, run the server with `uwsgi` from the directory that contains `instrumentation_example`:

`opentelemetry-instrument uwsgi --http :8000 --module instrumentation_example.wsgi`

This should start one uWSGI worker in your console. Open up a browser and point it to `localhost:8000`. This request should display a span exported in the server console.

## References

- Django

- OpenTelemetry Project

- OpenTelemetry Django extension