HTTP Dispatcher: Post event data as JSON & improve logging

Change-Id: Ia0e6ba97a3257fe305e424894507fb2d3e7c8d17
This commit is contained in:
Darren Hague 2016-01-19 10:26:37 +00:00
parent b92a0315e0
commit 8e870b1828
2 changed files with 60 additions and 33 deletions

View File

@ -91,28 +91,43 @@ class HttpDispatcher(dispatcher.MeterDispatcherBase,
'counter_volume': meter['counter_volume']})
try:
# Every meter should be posted to the target
meter_json = json.dumps(meter)
LOG.trace('Meter Message: %s', meter_json)
res = requests.post(self.target,
data=json.dumps(meter),
data=meter_json,
headers=self.headers,
timeout=self.timeout)
LOG.debug('Message posting finished with status code '
LOG.debug('Meter message posting finished with status code '
'%d.', res.status_code)
except Exception as err:
LOG.exception(_LE('Failed to record metering data: %s.'), err)
res.raise_for_status()
except requests.exceptions.HTTPError:
LOG.exception(_LE('Status Code: %{code}s. Failed to'
'dispatch meter: %{meter}s'),
{'code': res.status_code, 'meter': meter})
def record_events(self, events):
if self.event_target == '':
# if the event target was not set, do not do anything
LOG.error(_LE('Dispatcher event target was not set, no event will '
'be posted. Set event_target in the ceilometer.conf '
'file.'))
return
if not isinstance(events, list):
events = [events]
for event in events:
res = None
try:
res = requests.post(self.event_target, data=event,
event_json = json.dumps(event)
LOG.trace('Event Message: %s', event_json)
res = requests.post(self.event_target,
data=event_json,
headers=self.headers,
timeout=self.timeout)
LOG.debug('Event Message posting finished with status code '
'%d.', res.status_code)
res.raise_for_status()
except Exception:
error_code = res.status_code if res else 'unknown'
except requests.exceptions.HTTPError:
LOG.exception(_LE('Status Code: %{code}s. Failed to'
'dispatch event: %{event}s'),
{'code': error_code, 'event': event})
{'code': res.status_code, 'event': event})

View File

@ -27,6 +27,7 @@ from ceilometer.publisher import utils
class TestDispatcherHttp(base.BaseTestCase):
"""Test sending meters with the http dispatcher"""
def setUp(self):
super(TestDispatcherHttp, self).setUp()
@ -72,50 +73,61 @@ class TestDispatcherHttp(base.BaseTestCase):
class TestEventDispatcherHttp(base.BaseTestCase):
"""Test sending events with the http dispatcher"""
def setUp(self):
super(TestEventDispatcherHttp, self).setUp()
self.CONF = self.useFixture(fixture_config.Config()).conf
# repr(uuid.uuid4()) is used in test event creation to avoid an
# exception being thrown when the uuid is serialized to JSON
event = event_models.Event(repr(uuid.uuid4()), 'test',
datetime.datetime(2012, 7, 2, 13, 53, 40),
[], {})
event = utils.message_from_event(event,
self.CONF.publisher.telemetry_secret)
self.event = event
def test_http_dispatcher(self):
self.CONF.dispatcher_http.event_target = 'fake'
dispatcher = http.HttpDispatcher(self.CONF)
event = event_models.Event(uuid.uuid4(), 'test',
datetime.datetime(2012, 7, 2, 13, 53, 40),
[], {})
event = utils.message_from_event(event,
self.CONF.publisher.telemetry_secret)
with mock.patch.object(requests, 'post') as post:
dispatcher.record_events(event)
dispatcher.record_events(self.event)
self.assertEqual(1, post.call_count)
def test_http_dispatcher_bad(self):
def test_http_dispatcher_bad_server(self):
self.CONF.dispatcher_http.event_target = 'fake'
dispatcher = http.HttpDispatcher(self.CONF)
with mock.patch.object(requests, 'post') as post:
response = requests.Response()
response.status_code = 500
post.return_value = response
with mock.patch('ceilometer.dispatcher.http.LOG',
mock.MagicMock()) as LOG:
dispatcher.record_events(self.event)
self.assertTrue(LOG.exception.called)
def test_http_dispatcher_with_no_target(self):
self.CONF.dispatcher_http.event_target = ''
dispatcher = http.HttpDispatcher(self.CONF)
event = event_models.Event(uuid.uuid4(), 'test',
datetime.datetime(2012, 7, 2, 13, 53, 40),
[], {})
event = utils.message_from_event(event,
self.CONF.publisher.telemetry_secret)
with mock.patch('ceilometer.dispatcher.http.LOG',
mock.MagicMock()) as LOG:
dispatcher.record_events(event)
self.assertTrue(LOG.exception.called)
# The target should be None
self.assertEqual('', dispatcher.event_target)
with mock.patch.object(requests, 'post') as post:
dispatcher.record_events(self.event)
# Since the target is not set, no http post should occur, thus the
# call_count should be zero.
self.assertEqual(0, post.call_count)
def test_http_dispatcher_share_target(self):
self.CONF.dispatcher_http.target = 'fake'
dispatcher = http.HttpDispatcher(self.CONF)
event = event_models.Event(uuid.uuid4(), 'test',
datetime.datetime(2012, 7, 2, 13, 53, 40),
[], {})
event = utils.message_from_event(event,
self.CONF.publisher.telemetry_secret)
with mock.patch.object(requests, 'post') as post:
dispatcher.record_events(event)
dispatcher.record_events(self.event)
self.assertEqual('fake', post.call_args[0][0])