1import logging
2import statsd
3
4from . import compat
5
6
7class Client(object):
8
9    '''Statsd Client Object
10
11    :keyword name: The name for this client
12    :type name: str
13    :keyword connection: The connection to use, will be automatically created
14        if not given
15    :type connection: :class:`~statsd.connection.Connection`
16
17    >>> client = Client('test')
18    >>> client
19    <Client:test@<Connection[localhost:8125] P(1.0)>>
20    >>> client.get_client('spam')
21    <Client:test.spam@<Connection[localhost:8125] P(1.0)>>
22    '''
23
24    #: The name of the client, everything sent from this client will be \
25    #: prefixed by name
26    name = None
27
28    #: The :class:`~statsd.connection.Connection` to use, creates a new
29    #: connection if no connection is given
30    connection = None
31
32    def __init__(self, name, connection=None):
33        self.name = self._get_name(name)
34        if not connection:
35            connection = statsd.Connection()
36        self.connection = connection
37        self.logger = logging.getLogger(
38            '%s.%s' % (__name__, self.__class__.__name__))
39
40    @classmethod
41    def _get_name(cls, *name_parts):
42        name_parts = [compat.to_str(x) for x in name_parts if x]
43        return '.'.join(name_parts)
44
45    def get_client(self, name=None, class_=None):
46        '''Get a (sub-)client with a separate namespace
47        This way you can create a global/app based client with subclients
48        per class/function
49
50        :keyword name: The name to use, if the name for this client was `spam`
51            and the `name` argument is `eggs` than the resulting name will be
52            `spam.eggs`
53        :type name: str
54        :keyword class_: The :class:`~statsd.client.Client` subclass to use
55            (e.g. :class:`~statsd.timer.Timer` or
56            :class:`~statsd.counter.Counter`)
57        :type class_: :class:`~statsd.client.Client`
58        '''
59
60        # If the name was given, use it. Otherwise simply clone
61        name = self._get_name(self.name, name)
62
63        # Create using the given class, or the current class
64        if not class_:
65            class_ = self.__class__
66
67        return class_(
68            name=name,
69            connection=self.connection,
70        )
71
72    def get_average(self, name=None):
73        '''Shortcut for getting an :class:`~statsd.average.Average` instance
74
75        :keyword name: See :func:`~statsd.client.Client.get_client`
76        :type name: str
77        '''
78        return self.get_client(name=name, class_=statsd.Average)
79
80    def get_counter(self, name=None):
81        '''Shortcut for getting a :class:`~statsd.counter.Counter` instance
82
83        :keyword name: See :func:`~statsd.client.Client.get_client`
84        :type name: str
85        '''
86        return self.get_client(name=name, class_=statsd.Counter)
87
88    def get_gauge(self, name=None):
89        '''Shortcut for getting a :class:`~statsd.gauge.Gauge` instance
90
91        :keyword name: See :func:`~statsd.client.Client.get_client`
92        :type name: str
93        '''
94        return self.get_client(name=name, class_=statsd.Gauge)
95
96    def get_raw(self, name=None):
97        '''Shortcut for getting a :class:`~statsd.raw.Raw` instance
98
99        :keyword name: See :func:`~statsd.client.Client.get_client`
100        :type name: str
101        '''
102        return self.get_client(name=name, class_=statsd.Raw)
103
104    def get_timer(self, name=None):
105        '''Shortcut for getting a :class:`~statsd.timer.Timer` instance
106
107        :keyword name: See :func:`~statsd.client.Client.get_client`
108        :type name: str
109        '''
110        return self.get_client(name=name, class_=statsd.Timer)
111
112    def __repr__(self):
113        return '<%s:%s@%r>' % (
114            self.__class__.__name__,
115            self.name,
116            self.connection,
117        )
118
119    def _send(self, data):
120        return self.connection.send(data)
121