<commit_before>"""
.. module:: munin
   :platform: Any
   :synopsis: Provides MuninNode source which can get events from the
              munin-node protocol.

.. moduleauthor:: <NAME> <<EMAIL>>
"""

import time

from twisted.internet import defer, reactor
from twisted.protocols.basic import LineReceiver
from twisted.internet.protocol import ClientCreator

from zope.interface import implements

from tensor.interfaces import ITensorSource
from tensor.objects import Source
from tensor.aggregators import Counter, Counter32

class MuninProtocol(LineReceiver):
    """MuninProtocol - provides a line receiver protocol for making requests
    to munin-node

    Requests must be made sequentially
    """
    delimiter = '\n'
    def __init__(self):
        self.ready = False
        self.buffer = []
        self.d = None

    def lineReceived(self, line):
        if (line[0] == '#'):
            return

        if self.d and (not self.d.called):
            if self.list:
                if line == '.':
                    buffer = self.buffer
                    self.buffer = []
                    self.d.callback(buffer)
                else:
                    self.buffer.append(line)
            else:
                self.d.callback(line)

    def disconnect(self):
        return self.transport.loseConnection()

    def sendCommand(self, command, list=False):
        self.d = defer.Deferred()
        self.list = list
        self.sendLine(command)
        return self.d
        

class MuninNode(Source):
    """Connects to munin-node and retrieves all metrics

    **Configuration arguments:**
    
    :param host: munin-node hostname (probably localhost)
    :type host: str.
    :param port: munin-node port (probably 4949)
    :type port: int.
    
    **Metrics:**

    :(service name).(plugin name).(keys...): A dot separated tree of
                                             munin plugin keys
    """

    implements(ITensorSource)

    def __init__(self, *a, **kw):
        Source.__init__(self, *a, **kw)

    @defer.inlineCallbacks
    def get(self):
        host = self.config.get('host', 'localhost')
        port = int(self.config.get('port', 4949))

        creator = ClientCreator(reactor, MuninProtocol)
        proto = yield creator.connectTCP(host, port)

        # Announce our capabilities 
        yield proto.sendCommand('cap multigraph')

        listout = yield proto.sendCommand('list')
        plug_list = listout.split()
        events = []
        
        for plug in plug_list:
            # Retrive the configuration for this plugin
            config = yield proto.sendCommand('config %s' % plug, True)
            plugin_config = {}
            for r in config:
                name, val = r.split(' ', 1)
                if '.' in name:
                    metric, key = name.split('.')

                    if key in ['type', 'label', 'min', 'info']:
                        plugin_config['%s.%s.%s' % (plug, metric, key)] = val

                else:
                    if name == 'graph_category':
                        plugin_config['%s.category' % plug] = val

            category = plugin_config.get('%s.category' % plug, 'system')

            # Retrieve the metrics
            metrics = yield proto.sendCommand('fetch %s' % plug, True)
            for m in metrics:
                name, val = m.split(' ', 1)
                if name != 'multigraph':
                    metric, key = name.split('.')

                    base = '%s.%s' % (plug, metric)
                    
                    m_type = plugin_config.get('%s.type' % base, 'GAUGE')

                    try:
                        val = float(val)
                    except:
                        continue

                    base = '%s.%s' % (plug, metric)
                    info = plugin_config.get('%s.info' % base, base)
                    prefix = '%s.%s' % (category, base)

                    if m_type == 'COUNTER':
                        events.append(self.createEvent('ok', info, val,
                            prefix=prefix, aggregation=Counter32))
                    elif m_type == 'DERIVE':
                        events.append(self.createEvent('ok', info, val,
                            prefix=prefix, aggregation=Counter))
                    else:
                        events.append(self.createEvent('ok', info, val,
                            prefix=prefix))

        yield proto.disconnect()

        defer.returnValue(events)
