1- #!/usr/bin/env python
21"""
32DogStatsd is a Python client for DogStatsd, a Statsd fork for Datadog.
43"""
2120class DogStatsd (object ):
2221 OK , WARNING , CRITICAL , UNKNOWN = (0 , 1 , 2 , 3 )
2322
24- def __init__ (self , host = 'localhost' , port = 8125 , max_buffer_size = 50 ):
23+ def __init__ (self , host = 'localhost' , port = 8125 , max_buffer_size = 50 ):
2524 """
2625 Initialize a DogStatsd object.
2726
@@ -31,30 +30,29 @@ def __init__(self, host='localhost', port=8125, max_buffer_size=50):
3130 :param port: the port of the DogStatsd server.
3231 :param max_buffer_size: Maximum number of metric to buffer before sending to the server if sending metrics in batch
3332 """
34- self ._host = host
35- self ._port = int ( port )
33+ self ._host = None
34+ self ._port = None
3635 self .socket = None
3736 self .max_buffer_size = max_buffer_size
3837 self ._send = self ._send_to_server
39-
38+ self . connect ( host , port )
4039 self .encoding = 'utf-8'
4140
42- def __enter__ (self ):
43- self .open_buffer (self .max_buffer_size )
44- return self
45-
46- def __exit__ (self , type , value , traceback ):
47- self .close_buffer ()
48-
4941 def get_socket (self ):
5042 '''
5143 Return a connected socket
5244 '''
5345 if not self .socket :
54- self .socket = socket .socket (socket .AF_INET , socket .SOCK_DGRAM )
55- self .socket .connect ((self ._host , self ._port ))
46+ self .connect (self ._host , self ._port )
5647 return self .socket
5748
49+ def __enter__ (self ):
50+ self .open_buffer (self .max_buffer_size )
51+ return self
52+
53+ def __exit__ (self , type , value , traceback ):
54+ self .close_buffer ()
55+
5856 def open_buffer (self , max_buffer_size = 50 ):
5957 '''
6058 Open a buffer to send a batch of metrics in one packet
@@ -67,7 +65,7 @@ def open_buffer(self, max_buffer_size=50):
6765
6866 '''
6967 self .max_buffer_size = max_buffer_size
70- self .buffer = []
68+ self .buffer = []
7169 self ._send = self ._send_to_buffer
7270
7371 def close_buffer (self ):
@@ -77,6 +75,15 @@ def close_buffer(self):
7775 self ._send = self ._send_to_server
7876 self ._flush_buffer ()
7977
78+ def connect (self , host , port ):
79+ """
80+ Connect to the statsd server on the given host and port.
81+ """
82+ self ._host = host
83+ self ._port = int (port )
84+ self .socket = socket .socket (socket .AF_INET , socket .SOCK_DGRAM )
85+ self .socket .connect ((self ._host , self ._port ))
86+
8087 def gauge (self , metric , value , tags = None , sample_rate = 1 ):
8188 """
8289 Record the value of a gauge, optionally setting a list of tags and a
@@ -176,13 +183,12 @@ def _report(self, metric, metric_type, value, tags, sample_rate):
176183
177184 def _send_to_server (self , packet ):
178185 try :
179- # If set, use socket directly
180- (self .socket or self .get_socket ()).send (packet .encode (self .encoding ))
186+ self .socket .send (packet .encode (self .encoding ))
181187 except socket .error :
182- log .info ("Error submitting packet , will try refreshing the socket" )
183- self .socket = None
188+ log .info ("Error submitting metric , will try refreshing the socket" )
189+ self .connect ( self . _host , self . _port )
184190 try :
185- self .get_socket () .send (packet .encode (self .encoding ))
191+ self .socket .send (packet .encode (self .encoding ))
186192 except socket .error :
187193 log .exception ("Failed to send packet with a newly binded socket" )
188194
@@ -193,7 +199,7 @@ def _send_to_buffer(self, packet):
193199
194200 def _flush_buffer (self ):
195201 self ._send_to_server ("\n " .join (self .buffer ))
196- self .buffer = []
202+ self .buffer = []
197203
198204 def _escape_event_content (self , string ):
199205 return string .replace ('\n ' , '\\ n' )
@@ -233,7 +239,10 @@ def event(self, title, text, alert_type=None, aggregation_key=None,
233239 raise Exception (u'Event "%s" payload is too big (more that 8KB), '
234240 'event discarded' % title )
235241
236- self ._send (string )
242+ try :
243+ self .socket .send (string .encode (self .encoding ))
244+ except Exception :
245+ log .exception (u'Error submitting event "%s"' % title )
237246
238247 def service_check (self , check_name , status , tags = None , timestamp = None ,
239248 hostname = None , message = None ):
@@ -255,7 +264,10 @@ def service_check(self, check_name, status, tags=None, timestamp=None,
255264 if message :
256265 string = u'{0}|m:{1}' .format (string , message )
257266
258- self ._send (string )
267+ try :
268+ self .socket .send (string .encode (self .encoding ))
269+ except Exception :
270+ log .exception (u'Error submitting service check "{0}"' .format (check_name ))
259271
260272
261273statsd = DogStatsd ()
0 commit comments