|
| 1 | +# Python3 Flask Instrumentation |
| 2 | +In this doc I identify the following issues with the [OTel Python getting started docs](https://opentelemetry.io/docs/instrumentation/python/getting-started/): |
| 3 | +- 🔔 auto-instrumentation is broken on main:latest, even for `flask<3` |
| 4 | + |
| 5 | +After the supporting analysis of [the logs](./demo.log), there is a proposal for working getting started instructions. |
| 6 | + |
| 7 | +# Current getting started instructions |
| 8 | + |
| 9 | +### On macOS with Python 3.11.6 |
| 10 | +#### pip freeze |
| 11 | +Running `pip install 'flask<3'` from a clean venv yields: |
| 12 | +``` |
| 13 | +blinker==1.7.0 |
| 14 | +click==8.1.7 |
| 15 | +Flask==2.3.3 |
| 16 | +itsdangerous==2.1.2 |
| 17 | +Jinja2==3.1.2 |
| 18 | +MarkupSafe==2.1.3 |
| 19 | +Werkzeug==3.0.1 |
| 20 | +``` |
| 21 | + |
| 22 | +## Current setup |
| 23 | +In the [auto-instrumentation section of the OTel Python docs](https://opentelemetry.io/docs/instrumentation/python/getting-started/#instrumentation) have setup instructions that say: |
| 24 | +```sh |
| 25 | +pip install opentelemetry-distro |
| 26 | +opentelemetry-bootsrap -a install |
| 27 | +``` |
| 28 | + |
| 29 | +### Replicating the setup instructions |
| 30 | +#### Input |
| 31 | +Run the server as in the docs: |
| 32 | +```sh |
| 33 | +OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true \ |
| 34 | + opentelemetry-instrument \ |
| 35 | + --traces_exporter console \ |
| 36 | + --metrics_exporter console \ |
| 37 | + --logs_exporter console \ |
| 38 | + --service_name dice-server \ |
| 39 | + flask run -p 8080 | demo.log |
| 40 | +``` |
| 41 | +^ notice the output tee'd to demo.log, that will be used to quantify claims. I've included [sample logs in this repo](./demo.log), with the "* Debug mode: off" line removed so the reader can `jq < demo.log` for more detail. |
| 42 | + |
| 43 | +#### curl a few times |
| 44 | +in Bash: |
| 45 | +```sh |
| 46 | +for i in {1..3}; do curl http://localhost:8080/rolldice; done |
| 47 | +``` |
| 48 | +or in Fish |
| 49 | +```sh |
| 50 | +for i in (seq 1 128); curl http://localhost:8080/rolldice; end |
| 51 | +``` |
| 52 | +
|
| 53 | +#### Output |
| 54 | +```json |
| 55 | + { |
| 56 | + "body": "Anonymous player is rolling the dice: 5", |
| 57 | + "severity_number": "<SeverityNumber.WARN: 13>", |
| 58 | + "severity_text": "WARNING", |
| 59 | + "attributes": { |
| 60 | + "otelSpanID": "0", |
| 61 | + "otelTraceID": "0", |
| 62 | + "otelTraceSampled": false, |
| 63 | + "otelServiceName": "dice-server" |
| 64 | + }, |
| 65 | + "dropped_attributes": 0, |
| 66 | + "timestamp": "2023-12-06T18:31:18.219932Z", |
| 67 | + "trace_id": "0x00000000000000000000000000000000", |
| 68 | + "span_id": "0x0000000000000000", |
| 69 | + "trace_flags": 0, |
| 70 | + "resource": "BoundedAttributes({'telemetry.sdk.language': 'python', 'telemetry.sdk.name': 'opentelemetry', 'telemetry.sdk.version': '1.21.0', 'service.name': 'dice-server', 'telemetry.auto.version': '0.42b0'}, maxlen=None)" |
| 71 | +} |
| 72 | +``` |
| 73 | +^ note "trace_id" and "span_id" `0x00...` with ID attrs `"0"` in the trace of the /rolldice endpoint. |
| 74 | +
|
| 75 | +notice the versions used: |
| 76 | +- `sdk.version: 1.21.0` |
| 77 | +- `auto.version: 0.42b0` |
| 78 | +
|
| 79 | +#### 💢 Docs claim (1): trace and span IDs will be populated |
| 80 | +
|
| 81 | +##### When tested on latest |
| 82 | +The traces and spans are zeroed out. |
| 83 | +
|
| 84 | +##### Documentation excerpt |
| 85 | +In the [OTel getting started docs](https://opentelemetry.io/docs/instrumentation/python/getting-started/#run-the-instrumented-app), dropping down the _expected output_ section, the docs show non-zero trace and span IDs: |
| 86 | +```json |
| 87 | +{ |
| 88 | + "body": "Anonymous player is rolling the dice: 3", |
| 89 | + "severity_number": "<SeverityNumber.WARN: 13>", |
| 90 | + "severity_text": "WARNING", |
| 91 | + "attributes": { |
| 92 | + "otelSpanID": "5c2b0f851030d17d", |
| 93 | + "otelTraceID": "db1fc322141e64eb84f5bd8a8b1c6d1f", |
| 94 | + "otelServiceName": "dice-server" |
| 95 | + }, |
| 96 | + "timestamp": "2023-10-10T08:14:32.631195Z", |
| 97 | + "trace_id": "0xdb1fc322141e64eb84f5bd8a8b1c6d1f", |
| 98 | + "span_id": "0x5c2b0f851030d17d", |
| 99 | + "trace_flags": 1, |
| 100 | + "resource": "BoundedAttributes({'telemetry.sdk.language': 'python', 'telemetry.sdk.name': 'opentelemetry', 'telemetry.sdk.version': '1.17.0', 'service.name': 'dice-server', 'telemetry.auto.version': '0.38b0'}, maxlen=None)" |
| 101 | +} |
| 102 | +``` |
| 103 | +^ notice the populated trace and span IDs. The reader may also notice the different versions of the SDK. I'm not sure if that aught to matter vis the instructions in the docs. |
| 104 | +versions in docs: |
| 105 | +- `sdk.version: 1.17.0` |
| 106 | +- `auto.version: 0.38b0` |
| 107 | +
|
| 108 | +The versions in the docs are not latest, which will be installed by following `pip install opentelemetry-distro` as stated in docs. |
| 109 | +
|
| 110 | +#### 💢 Docs claim (2): http attributes will be populated |
| 111 | +
|
| 112 | +##### When tested on latest |
| 113 | +The speified cattributes are missing entirely. |
| 114 | +
|
| 115 | +##### Documentation excerpt |
| 116 | +The docs in the same section as (1) above also claim: |
| 117 | +```json |
| 118 | + "attributes": { |
| 119 | + "http.method": "GET", |
| 120 | + "http.server_name": "127.0.0.1", |
| 121 | + "http.scheme": "http", |
| 122 | + "net.host.port": 8080, |
| 123 | + "http.host": "localhost:8080", |
| 124 | + "http.target": "/rolldice?rolls=12", |
| 125 | + "net.peer.ip": "127.0.0.1", |
| 126 | + "http.user_agent": "curl/8.1.2", |
| 127 | + "net.peer.port": 58419, |
| 128 | + "http.flavor": "1.1", |
| 129 | + "http.route": "/rolldice", |
| 130 | + "http.status_code": 200 |
| 131 | + }, |
| 132 | +``` |
| 133 | +^ these logs should appear. However `grep "http\.method" < demo.log` yields no results. |
| 134 | +
|
| 135 | +#### 💢 Docs claim (3): request duration will be measured with a histogram |
| 136 | +
|
| 137 | +##### When tested on latest |
| 138 | +The histogram is missing entirely. |
| 139 | +
|
| 140 | +##### Documentation excerpt |
| 141 | +The docs claim we'll see this output, under the second _View example output_ dropdown. |
| 142 | +```json |
| 143 | + "data": { |
| 144 | + "aggregation_temporality": 2, |
| 145 | + "data_points": [ |
| 146 | + { |
| 147 | + "attributes": { |
| 148 | + "http.flavor": "1.1", |
| 149 | + "http.host": "localhost:5000", |
| 150 | + "http.method": "GET", |
| 151 | + "http.scheme": "http", |
| 152 | + "http.server_name": "127.0.0.1", |
| 153 | + "http.status_code": 200, |
| 154 | + "net.host.port": 5000 |
| 155 | + }, |
| 156 | + "bucket_counts": [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
| 157 | + "count": 1, |
| 158 | + "explicit_bounds": [ |
| 159 | + 0, 5, 10, 25, 50, 75, 100, 250, 500, 1000 |
| 160 | + ], |
| 161 | + "max": 1, |
| 162 | + "min": 1, |
| 163 | + "start_time_unix_nano": 1666077040063027610, |
| 164 | + "sum": 1, |
| 165 | + "time_unix_nano": 1666077098181107419, |
| 166 | +``` |
| 167 | +
|
| 168 | +### Current setup docs issue summary |
| 169 | +- Auto-instrumentation is broken, even for `flask<3`. |
| 170 | +
|
| 171 | +# Proposed getting started instructions |
| 172 | +With a Python3 > 3.6 installation, in Fish:jh |
| 173 | +```sh |
| 174 | +python3 -m venv venv |
| 175 | +source venv/bin/activate.fish |
| 176 | +pip install 'werkzeug<3' |
| 177 | +pip install 'flask<3' |
| 178 | +pip install opentelemetry-distro |
| 179 | +pip install opentelemetry-instrumentation-flask |
| 180 | +``` |
| 181 | +^ run pip installs verbosely like this because pip does not use argument order. |
| 182 | +
|
| 183 | +Doing so yields: |
| 184 | +``` |
| 185 | +Flask==2.3.3 |
| 186 | +Werkzeug==2.3.8 |
| 187 | +``` |
| 188 | +
|
| 189 | +... proposal under construction ... |
| 190 | +
|
| 191 | +## Server |
| 192 | +```sh |
| 193 | +flask run -p 8080 |
| 194 | +``` |
| 195 | +
|
| 196 | +## Client |
| 197 | +```sh |
| 198 | +curl http://localhost:8080/rolldice |
| 199 | +``` |
| 200 | +
|
| 201 | +### Expected result |
| 202 | +You should get random numbers between 1 and 6 immediately. |
0 commit comments