Skip to content

Commit 27a7b71

Browse files
author
alrex
authored
Add lightstep.hostname tag (#98)
* adding lightstep.hostname tag
1 parent 1c94520 commit 27a7b71

File tree

3 files changed

+143
-116
lines changed

3 files changed

+143
-116
lines changed

lightstep/http_converter.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import socket
2+
import sys
3+
14
from lightstep.collector_pb2 import Auth, ReportRequest, Span, Reporter, KeyValue, Reference, SpanContext
25
from lightstep.converter import Converter
36
from . import util
47
from . import version as tracer_version
5-
import sys
68
from google.protobuf.timestamp_pb2 import Timestamp
79

810

@@ -22,6 +24,7 @@ def create_runtime(self, component_name, tags, guid):
2224
if tags is None:
2325
tags = {}
2426
tracer_tags = tags.copy()
27+
tracer_tags['lightstep.hostname'] = tracer_tags.get('lightstep.hostname', socket.gethostname())
2528

2629
tracer_tags.update({
2730
'lightstep.tracer_platform': 'python',

lightstep/thrift_converter.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import socket
2+
import sys
3+
14
from lightstep import constants
25
from lightstep.converter import Converter
36
from .crouton import ttypes
4-
import sys
57
from . import util
68
from . import version as tracer_version
79
import jsonpickle
@@ -22,6 +24,7 @@ def create_runtime(self, component_name, tags, guid):
2224
if tags is None:
2325
tags = {}
2426
tracer_tags = tags.copy()
27+
tracer_tags['lightstep.hostname'] = tracer_tags.get('lightstep.hostname', socket.gethostname())
2528

2629
tracer_tags.update({
2730
'lightstep.tracer_platform': 'python',

tests/recorder_test.py

+135-114
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import socket
12
import time
23
import unittest
34

@@ -15,6 +16,7 @@
1516
class MockConnection(object):
1617
"""MockConnection is used to debug and test Runtime.
1718
"""
19+
1820
def __init__(self):
1921
self.reports = []
2022
self.ready = False
@@ -40,121 +42,140 @@ def clear(self):
4042

4143
@pytest.fixture(params=[True, False])
4244
def recorder(request):
43-
runtime_args = {'collector_encryption': 'none',
44-
'collector_host': 'localhost',
45-
'collector_port': 9998,
46-
'access_token': '{your_access_token}',
47-
'component_name': 'python/runtime_test',
48-
'periodic_flush_seconds': 0,
49-
'use_thrift': request.param,
50-
'use_http': not request.param}
51-
recorder = lightstep.recorder.Recorder(runtime_args)
52-
yield recorder
53-
54-
55-
# ------_
56-
# HELPERS
57-
# ------_
58-
def check_spans(converter, report):
59-
"""Checks spans' name.
60-
"""
61-
def setUp(self):
62-
self.mock_connection = MockConnection()
63-
self.mock_connection.open()
64-
self.runtime_args = {'collector_encryption': 'none',
65-
'collector_host': 'localhost',
66-
'collector_port': 9998,
67-
'access_token': '{your_access_token}',
68-
'component_name': 'python/runtime_test',
69-
'periodic_flush_seconds': 0}
70-
71-
def create_test_recorder(self):
72-
"""Returns a LightStep Recorder based on self.runtime_args.
73-
"""
74-
return lightstep.recorder.Recorder(**self.runtime_args)
75-
76-
# -------------
77-
# SHUTDOWN TESTS
78-
# -------------
79-
def test_send_spans_after_shutdown(self):
80-
recorder = self.create_test_recorder()
81-
82-
# Send 10 spans
83-
for i in range(10):
84-
recorder.record_span(self.dummy_basic_span(recorder, i))
85-
self.assertTrue(recorder.flush(self.mock_connection))
86-
87-
# Check 10 spans
88-
self.check_spans(self.mock_connection.reports[0].span_records)
89-
90-
# Delete current logs and shutdown runtime
91-
self.mock_connection.clear()
92-
recorder.shutdown()
93-
94-
# Send 10 spans, though none should get through
95-
for i in range(10):
96-
recorder.record_span(self.dummy_basic_span(recorder, i))
97-
self.assertFalse(recorder.flush(self.mock_connection))
98-
self.assertEqual(len(self.mock_connection.reports), 0)
99-
100-
def test_shutdown_twice(self):
101-
recorder = self.create_test_recorder()
45+
runtime_args = {
46+
"collector_encryption": "none",
47+
"collector_host": "localhost",
48+
"collector_port": 9998,
49+
"access_token": "{your_access_token}",
50+
"component_name": "python/runtime_test",
51+
"periodic_flush_seconds": 0,
52+
"use_thrift": request.param,
53+
"use_http": not request.param,
54+
}
55+
yield lightstep.recorder.Recorder(**runtime_args)
56+
57+
58+
def test_default_tags_set_correctly(recorder):
59+
mock_connection = MockConnection()
60+
mock_connection.open()
61+
tags = getattr(recorder._runtime, "tags", None)
62+
if tags is None:
63+
tags = getattr(recorder._runtime, "attrs")
64+
for tag in tags:
65+
if hasattr(tag, "key"):
66+
if tag.key == "lightstep.hostname":
67+
assert tag.string_value == socket.gethostname()
68+
elif tag.key == "lightstep.tracer_platform":
69+
assert tag.string_value == "python"
70+
else:
71+
if tag.Key == "lightstep.hostname":
72+
assert tag.Value == socket.gethostname()
73+
elif tag.Key == "lightstep.tracer_platform":
74+
assert tag.Value == "python"
75+
assert len(tags) == 6
76+
runtime_args = {
77+
"collector_encryption": "none",
78+
"collector_host": "localhost",
79+
"collector_port": 9998,
80+
"access_token": "{your_access_token}",
81+
"component_name": "python/runtime_test",
82+
"periodic_flush_seconds": 0,
83+
"tags": {
84+
"lightstep.hostname": "hostname",
85+
},
86+
}
87+
new_recorder = lightstep.recorder.Recorder(**runtime_args)
88+
for tag in new_recorder._runtime.tags:
89+
if tag.key == "lightstep.hostname":
90+
assert tag.string_value == "hostname"
91+
assert len(new_recorder._runtime.tags) == 6
92+
93+
94+
# --------------
95+
# SHUTDOWN TESTS
96+
# --------------
97+
def test_send_spans_after_shutdown(recorder):
98+
mock_connection = MockConnection()
99+
mock_connection.open()
100+
# Send 10 spans
101+
for i in range(10):
102+
dummy_basic_span(recorder, i)
103+
assert recorder.flush(mock_connection)
104+
105+
# Check 10 spans
106+
check_spans(recorder.converter, mock_connection.reports[0])
107+
108+
# Delete current logs and shutdown runtime
109+
mock_connection.clear()
110+
recorder.shutdown()
111+
112+
# Send 10 spans, though none should get through
113+
for i in range(10):
114+
recorder.record_span(dummy_basic_span(recorder, i))
115+
assert not recorder.flush(mock_connection)
116+
assert len(mock_connection.reports) == 0
117+
118+
119+
def test_shutdown_twice(recorder):
120+
try:
102121
recorder.shutdown()
103122
recorder.shutdown()
123+
except Exception as error:
124+
self.fail("Unexpected exception raised: {}".format(error))
125+
126+
127+
# ------------
128+
# STRESS TESTS
129+
# ------------
130+
def test_stress_logs(recorder):
131+
mock_connection = MockConnection()
132+
mock_connection.open()
133+
for i in range(1000):
134+
dummy_basic_span(recorder, i)
135+
assert recorder.flush(mock_connection)
136+
assert recorder.converter.num_span_records(mock_connection.reports[0]) == 1000
137+
check_spans(recorder.converter, mock_connection.reports[0])
138+
139+
140+
def test_stress_spans(recorder):
141+
mock_connection = MockConnection()
142+
mock_connection.open()
143+
for i in range(1000):
144+
dummy_basic_span(recorder, i)
145+
assert recorder.flush(mock_connection)
146+
assert recorder.converter.num_span_records(mock_connection.reports[0]) == 1000
147+
check_spans(recorder.converter, mock_connection.reports[0])
148+
149+
150+
# -------------
151+
# RUNTIME TESTS
152+
# -------------
153+
def test_buffer_limits(recorder):
154+
mock_connection = MockConnection()
155+
mock_connection.open()
156+
recorder._max_span_records = 88
157+
158+
assert len(recorder._span_records) == 0
159+
for i in range(0, 100):
160+
dummy_basic_span(recorder, i)
161+
assert len(recorder._span_records) == 88
162+
assert recorder.flush(mock_connection)
104163

105-
# ------------
106-
# STRESS TESTS
107-
# ------------
108-
def test_stress_logs(self):
109-
recorder = self.create_test_recorder()
110-
for i in range(1000):
111-
recorder.record_span(self.dummy_basic_span(recorder, i))
112-
self.assertTrue(recorder.flush(self.mock_connection))
113-
self.assertEqual(len(self.mock_connection.reports[0].span_records), 1000)
114-
self.check_spans(self.mock_connection.reports[0].span_records)
115-
116-
def test_stress_spans(self):
117-
recorder = self.create_test_recorder()
118-
for i in range(1000):
119-
recorder.record_span(self.dummy_basic_span(recorder, i))
120-
self.assertTrue(recorder.flush(self.mock_connection))
121-
self.assertEqual(len(self.mock_connection.reports[0].span_records), 1000)
122-
self.check_spans(self.mock_connection.reports[0].span_records)
123-
124-
# -------------
125-
# RUNTIME TESTS
126-
# -------------
127-
128-
def test_buffer_limits(self):
129-
self.runtime_args.update({
130-
'max_span_records': 88,
131-
})
132-
recorder = self.create_test_recorder()
133-
134-
self.assertEqual(len(recorder._span_records), 0)
135-
for i in range(0, 10000):
136-
recorder.record_span(self.dummy_basic_span(recorder, i))
137-
self.assertEqual(len(recorder._span_records), 88)
138-
self.assertTrue(recorder.flush(self.mock_connection))
139-
140-
# ------
141-
# HELPER
142-
# ------
143-
def check_spans(self, spans):
144-
"""Checks spans' name.
145-
"""
146-
for i, span in enumerate(spans):
147-
self.assertEqual(span.span_name, str(i))
148-
149-
def dummy_basic_span(self, recorder, i):
150-
return BasicSpan(
151-
lightstep.tracer._LightstepTracer(False, recorder, None),
152-
operation_name=str(i),
153-
context=SpanContext(
154-
trace_id=1000+i,
155-
span_id=2000+i),
156-
start_time=time.time())
157164

158-
159-
if __name__ == '__main__':
160-
unittest.main()
165+
def check_spans(converter, report):
166+
"""Checks spans' name.
167+
"""
168+
spans = converter.get_span_records(report)
169+
for i, span in enumerate(spans):
170+
assert converter.get_span_name(span) == str(i)
171+
172+
173+
def dummy_basic_span(recorder, i):
174+
span = BasicSpan(
175+
lightstep.tracer._LightstepTracer(False, recorder, None),
176+
operation_name=str(i),
177+
context=SpanContext(trace_id=1000 + i, span_id=2000 + i),
178+
start_time=time.time() - 100,
179+
)
180+
span.finish()
181+
return span

0 commit comments

Comments
 (0)