Source code for perfmetrics.clientstack

# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import threading

from .statsd import statsd_client_from_uri

string_types = (str,)
if str is bytes: # pragma: no cover
    string_types += (unicode,) # pylint:disable=undefined-variable

class ClientStack(threading.local):
    """
    Thread local stack of StatsdClients.

    Applications and tests can either set the global statsd client using
    perfmetrics.set_statsd_client() or set a statsd client for each thread
    using statsd_client_stack.push()/.pop()/.clear().

    This is like pyramid.threadlocal but it handles the default differently.
    """

    default = None

    def __init__(self):
        threading.local.__init__(self) # pylint:disable=non-parent-init-called
        self.stack = []

    def get(self):
        """
        Return the current StatsdClient for the thread.

        Returns the thread-local client if there is one, or the global
        client if there is one, or None.
        """
        stack = self.stack
        return stack[-1] if stack else self.default

    def push(self, obj):
        self.stack.append(obj)

    def pop(self):
        stack = self.stack
        if stack:
            return stack.pop()

    def clear(self):
        del self.stack[:]


client_stack = ClientStack()

# Just expose the bound method, don't wrap it,
# for speed.
statsd_client = client_stack.get


[docs]def set_statsd_client(client_or_uri): """ Set the global StatsdClient. The ``client_or_uri`` can be a StatsdClient, a ``statsd://`` URI, or None. Note that when the perfmetrics module is imported, it looks for the ``STATSD_URI`` environment variable and calls `set_statsd_client` if that variable is found. """ if isinstance(client_or_uri, string_types): client = statsd_client_from_uri(client_or_uri) else: client = client_or_uri ClientStack.default = client