Skip to content

Commit 618daa1

Browse files
committed
added README
1 parent 6e2ba7a commit 618daa1

File tree

9 files changed

+83
-81
lines changed

9 files changed

+83
-81
lines changed

example/README.md

+53-46
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,81 @@
11
## Example
22

3-
This example has a flask client and server and shows they can trace requests
4-
both within and between the two sites using the flask_opentracing extension and
3+
This example has a flask client and server and shows how to trace the requests
4+
to a webserver from a client using the flask_opentracing extension and
55
a concrete variant of an OpenTracing tracer. To run, make sure that you run pip
6-
install for flask, opentracing, and lightstep (although you will not be able to
7-
view the lightstep traces unless you have an access token).
6+
install for flask, opentracing, jaeger_client.
87

9-
Open two terminals and navigate to this directory. Run the following commands in
10-
each terminal:
8+
### Set up Jaeger:
119

12-
First window:
10+
First, we'll have to download and run our Jaeger instance. It collects and displays
11+
traces in neat graphical format.
1312

14-
```
15-
> export FLASK_APP=server.py
16-
> flask run
13+
If you already have Docker installed, run this:
14+
15+
```
16+
docker run -d -e \
17+
COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
18+
-p 5775:5775/udp \
19+
-p 6831:6831/udp \
20+
-p 6832:6832/udp \
21+
-p 5778:5778 \
22+
-p 16686:16686 \
23+
-p 14268:14268 \
24+
-p 9411:9411 \
25+
jaegertracing/all-in-one:latest
1726
```
1827

19-
Second window:
28+
You should be able to see a web interface by browsing to http://localhost:16686/search
2029

21-
```
22-
> export FLASK_APP=client.py
23-
> flask run --port=0
30+
![traced request](https://raw.githubusercontent.com/opentracing-contrib/python-flask/example/example/img/jaeger_0.png)
31+
32+
Now, open two terminals and navigate to this directory. Run the following commands in
33+
each terminal:
34+
35+
First window:
36+
37+
```
38+
> python3 server.py
2439
```
2540

26-
To test the traces, check what port the client is running on and load
27-
localhost:port. If you have a lightstep tracer token, you
28-
should be able to view the trace data on the lightstep interface.
29-
(NOTE: if you wish to use a different OpenTracing tracer, simply replace
30-
`ls_tracer` with the OpenTracing tracer instance of your choice.)
41+
Give it few seconds to start and run this in second window:
3142

32-
### Trace a request:
43+
```
44+
> python3 client.py
45+
```
3346

34-
Navigate to `/request/simple/<int:numrequests>` where numrequests is the number
35-
of requests you want to send to the page. This will send a request to the server
36-
app, and the trace will include a span on both the client and server sides. This
37-
occurs automatically since both the client and server functions are decorated
38-
with @tracer.trace().
47+
To see the traced requests, go to Jaeger web interface.
48+
Select your service name from dropdown on the left (it's
49+
"jaeger_opentracing_example" in our case) and press Find traces button at the bottom of the page.
3950

40-
Result for `/request/simple/1`:
4151

42-
![request and response spans](https://raw.githubusercontent.com/kcamenzind/flask_opentracing/master/example/img/simple.png)
52+
![traced request](https://raw.githubusercontent.com/opentracing-contrib/python-flask/example/example/img/jaeger.png)
4353

44-
### Log something to a request:
4554

46-
Navigate to `/log`. This will log a message to the server-side span. The client
47-
span is created automatically through the @tracer.trace() decorator, while the
48-
logging occurs within the function by accessing the current span as follows:
55+
(NOTE: if you wish to use a different OpenTracing tracer instead of Jaeger, simply replace
56+
`jaeger_tracer` with the OpenTracing tracer instance of your choice.)
4957

50-
```python
51-
span = tracer.get_span()
52-
span.log_event("hello world")
53-
```
54-
Result for `/log`:
58+
### Trace a request from browser:
5559

56-
![span with log](https://raw.githubusercontent.com/kcamenzind/flask_opentracing/master/example/img/log.png)
60+
Browse to http://localhost:5000/log and compare the trace in Jaeger.
61+
The last one has 2 spans instead of 3. The span of webserver's GET method is missing.
62+
That is because in client.py we pass already existing span over the wire, whereas the request from your browser has to tracing data in it.
5763

5864
### Add spans to the trace manually:
5965

60-
Navigate to `/request/childspan/<int:numrequests>`. This will send a request to
61-
the server app, and the trace will include a span on both the client and server
62-
sides. The server app will additionally create a child span for the server-side
63-
span. This example demonstrates how you can trace non-RPC function calls in your
64-
app, through accessing the current span as follows:
66+
In log function of the server app, we are creating current_span. This is done to
67+
trace the work that is being done to render the response to /log. Suppose there's
68+
a database connection happening. By creating a separate span for it, you'll be able
69+
to trace the DB request separately from rendering or the response. This gives a
70+
lot of flexibility to the user.
71+
72+
Following code shows how to create a span based on already existing one.
6573

6674
```python
6775
parent_span = tracer.get_span()
68-
child_span = ls_tracer.start_span("inside create_child_span", parent_span)
76+
child_span = jaeger_tracer.start_span("inside create_child_span", parent_span)
6977
... do some stuff
70-
child_span.finish()
78+
child_span.finish()
7179
```
72-
Result for `/request/childspan/2`:
7380

74-
![two child spans](https://raw.githubusercontent.com/kcamenzind/flask_opentracing/master/example/img/childspan.png)
81+
![traced request](https://raw.githubusercontent.com/opentracing-contrib/python-flask/example/example/img/jaeger_1.png)

example/client.py

+10-18
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,27 @@
11
import requests
22
import time
33
from opentracing_instrumentation.client_hooks import install_all_patches
4-
from opentracing_instrumentation.request_context import get_current_span, span_in_context
54
from jaeger_client import Config
6-
from opentracing.ext import tags
7-
from opentracing.propagation import Format
85

9-
from os import environ
6+
from os import getenv
107

11-
JAEGER_HOST = environ.get('JAEGER_HOST')
12-
13-
WEBSERVER_HOST = environ.get('WEBSERVER_HOST')
8+
JAEGER_HOST = getenv('JAEGER_HOST', 'localhost')
9+
WEBSERVER_HOST = getenv('WEBSERVER_HOST', 'localhost')
1410

11+
# Create configuration object with enabled logging and sampling of all requests.
1512
config = Config(config={'sampler': {'type': 'const', 'param': 1},
1613
'logging': True,
1714
'local_agent': {'reporting_host': JAEGER_HOST}},
1815
service_name="jaeger_opentracing_example")
1916
tracer = config.initialize_tracer()
2017

18+
# Automatically trace all requests made with 'requests' library.
2119
install_all_patches()
2220

2321
url = "http://{}:5000/log".format(WEBSERVER_HOST)
24-
with tracer.start_span('say-hello') as span:
25-
span.set_tag(tags.HTTP_METHOD, 'GET')
26-
span.set_tag(tags.HTTP_URL, url)
27-
span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT)
28-
headers = {}
29-
tracer.inject(span, Format.HTTP_HEADERS, headers)
30-
31-
r = requests.get(url, headers=headers)
32-
print(r.text)
22+
# Make the actual request to webserver.
23+
requests.get(url)
3324

34-
time.sleep(2)
35-
tracer.close()
25+
# allow tracer to flush the spans - https://github.com/jaegertracing/jaeger-client-python/issues/50
26+
time.sleep(2)
27+
tracer.close()

example/img/childspan.png

-97.4 KB
Binary file not shown.

example/img/jaeger.png

109 KB
Loading

example/img/jaeger_0.png

81.6 KB
Loading

example/img/jaeger_1.png

35.8 KB
Loading

example/img/log.png

-64.2 KB
Binary file not shown.

example/img/simple.png

-137 KB
Binary file not shown.

example/server.py

+20-17
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,43 @@
1-
import opentracing
21
import logging
32
from jaeger_client import Config
43
from flask_opentracing import FlaskTracer
5-
from opentracing.propagation import Format
64
from flask import Flask, request
7-
from opentracing.ext import tags
8-
from os import environ
9-
10-
JAEGER_HOST = environ.get('JAEGER_HOST')
5+
from os import getenv
6+
JAEGER_HOST = getenv('JAEGER_HOST', 'localhost')
117

128
if __name__ == '__main__':
139
app = Flask(__name__)
1410
log_level = logging.DEBUG
1511
logging.getLogger('').handlers = []
1612
logging.basicConfig(format='%(asctime)s %(message)s', level=log_level)
13+
# Create configuration object with enabled logging and sampling of all requests.
1714
config = Config(config={'sampler': {'type': 'const', 'param': 1},
1815
'logging': True,
1916
'local_agent':
17+
# Also, provide a hostname of Jaeger instance to send traces to.
2018
{'reporting_host': JAEGER_HOST}},
19+
# Service name can be arbitrary string describing this particular web service.
2120
service_name="jaeger_opentracing_example")
22-
ls_tracer = config.initialize_tracer()
23-
tracer = FlaskTracer(ls_tracer)
21+
jaeger_tracer = config.initialize_tracer()
22+
tracer = FlaskTracer(jaeger_tracer)
2423

2524
@app.route('/log')
25+
# Indicate that /log endpoint should be traced
2626
@tracer.trace()
2727
def log():
28+
# Extract the span information for request object.
29+
request_span = tracer.get_span(request)
30+
# Start internal span to trace some kind of business logic for /log.
31+
current_span = jaeger_tracer.start_span("python webserver internal span of log method",
32+
child_of=request_span)
33+
# Perform some computations to be traced.
34+
35+
a = 1
36+
b = 2
37+
c = a + b
2838

29-
span_ctx = ls_tracer.extract(Format.HTTP_HEADERS, request.headers)
30-
print(request.headers)
31-
span_tags = {tags.SPAN_KIND: tags.SPAN_KIND_RPC_SERVER}
32-
print(span_tags)
33-
child_span = ls_tracer.start_span("python webserver internal span of log method",
34-
child_of=span_ctx,
35-
tags=span_tags)
36-
#do some things here
37-
child_span.finish()
39+
# Finish the current span.
40+
current_span.finish()
3841
return "log"
3942

4043
app.run(debug=True, host='0.0.0.0', port=5000)

0 commit comments

Comments
 (0)