Catch permissions errors when writing StatsD packets

Closes-Bug: #1183152

Change-Id: I4b2c6e947241c987779a385fdff270d037470a57
This commit is contained in:
John Dickinson 2014-08-10 23:50:17 -07:00
parent 698919e67b
commit 1bc4fe891a
2 changed files with 27 additions and 4 deletions
swift/common
test/unit/common

@ -933,7 +933,7 @@ class LoggerFileObject(object):
class StatsdClient(object):
def __init__(self, host, port, base_prefix='', tail_prefix='',
default_sample_rate=1, sample_rate_factor=1):
default_sample_rate=1, sample_rate_factor=1, logger=None):
self._host = host
self._port = port
self._base_prefix = base_prefix
@ -942,6 +942,7 @@ class StatsdClient(object):
self._sample_rate_factor = sample_rate_factor
self._target = (self._host, self._port)
self.random = random
self.logger = logger
def set_prefix(self, new_prefix):
if new_prefix and self._base_prefix:
@ -966,7 +967,13 @@ class StatsdClient(object):
# Ideally, we'd cache a sending socket in self, but that
# results in a socket getting shared by multiple green threads.
with closing(self._open_socket()) as sock:
return sock.sendto('|'.join(parts), self._target)
try:
return sock.sendto('|'.join(parts), self._target)
except IOError as err:
if self.logger:
self.logger.warn(
'Error sending UDP message to %r: %s',
self._target, err)
def _open_socket(self):
return socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
@ -1332,7 +1339,7 @@ def get_logger(conf, name=None, log_to_console=False, log_route=None,
'log_statsd_sample_rate_factor', 1))
statsd_client = StatsdClient(statsd_host, statsd_port, base_prefix,
name, default_sample_rate,
sample_rate_factor)
sample_rate_factor, logger=logger)
logger.statsd_client = statsd_client
else:
logger.statsd_client = None

@ -110,10 +110,14 @@ class MockOs(object):
class MockUdpSocket(object):
def __init__(self):
def __init__(self, sendto_errno=None):
self.sent = []
self.sendto_errno = sendto_errno
def sendto(self, data, target):
if self.sendto_errno:
raise socket.error(self.sendto_errno,
'test errno %s' % self.sendto_errno)
self.sent.append((data, target))
def close(self):
@ -3037,6 +3041,18 @@ class TestStatsdLogging(unittest.TestCase):
self.assertEqual(logger.logger.statsd_client._sample_rate_factor,
0.81)
def test_no_exception_when_cant_send_udp_packet(self):
logger = utils.get_logger({'log_statsd_host': 'some.host.com'})
statsd_client = logger.logger.statsd_client
fl = FakeLogger()
statsd_client.logger = fl
mock_socket = MockUdpSocket(sendto_errno=errno.EPERM)
statsd_client._open_socket = lambda *_: mock_socket
logger.increment('tunafish')
expected = ["Error sending UDP message to ('some.host.com', 8125): "
"[Errno 1] test errno 1"]
self.assertEqual(fl.get_lines_for_level('warning'), expected)
def test_sample_rates(self):
logger = utils.get_logger({'log_statsd_host': 'some.host.com'})