<commit_msg>Remove pointless constructor<commit_after>"""
.. module:: munin
   :platform: Any
   :synopsis: Provides MuninNode source which can get events from the
              munin-node protocol.

.. moduleauthor:: <NAME> <<EMAIL>>
"""

import time

from twisted.internet import defer, reactor
from twisted.protocols.basic import LineReceiver
from twisted.internet.protocol import ClientCreator

from zope.interface import implements

from tensor.interfaces import ITensorSource
from tensor.objects import Source
from tensor.aggregators import Counter, Counter32

class MuninProtocol(LineReceiver):
    """MuninProtocol - provides a line receiver protocol for making requests
    to munin-node

    Requests must be made sequentially
    """
    delimiter = '\n'
    def __init__(self):
        self.ready = False
        self.buffer = []
        self.d = None

    def lineReceived(self, line):
        if (line[0] == '#'):
            return

        if self.d and (not self.d.called):
            if self.list:
                if line == '.':
                    buffer = self.buffer
                    self.buffer = []
                    self.d.callback(buffer)
                else:
                    self.buffer.append(line)
            else:
                self.d.callback(line)

    def disconnect(self):
        return self.transport.loseConnection()

    def sendCommand(self, command, list=False):
        self.d = defer.Deferred()
        self.list = list
        self.sendLine(command)
        return self.d
        

class MuninNode(Source):
    """Connects to munin-node and retrieves all metrics

    **Configuration arguments:**
    
    :param host: munin-node hostname (probably localhost)
    :type host: str.
    :param port: munin-node port (probably 4949)
    :type port: int.
    
    **Metrics:**

    :(service name).(plugin name).(keys...): A dot separated tree of
                                             munin plugin keys
    """

    implements(ITensorSource)

    @defer.inlineCallbacks
    def get(self):
        host = self.config.get('host', 'localhost')
        port = int(self.config.get('port', 4949))

        creator = ClientCreator(reactor, MuninProtocol)
        proto = yield creator.connectTCP(host, port)

        # Announce our capabilities 
        yield proto.sendCommand('cap multigraph')

        listout = yield proto.sendCommand('list')
        plug_list = listout.split()
        events = []
        
        for plug in plug_list:
            # Retrive the configuration for this plugin
            config = yield proto.sendCommand('config %s' % plug, True)
            plugin_config = {}
            for r in config:
                name, val = r.split(' ', 1)
                if '.' in name:
                    metric, key = name.split('.')

                    if key in ['type', 'label', 'min', 'info']:
                        plugin_config['%s.%s.%s' % (plug, metric, key)] = val

                else:
                    if name == 'graph_category':
                        plugin_config['%s.category' % plug] = val

            category = plugin_config.get('%s.category' % plug, 'system')

            # Retrieve the metrics
            metrics = yield proto.sendCommand('fetch %s' % plug, True)
            for m in metrics:
                name, val = m.split(' ', 1)
                if name != 'multigraph':
                    metric, key = name.split('.')

                    base = '%s.%s' % (plug, metric)
                    
                    m_type = plugin_config.get('%s.type' % base, 'GAUGE')

                    try:
                        val = float(val)
                    except:
                        continue

                    base = '%s.%s' % (plug, metric)
                    info = plugin_config.get('%s.info' % base, base)
                    prefix = '%s.%s' % (category, base)

                    if m_type == 'COUNTER':
                        events.append(self.createEvent('ok', info, val,
                            prefix=prefix, aggregation=Counter32))
                    elif m_type == 'DERIVE':
                        events.append(self.createEvent('ok', info, val,
                            prefix=prefix, aggregation=Counter))
                    else:
                        events.append(self.createEvent('ok', info, val,
                            prefix=prefix))

        yield proto.disconnect()

        defer.returnValue(events)

{'fraction_non_alphanumeric': 0.10836120401337793, 'fraction_numerical': 0.0033444816053511705, 'mean_word_length': 1.555840455840456, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7023393', 'n_tokens_mistral': 2463, 'n_tokens_neox': 2276, 'n_words': 635}