Skip to content

Commit 4528a1a

Browse files
authored
Use requests.Session in WavefrontClient (#107)
1 parent 12e883f commit 4528a1a

5 files changed

Lines changed: 108 additions & 96 deletions

File tree

example.py

100644100755
Lines changed: 64 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
#! /usr/bin/env python3
12
"""Wavefront SDK Usage Example."""
23

4+
import platform
35
import sys
46
import time
57
import uuid
@@ -11,68 +13,95 @@
1113
def send_metrics(wavefront_client):
1214
"""Send a metric."""
1315
wavefront_client.send_metric(
14-
'python.proxy.new york.power.usage',
15-
42422.0, None, 'localhost', None)
16+
'python.sdk.example.new_york.power.usage', # metric name (str)
17+
time.time() % 3600, # metric value (float)
18+
None, # metric timestamp (int)
19+
platform.node(), # metric source (str)
20+
{}) # metric tags (dict)
1621

1722

1823
def send_delta_counter(wavefront_client):
1924
"""Send a delta counter."""
2025
wavefront_client.send_delta_counter(
21-
'python.delta.proxy.counter',
22-
1.0, 'localhost', None)
26+
'python.sdk.example.delta.proxy.counter', # counter name (str)
27+
1.0, # counter value (float)
28+
platform.node(), # source name (str)
29+
None) # counter tags (dict)
2330

2431

2532
def send_histogram(wavefront_client):
2633
"""Send a histogram."""
2734
wavefront_client.send_distribution(
28-
'python.proxy.request.latency',
29-
[(30, 20), (5.1, 10)], {histogram_granularity.DAY,
30-
histogram_granularity.HOUR,
31-
histogram_granularity.MINUTE},
32-
None, 'appServer1', {'region': 'us-west'})
35+
'python.sdk.example.request.latency', # histogram name (str)
36+
[(30, 20), (5.1, 10)], # histogram centroids (list)
37+
{histogram_granularity.DAY,
38+
histogram_granularity.HOUR,
39+
histogram_granularity.MINUTE}, # granularities (set)
40+
None, # histogram timestamp (int)
41+
platform.node(), # histogram source (str)
42+
{'region': 'us-west'}) # histogram tags (dict)
3343

3444

3545
def send_tracing_span(wavefront_client):
3646
"""Send a tracing span."""
3747
wavefront_client.send_span(
38-
'getAllUsersFromPythonProxy', 1533529977, 343500, 'localhost',
39-
uuid.UUID('7b3bf470-9456-11e8-9eb6-529269fb1459'),
40-
uuid.UUID('0313bafe-9457-11e8-9eb6-529269fb1459'),
41-
[uuid.UUID('2f64e538-9457-11e8-9eb6-529269fb1459')], None,
42-
[('application', 'Wavefront'),
43-
('http.method', 'GET')], None)
48+
'getAllUsersFromPythonProxy', # span name (str)
49+
1533529977, # start milliseconds (int)
50+
343500, # duration milliseconds (int)
51+
platform.node(), # span source (str)
52+
uuid.UUID('7b3bf470-9456-11e8-9eb6-529269fb1459'), # trace ID (UUID)
53+
uuid.UUID('0313bafe-9457-11e8-9eb6-529269fb1459'), # span ID (UUID)
54+
[
55+
uuid.UUID('2f64e538-9457-11e8-9eb6-529269fb1459')
56+
], # parents (list[UUID])
57+
None, # follows from (list[UUID])
58+
[
59+
('application', 'Wavefront'),
60+
('http.method', 'GET')
61+
], # span tags (list[tuple])
62+
None # span log
63+
)
4464

4565

4666
def send_event(wavefront_client):
4767
"""Send an event."""
4868
wavefront_client.send_event(
49-
'event_via_proxy',
50-
1590650592,
51-
1590650692,
52-
"localhost",
53-
["env:", "test"],
54-
{"severity": "info",
55-
"type": "backup",
56-
"details": "broker backup"})
57-
58-
59-
if __name__ == '__main__':
60-
# Either "proxy://our.proxy.lb.com:2878"
61-
# Or "https://someToken@DOMAIN.wavefront.com"
69+
'python_sdk_example_event', # event name (str)
70+
1590650592, # event start milliseconds (int)
71+
1590650692, # event end milliseconds (int)
72+
platform.node(), # event source (str)
73+
["env:", "test"], # event tags (list[str] or tuple[str])
74+
{
75+
"severity": "info",
76+
"type": "backup",
77+
"details": "broker backup"
78+
} # event annotations (dict)
79+
)
80+
81+
82+
def main():
83+
"""Send sample metrics in a loop."""
6284
wavefront_proxy_url = sys.argv[1]
6385

