Skip to content
This repository was archived by the owner on Jul 21, 2021. It is now read-only.

Commit 6f77b6f

Browse files
author
Ben Sigelman
committed
Automated commit
1 parent 902fc16 commit 6f77b6f

File tree

14 files changed

+311
-312
lines changed

14 files changed

+311
-312
lines changed

README.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
1-
# api-python
1+
# LightStep OpenTracing Bindings
2+
3+
This library is the LightStep binding for [OpenTracing](http://opentracing.io/). See the [OpenTracing Python API](https://github.com/opentracing/opentracing-python) for additional detail.
24

35
* [Installation](#installation)
46
* [Getting Started](#getting-started)
57

68
## Installation
79

8-
```
10+
```bash
911
apt-get install python-dev
1012
pip install lightstep
1113
```
1214

13-
**Important Note:**: The LightStep secure connection uses [Server Name Identification (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication#No_support). This requires Python 2.7.9 or greater.
14-
15-
1615
## Getting Started
1716

18-
LightStep implements [The OpenTracing Project's](http://opentracing.io/) [Python API](https://github.com/opentracing/opentracing-python)
19-
2017
Please see the [example programs](examples/) for examples of how to use this library.
2118
In particular:
2219
* [Trivial Example](examples/trivial/main.py) shows how to use the library on a single host.
@@ -27,7 +24,8 @@ Or if your python code is already instrumented for OpenTracing, you can simply s
2724
```python
2825
import lightstep.tracer
2926

30-
opentracing.tracer = lightstep.tracer.init_tracer(access_token='{your_access_token}')
27+
opentracing.tracer = lightstep.tracer.init_tracer(
28+
access_token='{your_access_token}')
3129
```
3230

3331
## License

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.48
1+
2.0.1

examples/docker/README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
Run `run_all.sh` to launch `../trivial/main.py` in Docker containers of various versions. It will install the latest published LightStep library in the container.
2-
3-
This is a fairly manual test at the moment and the command line / logs / LightStep web UI need to be scanned to see if there were any errors -- but it's better than nothing!
1+
Run `run_all.sh` to launch `../trivial/main.py` in Docker containers with various versions of Python. It will install the latest published LightStep library in the container.

examples/docker/_start.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
pip install lightstep
2-
python trivial/main.py --token "{your_access_token}" --host "api.traceguide.io"
2+
python trivial/main.py --token "{your_access_token}" --host "collector.lightstep.com"

examples/http/context_in_headers.py

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import opentracing
1818
import opentracing.ext.tags
1919

20-
import lightstep.helpers
2120
import lightstep.tracer
2221

2322
class RemoteHandler(BaseHTTPRequestHandler):
@@ -26,54 +25,57 @@ class RemoteHandler(BaseHTTPRequestHandler):
2625
def do_GET(self):
2726
with before_answering_request(self, opentracing.tracer) as server_span:
2827

29-
server_span.info('Received request for %s', self.path)
28+
server_span.log_event('request received', self.path)
3029

3130
self.send_response(200)
3231
self.send_header('Content-type', 'text/html')
3332
self.end_headers()
3433
self.wfile.write("Hello World!")
3534

36-
server_span.info('Finished preparing response for %s', self.path)
35+
server_span.log_event('prepared response', self.path)
3736

3837

3938
def before_sending_request(request, parent_span):
4039
"""Context manager creates Span and encodes the span's TraceContext into request.
4140
"""
4241
operation = 'Sending request'
43-
if parent_span is None:
44-
span = opentracing.tracer.start_trace(operation_name=operation)
45-
else:
46-
span = parent_span.start_child(operation_name=operation)
47-
42+
span = opentracing.tracer.start_span(operation_name=operation, parent=parent_span)
4843
span.set_tag('server.http.url', request.get_full_url())
4944
host = request.get_host()
5045
if host:
5146
span.set_tag(opentracing.ext.tags.PEER_HOST_IPV4, host)
5247

53-
lightstep.helpers.trace_context_writer(span.trace_context,
54-
opentracing.tracer,
55-
add=request.add_header)
48+
text_carrier = opentracing.SplitTextCarrier()
49+
span.tracer.injector(opentracing.Format.SPLIT_TEXT).inject_span(
50+
span, text_carrier)
51+
for k, v in text_carrier.tracer_state.iteritems():
52+
request.add_header(k, v)
53+
for k, v in text_carrier.baggage.iteritems():
54+
request.add_header(k, v)
5655
return span
5756

5857

5958
def before_answering_request(handler, tracer):
6059
"""Context manager creates a Span, using TraceContext encoded in handler if possible.
6160
"""
62-
context = lightstep.helpers.trace_context_from_tuples(handler.headers.items(),
63-
opentracing.tracer)
64-
operation = 'Answering request ' + handler.path
65-
if context is None:
61+
operation = 'handle_request:' + handler.path
62+
text_carrier = opentracing.SplitTextCarrier()
63+
plain_text_map = {}
64+
for k, v in handler.headers.items():
65+
plain_text_map[k.lower()] = v # inefficient and possibly unnecessary...
66+
text_carrier.tracer_state = plain_text_map
67+
text_carrier.baggage = plain_text_map
68+
span = tracer.extractor(opentracing.Format.SPLIT_TEXT).join_trace(
69+
operation, text_carrier)
70+
71+
if span is None:
6672
print 'ERROR: Context missing, starting new trace'
6773
global _exit_code
6874
_exit_code = errno.ENOMSG
69-
span = tracer.start_trace(operation_name=operation)
75+
span = tracer.start_span(operation_name=operation)
7076
headers = ', '.join({k + '=' + v for k, v in handler.headers.items()})
71-
span.error('Could not extract trace context from http headers: %s', headers)
77+
span.log_event('extraction_failed', headers)
7278
print 'Could not extract trace context from http headers: ' + headers
73-
else:
74-
print 'Context received, joining remote trace'
75-
span = tracer.join_trace(operation_name=operation,
76-
parent_trace_context=context)
7779

7880
host, port = handler.client_address
7981
if host:
@@ -100,13 +102,13 @@ def lightstep_tracer_from_args():
100102
parser = argparse.ArgumentParser()
101103
parser.add_argument('--token', help='Your LightStep access token.')
102104
parser.add_argument('--host', help='The LightStep reporting service host to contact.',
103-
default='localhost')
105+
default='collector.lightstep.com')
104106
parser.add_argument('--port', help='The LightStep reporting service port.',
105-
type=int, default=9997)
107+
type=int, default=443)
106108
parser.add_argument('--use_tls', help='Whether to use TLS for reporting',
107-
type=bool, default=False)
108-
parser.add_argument('--group-name', help='The LightStep runtime group',
109-
default='Python-Opentracing-Remote')
109+
type=bool, default=True)
110+
parser.add_argument('--group_name', help='The LightStep runtime group',
111+
default='context_in_headers_example')
110112
args = parser.parse_args()
111113

112114
if args.use_tls:
@@ -146,13 +148,16 @@ def lightstep_tracer_from_args():
146148
with before_sending_request(request=request,
147149
parent_span=None) as client_span:
148150

149-
client_span.info('About to send request to %s', url)
151+
client_span.log_event('sending request', url)
150152

151153
# Send request to server
152154
response = urllib2.urlopen(request)
153155

154156
response_body = response.read()
155-
client_span.info('Server returned %d: %s', response.code, response_body)
157+
client_span.log_event('server returned', {
158+
"code": response.code,
159+
"body": response_body,
160+
})
156161

157162
print 'Server returned ' + str(response.code) + ': ' + response_body
158163

examples/trivial/main.py

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,27 @@ def sleep_dot():
1919
def add_spans():
2020
"""Calls the opentracing API, doesn't use any LightStep-specific code.
2121
"""
22-
with opentracing.tracer.start_trace(operation_name='trivial/initial_request') as parent_span:
22+
with opentracing.tracer.start_span(operation_name='trivial/initial_request') as parent_span:
2323
parent_span.set_tag('url', 'localhost')
2424
sleep_dot()
25-
parent_span.info('All good here! N=%d, flt=%f, string=%s', 42, 3.14, 'xyz')
25+
parent_span.log_event('All good here!', payload={'N': 42, 'pi': 3.14, 'abc': 'xyz'})
2626
parent_span.set_tag('span_type', 'parent')
27+
parent_span.set_baggage_item('checked', 'baggage')
2728
sleep_dot()
2829

2930
# This is how you would represent starting work locally.
30-
with parent_span.start_child(operation_name='trivial/child_request') as child_span:
31-
child_span.error('Uh Oh! N=%d, flt=%f, string=%s', 42, 3.14, 'xyz')
31+
with opentracing.start_child_span(parent_span, operation_name='trivial/child_request') as child_span:
32+
child_span.log_event('Uh Oh!', payload={'error': True})
3233
child_span.set_tag('span_type', 'child')
3334
sleep_dot()
3435

3536
# To connect remote calls, pass a trace context down the wire.
36-
trace_context = child_span.trace_context
37-
with opentracing.tracer.join_trace(operation_name='trivial/remote_span',
38-
parent_trace_context=trace_context) as remote_span:
39-
remote_span.info('Remote! N=%d, flt=%f, string=%s', 42, 3.14, 'xyz')
37+
split_text_carrier = opentracing.SplitTextCarrier()
38+
opentracing.tracer.injector(opentracing.Format.SPLIT_TEXT).inject_span(
39+
child_span, split_text_carrier)
40+
with opentracing.tracer.extractor(opentracing.Format.SPLIT_TEXT).join_trace(
41+
'trivial/remote_span', split_text_carrier) as remote_span:
42+
remote_span.log_event('Remote!')
4043
remote_span.set_tag('span_type', 'remote')
4144
sleep_dot()
4245

@@ -48,11 +51,11 @@ def lightstep_tracer_from_args():
4851
parser = argparse.ArgumentParser()
4952
parser.add_argument('--token', help='Your LightStep access token.')
5053
parser.add_argument('--host', help='The LightStep reporting service host to contact.',
51-
default='localhost')
54+
default='collector.lightstep.com')
5255
parser.add_argument('--port', help='The LightStep reporting service port.',
53-
type=int, default=9997)
56+
type=int, default=443)
5457
parser.add_argument('--use_tls', help='Whether to use TLS for reporting',
55-
type=bool, default=False)
58+
type=bool, default=True)
5659
parser.add_argument('--group-name', help='The LightStep runtime group',
5760
default='Python-Opentracing-Remote')
5861
args = parser.parse_args()
@@ -76,18 +79,25 @@ def lightstep_tracer_from_args():
7679
print 'Hello '
7780

7881
# Use opentracing's default no-op implementation
79-
with contextlib.closing(opentracing.Tracer()) as impl:
80-
opentracing.tracer = impl
82+
opentracing.tracer = opentracing.Tracer()
83+
try:
8184
add_spans()
85+
finally:
86+
opentracing.tracer.flush()
8287

83-
#Use LightStep's debug tracer, which logs to the console instead of reporting to LightStep.
84-
with contextlib.closing(lightstep.tracer.init_debug_tracer()) as impl:
85-
opentracing.tracer = impl
88+
# Use LightStep's debug tracer, which logs to the console instead of
89+
# reporting to LightStep.
90+
opentracing.tracer = lightstep.tracer.init_debug_tracer()
91+
try:
8692
add_spans()
93+
finally:
94+
opentracing.tracer.flush()
8795

8896
# Use LightStep's opentracing implementation
89-
with contextlib.closing(lightstep_tracer_from_args()) as impl:
90-
opentracing.tracer = impl
97+
opentracing.tracer = lightstep_tracer_from_args()
98+
try:
9199
add_spans()
100+
finally:
101+
opentracing.tracer.flush()
92102

93103
print 'World!'

lightstep/connection.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
from .crouton import ReportingService
88

99
class _Connection(object):
10-
""" Instances of _Connection are used to establish a connection to
11-
the server via HTTP protocol.
10+
"""Instances of _Connection are used to establish a connection to the
11+
server via HTTP protocol.
1212
13-
This class is NOT THREADSAFE.
13+
This class is NOT THREADSAFE and access must by synchronized externally.
1414
"""
1515
def __init__(self, service_url):
1616
self._service_url = service_url
@@ -20,9 +20,10 @@ def __init__(self, service_url):
2020
self._report_exceptions_count = 0
2121

2222
def open(self):
23-
""" Establish HTTP connection to the server.
24-
Note: THttpClient also supports https and will use http/https
25-
according to the scheme in the URL it is given.
23+
"""Establish HTTP connection to the server.
24+
25+
Note: THttpClient also supports https and will use http/https according
26+
to the scheme in the URL it is given.
2627
"""
2728
try:
2829
self._transport = THttpClient.THttpClient(self._service_url)
@@ -36,15 +37,14 @@ def open(self):
3637

3738

3839
def report(self, *args, **kwargs):
39-
""" Report to the server."""
40-
# Notice the annoying case change on the method name.
41-
# I chose to stay consistent with casing in this class
42-
# vs staying consistent with the casing of the pass-through method.
40+
"""Report to the server."""
41+
# Notice the annoying case change on the method name. I chose to stay
42+
# consistent with casing in this class vs staying consistent with the
43+
# casing of the pass-through method.
4344
return self._client.Report(*args, **kwargs)
4445

4546
def close(self):
46-
""" Close HTTP connection to the server.
47-
"""
47+
"""Close HTTP connection to the server."""
4848
if self._transport is None:
4949
return
5050
if self._client is None:

lightstep/constants.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
""" Constants
2-
"""
1+
"""Constants"""
32

43
# Runtime constants
54
FLUSH_THREAD_NAME = 'Flush Thread'

lightstep/helpers.py

Lines changed: 0 additions & 38 deletions
This file was deleted.

0 commit comments

Comments
 (0)