|
|
from __future__ import absolute_import, division, unicode_literals
|
|
|
|
|
|
import socket
|
|
|
|
|
|
from .base import StatsClientBase, PipelineBase
|
|
|
|
|
|
|
|
|
class Pipeline(PipelineBase):
|
|
|
|
|
|
def __init__(self, client):
|
|
|
super(Pipeline, self).__init__(client)
|
|
|
self._maxudpsize = client._maxudpsize
|
|
|
|
|
|
def _send(self):
|
|
|
data = self._stats.popleft()
|
|
|
while self._stats:
|
|
|
# Use popleft to preserve the order of the stats.
|
|
|
stat = self._stats.popleft()
|
|
|
if len(stat) + len(data) + 1 >= self._maxudpsize:
|
|
|
self._client._after(data)
|
|
|
data = stat
|
|
|
else:
|
|
|
data += '\n' + stat
|
|
|
self._client._after(data)
|
|
|
|
|
|
|
|
|
class StatsClient(StatsClientBase):
|
|
|
"""A client for statsd."""
|
|
|
|
|
|
def __init__(self, host='localhost', port=8125, prefix=None,
|
|
|
maxudpsize=512, ipv6=False):
|
|
|
"""Create a new client."""
|
|
|
fam = socket.AF_INET6 if ipv6 else socket.AF_INET
|
|
|
family, _, _, _, addr = socket.getaddrinfo(
|
|
|
host, port, fam, socket.SOCK_DGRAM)[0]
|
|
|
self._addr = addr
|
|
|
self._sock = socket.socket(family, socket.SOCK_DGRAM)
|
|
|
self._prefix = prefix
|
|
|
self._maxudpsize = maxudpsize
|
|
|
|
|
|
def _send(self, data):
|
|
|
"""Send data to statsd."""
|
|
|
try:
|
|
|
self._sock.sendto(data.encode('ascii'), self._addr)
|
|
|
except (socket.error, RuntimeError):
|
|
|
# No time for love, Dr. Jones!
|
|
|
pass
|
|
|
|
|
|
def close(self):
|
|
|
if self._sock and hasattr(self._sock, 'close'):
|
|
|
self._sock.close()
|
|
|
self._sock = None
|
|
|
|
|
|
def pipeline(self):
|
|
|
return Pipeline(self)
|
|
|
|