6486
client_factory = WavefrontClientFactory()
6587
client_factory.add_client(wavefront_proxy_url)
66-
wavefront_client = client_factory.get_client()
88+
wfront_client = client_factory.get_client()
6789

6890
try:
6991
while True:
70-
send_metrics(wavefront_client)
71-
send_histogram(wavefront_client)
72-
send_tracing_span(wavefront_client)
73-
send_delta_counter(wavefront_client)
74-
send_event(wavefront_client)
92+
send_metrics(wfront_client)
93+
send_histogram(wfront_client)
94+
send_tracing_span(wfront_client)
95+
send_delta_counter(wfront_client)
96+
send_event(wfront_client)
7597

7698
time.sleep(15)
7799
finally:
78-
wavefront_client.close()
100+
wfront_client.close()
101+
102+
103+
if __name__ == '__main__':
104+
# Either "proxy://our.proxy.lb.com:2878"
105+
# Or "https://someToken@DOMAIN.wavefront.com"
106+
# should be passed as an input in sys.argv[1]
107+
main()

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
setuptools.setup(
1313
name='wavefront-sdk-python',
14-
version='1.8.15', # Please update with each pull request.
14+
version='1.9.0', # Please update with each pull request.
1515
author='VMware Aria Operations for Applications Team',
1616
url='https://github.com/wavefrontHQ/wavefront-sdk-python',
1717
license='Apache-2.0',
@@ -55,7 +55,7 @@
5555
packages=setuptools.find_packages(exclude=('*.tests', '*.tests.*',
5656
'tests.*', 'tests')),
5757
install_requires=(
58-
'requests>=2.18.4',
58+
'requests>=2.27',
5959
'tdigest>=0.5.2',
6060
'Deprecated>=1.2.10'
6161
)

test/test_client.py

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,10 @@
55

66
import unittest
77
import uuid
8-
from unittest.mock import ANY
9-
from unittest.mock import Mock
10-
from unittest.mock import patch
118

129
import requests
1310

14-
from wavefront_sdk.client import WavefrontClient
11+
import wavefront_sdk
1512
from wavefront_sdk.common.metrics import registry
1613
from wavefront_sdk.entities.tracing.span_log import SpanLog
1714

@@ -20,26 +17,24 @@ class TestUtils(unittest.TestCase):
2017
"""Test direct ingestion."""
2118

2219
def setUp(self):
23-
self._sender = WavefrontClient(
24-
'no_server',
25-
'no_token',
20+
self._sender = wavefront_sdk.client.WavefrontClient(
21+
'no_server', 'no_token',
2622
flush_interval_seconds=86400, # turn off auto flushing
2723
enable_internal_metrics=False)
2824
self._spans_log_buffer = self._sender._spans_log_buffer
2925
self._tracing_spans_buffer = self._sender._tracing_spans_buffer
30-
self._response = Mock()
26+
self._response = unittest.mock.Mock()
3127
self._response.status_code = 200
3228

3329
def test_send_version_with_internal_metrics(self):
3430
no_registry = registry.WavefrontSdkMetricsRegistry(
3531
wf_metric_sender=None)
36-
with patch.object(
32+
with unittest.mock.patch.object(
3733
registry,
3834
'WavefrontSdkMetricsRegistry',
3935
return_value=no_registry) as mock_registry:
40-
WavefrontClient(
41-
'no_server',
42-
'no_token',
36+
wavefront_sdk.client.WavefrontClient(
37+
'no_server', 'no_token',
4338
flush_interval_seconds=86400,
4439
enable_internal_metrics=True)
4540
self.assertRegex(
@@ -62,8 +57,6 @@ def test_send_span_with_span_logs(self):
6257
1635123789456000,
6358
{"FooLogKey": "FooLogValue"})])
6459

65-
self.maxDiff = None
66-
6760
# Verify span logs correctly emitted
6861
actual_line = self._spans_log_buffer.get()
6962
expected_line = (
@@ -104,8 +97,6 @@ def test_send_span_without_span_logs(self):
10497
[('application', 'Wavefront'), ('service', 'test-spans')],
10598
[])
10699

107-
self.maxDiff = None
108-
109100
# Assert no span logs emitted
110101
self.assertTrue(self._spans_log_buffer.empty())
111102

@@ -122,30 +113,27 @@ def test_send_span_without_span_logs(self):
122113

123114
def test_report_event(self):
124115

125-
with patch.object(
126-
requests, 'post', return_value=self._response) as mock_post:
127-
self._sender._report(
128-
'', self._sender.WAVEFRONT_EVENT_FORMAT, '', Mock())
129-
130-
mock_post.assert_called_once_with(
131-
ANY,
132-
params=None,
133-
headers=ANY,
134-
data=ANY,
135-
timeout=self._sender.HTTP_TIMEOUT)
116+
with unittest.mock.patch.object(
117+
requests.Session, 'post',
118+
return_value=self._response) as mock_post:
119+
self._sender._report('',
120+
self._sender.WAVEFRONT_EVENT_FORMAT,
121+
'',
122+
unittest.mock.Mock())
123+
mock_post.assert_called_once_with(unittest.mock.ANY,
124+
headers=unittest.mock.ANY,
125+
data=unittest.mock.ANY)
136126

137127
def test_report_non_event(self):
138128

139-
with patch.object(
140-
requests, 'post', return_value=self._response) as mock_post:
141-
self._sender._report('', 'metric', '', Mock())
142-
143-
mock_post.assert_called_once_with(
144-
ANY,
145-
params=ANY,
146-
headers=ANY,
147-
data=ANY,
148-
timeout=self._sender.HTTP_TIMEOUT)
129+
with unittest.mock.patch.object(
130+
requests.Session, 'post',
131+
return_value=self._response) as mock_post:
132+
self._sender._report('', 'metric', '', unittest.mock.Mock())
133+
mock_post.assert_called_once_with(unittest.mock.ANY,
134+
params=unittest.mock.ANY,
135+
headers=unittest.mock.ANY,
136+
data=unittest.mock.ANY)
149137

150138

151139
if __name__ == '__main__':

wavefront_sdk/__init__.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,15 @@
99
import pkg_resources
1010

1111
from .client_factory import WavefrontClientFactory
12-
from .direct import WavefrontDirectClient
13-
from .proxy import WavefrontProxyClient
1412

1513

16-
__all__ = ['WavefrontDirectClient',
17-
'WavefrontProxyClient',
18-
'WavefrontClientFactory']
14+
__all__ = ['WavefrontClientFactory']
1915

2016
__version__ = None
2117

2218
try:
2319
__version__ = pkg_resources.get_distribution(
24-
'wavefront-sdk-python'
25-
).version
20+
'wavefront-sdk-python').version
2621
except pkg_resources.DistributionNotFound:
2722
# __version__ is only available when distribution is installed.
2823
pass

wavefront_sdk/client.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,18 @@ def __init__(self, server, token, max_queue_size=50000, batch_size=10000,
7575
self._tracing_spans_buffer = queue_impl(max_queue_size)
7676
self._spans_log_buffer = queue_impl(max_queue_size)
7777
self._events_buffer = queue_impl(max_queue_size)
78-
self._headers = {'Content-Type': 'application/octet-stream',
79-
'Content-Encoding': 'gzip'}
80-
self._event_headers = {'Content-Type': 'application/json',
81-
'Content-Encoding': 'gzip'}
78+
self._headers = {'Content-Type': 'application/octet-stream'}
79+
self._event_headers = {'Content-Type': 'application/json'}
8280
self._closed = False
8381
self._schedule_lock = threading.RLock()
8482
self._timer = None
8583
self._schedule_timer()
84+
self._session = requests.Session()
85+
self._session.headers.update({'Content-Encoding': 'gzip'})
86+
self._session.timeout = self.HTTP_TIMEOUT
8687

8788
if token:
88-
self._headers['Authorization'] = 'Bearer ' + token
89-
self._event_headers['Authorization'] = 'Bearer ' + token
89+
self._session.headers.update({'Authorization': 'Bearer ' + token})
9090
ingestion_type = 'direct'
9191
else:
9292
ingestion_type = 'proxy'
@@ -192,18 +192,18 @@ def _report(self, points, data_format, entity_prefix, report_errors):
192192
"""
193193
try:
194194
if data_format == self.WAVEFRONT_EVENT_FORMAT and self._token:
195-
response = requests.post(self.server + self.EVENT_END_POINT,
196-
params=None,
197-
headers=self._event_headers,
198-
data=points,
199-
timeout=self.HTTP_TIMEOUT)
195+
response = self._session.post(
196+
self.server + self.EVENT_END_POINT,
197+
headers=self._event_headers,
198+
data=points)
200199
else:
201200
params = {'f': data_format}
202201
compressed_data = utils.gzip_compress(points.encode('utf-8'))
203-
response = requests.post(self.server + self.REPORT_END_POINT,
204-
params=params, headers=self._headers,
205-
data=compressed_data,
206-
timeout=self.HTTP_TIMEOUT)
202+
response = self._session.post(
203+
self.server + self.REPORT_END_POINT,
204+
headers=self._headers,
205+
data=compressed_data,
206+
params=params)
207207

208208
self._sdk_metrics_registry.new_delta_counter(
209209
f'{entity_prefix}.report.{response.status_code}').inc()

0 commit comments

Comments
 (0)