<commit_before>"""
Contains the base metrics store class and default metrics store class.
"""

import socket
import threading
import logging

class MetricsStore(object):
    """
    This is the base class for all metric stores. There is only one
    main method that metric stores must implement: :meth:`flush()`
    which is called from time to time to flush data out to the
    backing store.

    Metrics stores _must_ be threadsafe, since :meth:`flush()` could
    potentially be called by multiple flushing aggregators.
    """

    def flush(self, metrics):
        """
        This method is called by aggregators when flushing data.
        This must be thread-safe.
        """
        raise NotImplementedError("flush not implemented")

class GraphiteStore(MetricsStore):
    def __init__(self, host, port, attempts=3):
        """
        Implements a metrics store interface that allows metrics to
        be persisted to Graphite. Raises a :class:`ValueError` on bad arguments.

        :Parameters:
            - `host` : The hostname of the graphite server.
            - `port` : The port of the graphite server
            - `attempts` (optional) : The number of re-connect retries before failing.
        """
        if not isinstance(host, (str,unicode)): raise ValueError, "Host must be a string!"
        if not isinstance(port, int): raise ValueError, "Port must be an integer!"
        if port <= 0: raise ValueError, "Port must be positive!"
        if attempts <= 1: raise ValueError, "Must have at least 1 attempt!"

        self.host = host
        self.port = port
        self.attempts = attempts
        self.sock_lock = threading.Lock()
        self.sock = self._create_socket()
        self.logger = logging.getLogger("statsite.graphitestore")

    def flush(self, metrics):
        """
        Flushes the metrics provided to Graphite.

       :Parameters:
        - `metrics` : A list of (key,value,timestamp) tuples.
        """
        # Construct the output
        data = "\n".join(["%s %s %d" % metric for metric in metrics]) + "\n"

        # Serialize writes to the socket
        self.sock_lock.acquire()
        try:
            self._write_metric(data)
        except:
            self.logger.exception("Failed to write out the metrics!")
        finally:
            self.sock_lock.release()

    def close(self):
        """
        Closes the connection. The socket will be recreated on the next
        flush.
        """
        self.sock.close()

    def _create_socket(self):
        """Creates a socket and connects to the graphite server"""
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((self.host,self.port))
        return sock

    def _write_metric(self, metric):
        """Tries to write a string to the socket, reconnecting on any errors"""
        for attempt in xrange(self.attempts):
            try:
                self.sock.send(metric)
                break
            except socket.error:
                self.logger.exception("Failed to flush to Graphite!")
                self.sock = self._create_socket()<commit_msg>Use sendall instead of send for sending to graphite<commit_after>"""
Contains the base metrics store class and default metrics store class.
"""

import socket
import threading
import logging

class MetricsStore(object):
    """
    This is the base class for all metric stores. There is only one
    main method that metric stores must implement: :meth:`flush()`
    which is called from time to time to flush data out to the
    backing store.

    Metrics stores _must_ be threadsafe, since :meth:`flush()` could
    potentially be called by multiple flushing aggregators.
    """

    def flush(self, metrics):
        """
        This method is called by aggregators when flushing data.
        This must be thread-safe.
        """
        raise NotImplementedError("flush not implemented")

class GraphiteStore(MetricsStore):
    def __init__(self, host, port, attempts=3):
        """
        Implements a metrics store interface that allows metrics to
        be persisted to Graphite. Raises a :class:`ValueError` on bad arguments.

        :Parameters:
            - `host` : The hostname of the graphite server.
            - `port` : The port of the graphite server
            - `attempts` (optional) : The number of re-connect retries before failing.
        """
        if not isinstance(host, (str,unicode)): raise ValueError, "Host must be a string!"
        if not isinstance(port, int): raise ValueError, "Port must be an integer!"
        if port <= 0: raise ValueError, "Port must be positive!"
        if attempts <= 1: raise ValueError, "Must have at least 1 attempt!"

        self.host = host
        self.port = port
        self.attempts = attempts
        self.sock_lock = threading.Lock()
        self.sock = self._create_socket()
        self.logger = logging.getLogger("statsite.graphitestore")

    def flush(self, metrics):
        """
        Flushes the metrics provided to Graphite.

       :Parameters:
        - `metrics` : A list of (key,value,timestamp) tuples.
        """
        # Construct the output
        data = "\n".join(["%s %s %d" % metric for metric in metrics]) + "\n"

        # Serialize writes to the socket
        self.sock_lock.acquire()
        try:
            self._write_metric(data)
        except:
            self.logger.exception("Failed to write out the metrics!")
        finally:
            self.sock_lock.release()

    def close(self):
        """
        Closes the connection. The socket will be recreated on the next
        flush.
        """
        self.sock.close()

    def _create_socket(self):
        """Creates a socket and connects to the graphite server"""
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((self.host,self.port))
        return sock

    def _write_metric(self, metric):
        """Tries to write a string to the socket, reconnecting on any errors"""
        for attempt in xrange(self.attempts):
            try:
                self.sock.sendall(metric)
                break
            except socket.error:
                self.logger.exception("Failed to flush to Graphite!")
                self.sock = self._create_socket()
{'fraction_non_alphanumeric': 0.09144308620415939, 'fraction_numerical': 0.0012700428639466582, 'mean_word_length': 2.2490974729241877, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5293152', 'n_tokens_mistral': 1672, 'n_tokens_neox': 1620, 'n_words': 615}