Пример #1
0
    def get_all_active_checks(self):
        checks = []
        deps_error = []
        for plugin_data in self.plugins_checks:
            plugin_name = plugin_data['type']
            # Load plugin
            plugin_info = PluginRegister.get_plugin(plugin_name)
            if not plugin_info:
                print('Plugin {} does not exist'.format(plugin_name))
                exit(1)

            # Configure plugin
            try:
                plugin = plugin_info['plugin_cls'](
                    plugin_data.get('config', {})
                )
            except DependencyError as e:
                deps_error.append(str(e))
                continue

            # Launch plugin checks
            for check in plugin_data['checks']:
                func_name = plugin_info['checks'].get(check['type'])
                if func_name is None:
                    print('Unknown check {} on plugin {}'.format(check['type'],
                                                                 plugin_name))
                    exit(1)
                check_func = getattr(plugin, func_name)

                # An empty string is a valid check name
                check_name = check.get(
                    'name',
                    '{}_{}'.format(plugin_name, check['type'])
                ).lower()

                check_periodicity = (check.get('periodicity') or
                                     self.periodicity)

                checks.append(Check(check_name, check_periodicity,
                                    check_func, check))
        if deps_error:
            for error in deps_error:
                print(error)
            exit(1)

        # Check duplicate name
        names = [check.name for check in checks]
        duplicates_names = {name: names.count(name)
                            for name in names if names.count(name) > 1}
        for name, count in duplicates_names.items():
            print("check name {} was found {} times, please add name"
                  " field to theses checks".format(name, count))
        if duplicates_names:
            exit(1)
        return checks
Пример #2
0
from sauna.plugins import Plugin, PluginRegister

my_plugin = PluginRegister('HTTP')


@my_plugin.plugin()
class HTTP(Plugin):
    def __init__(self, config):
        super().__init__(config)
        try:
            import requests
            self.requests = requests
        except ImportError:
            from ... import DependencyError
            raise DependencyError(self.__class__.__name__, 'requests',
                                  'requests', 'python3-requests')

    @my_plugin.check()
    def request(self, check_config):
        code = check_config.get('code', 200)
        content = check_config.get('content', '')

        try:
            r = self._do_http_request(check_config)
        except Exception as e:
            return Plugin.STATUS_CRIT, '{}'.format(e)

        if r.status_code != code:
            return (Plugin.STATUS_CRIT,
                    'Got status code {} instead of {}'.format(
                        r.status_code, code))
Пример #3
0
 def test_get_plugin(self):
     import sauna
     sauna.Sauna.import_submodules('sauna.plugins.ext')
     load_plugin = PluginRegister.get_plugin('Load')
     self.assert_(issubclass(load_plugin['plugin_cls'], Plugin))
     self.assertIsNone(PluginRegister.get_plugin('Unknown'))
Пример #4
0
import re
import socket

from sauna.plugins import (Plugin, bytes_to_human, human_to_bytes,
                           PluginRegister)

my_plugin = PluginRegister('Memcached')


@my_plugin.plugin()
class Memcached(Plugin):
    def __init__(self, config):
        super().__init__(config)
        self.config = {
            'host': config.get('host', 'localhost'),
            'port': config.get('port', 11211),
            'timeout': config.get('timeout', 5)
        }
        self._stats = None

    @my_plugin.check()
    def accepting_connections(self, check_config):
        try:
            accept_connections = self.stats['accepting_conns'] == 1
        except OSError as e:
            return (Plugin.STATUS_CRIT,
                    'Memcached is not accepting connections: {}'.format(e))
        if accept_connections:
            return Plugin.STATUS_OK, 'Memcached is accepting connections'
        else:
            return Plugin.STATUS_CRIT, 'Memcached is not accepting connections'
Пример #5
0
Файл: ntpd.py Проект: wayt/sauna
import time
from datetime import timedelta
import os

from sauna.plugins import Plugin, PluginRegister

my_plugin = PluginRegister('Ntpd')


@my_plugin.plugin()
class Ntpd(Plugin):
    def __init__(self, config):
        super().__init__(config)
        self.config = {
            'stats_dir': config.get('stats_dir', '/var/log/ntpstats')
        }
        self._last_loop_stats = None

    @property
    def last_loop_stats(self):
        loopstats_file = os.path.join(self.config['stats_dir'], 'loopstats')
        if not self._last_loop_stats:
            with open(loopstats_file) as f:
                last_line_items = f.readlines()[-1].split()
            self._last_loop_stats = {
                'timestamp': int(os.stat(loopstats_file).st_mtime),
                'offset': float(last_line_items[2])
            }
        return self._last_loop_stats

    @my_plugin.check()
Пример #6
0
from sauna.plugins import Plugin, human_to_bytes, bytes_to_human,\
    PluginRegister

my_plugin = PluginRegister('Disque')


@my_plugin.plugin()
class Disque(Plugin):
    def __init__(self, config):
        super().__init__(config)
        try:
            import redis
            self.redis = redis
        except ImportError:
            from ... import DependencyError
            raise DependencyError(self.__class__.__name__, 'redis-py', 'redis',
                                  'python3-redis')
        self._disque_info = None

    @my_plugin.check()
    def used_memory(self, check_config):
        status = self._value_to_status_less(self.disque_info['used_memory'],
                                            check_config, human_to_bytes)
        output = 'Used memory: {}'.format(
            self.disque_info['used_memory_human'])
        return status, output

    @my_plugin.check()
    def used_memory_rss(self, check_config):
        status = self._value_to_status_less(
            self.disque_info['used_memory_rss'], check_config, human_to_bytes)
Пример #7
0
from sauna.plugins import Plugin, PluginRegister

my_plugin = PluginRegister('MDStat')


@my_plugin.plugin()
class MDStat(Plugin):
    def __init__(self, config):
        super().__init__(config)
        try:
            import pymdstat
            self.pymdstat = pymdstat
        except ImportError:
            from ... import DependencyError
            raise DependencyError(self.__class__.__name__, 'pymdstat',
                                  'pymdstat')
        self._md_stats = None

    @property
    def md_stats(self):
        if not self._md_stats:
            self._md_stats = self.pymdstat.MdStat().get_stats()
        return self._md_stats

    @my_plugin.check()
    def status(self, check_config):
        if not self.md_stats['arrays']:
            return self.STATUS_UNKNOWN, 'No RAID array detected'

        for array_name, array_infos in self.md_stats['arrays'].items():
            if array_infos['status'] != 'active':
Пример #8
0
import time
from datetime import timedelta

from sauna.plugins import Plugin, PluginRegister

my_plugin = PluginRegister('PuppetAgent')


@my_plugin.plugin()
class PuppetAgent(Plugin):
    def __init__(self, config):
        super().__init__(config)
        self.config = {
            'summary_path':
            config.get('summary_path',
                       '/var/lib/puppet/state/last_run_summary.yaml')
        }
        self._last_run_summary = None

    @property
    def last_run_summary(self):
        import yaml
        if not self._last_run_summary:
            with open(self.config['summary_path']) as f:
                self._last_run_summary = yaml.safe_load(f)
        return self._last_run_summary

    @my_plugin.check()
    def last_run_delta(self, check_config):
        current_time = int(time.time())
        last_run_time = self.last_run_summary['time']['last_run']
Пример #9
0
from sauna.plugins import Plugin, human_to_bytes, bytes_to_human,\
    PluginRegister

my_plugin = PluginRegister('Redis')


@my_plugin.plugin()
class Redis(Plugin):
    def __init__(self, config):
        super().__init__(config)
        try:
            import redis
            self.redis = redis
        except ImportError:
            from ... import DependencyError
            raise DependencyError(self.__class__.__name__, 'redis-py', 'redis',
                                  'python3-redis')
        self._redis_info = None

    @my_plugin.check()
    def used_memory(self, check_config):
        status = self._value_to_status_less(self.redis_info['used_memory'],
                                            check_config, human_to_bytes)
        output = 'Used memory: {}'.format(self.redis_info['used_memory_human'])
        return status, output

    @my_plugin.check()
    def used_memory_rss(self, check_config):
        status = self._value_to_status_less(self.redis_info['used_memory_rss'],
                                            check_config, human_to_bytes)
        output = 'Used memory RSS: {}'.format(
Пример #10
0
from sauna.plugins.base import PsutilPlugin
from sauna.plugins import human_to_bytes, bytes_to_human, PluginRegister

my_plugin = PluginRegister('Memory')


@my_plugin.plugin()
class Memory(PsutilPlugin):
    def __init__(self, config):
        super().__init__(config)
        self._virtual_memory = None
        self._swap_memory = None

    @my_plugin.check()
    def available(self, check_config):
        available = self.virtual_memory.available
        return (self._value_to_status_more(available, check_config,
                                           human_to_bytes),
                'Memory available: {}'.format(bytes_to_human(available)))

    @my_plugin.check()
    def used_percent(self, check_config):
        used_percent = self.virtual_memory.percent
        check_config = self._strip_percent_sign_from_check_config(check_config)
        return (self._value_to_status_less(used_percent, check_config),
                'Memory used: {}%'.format(used_percent))

    @my_plugin.check()
    def swap_used_percent(self, check_config):
        swap_used_percent = self.swap_memory.percent
        check_config = self._strip_percent_sign_from_check_config(check_config)
Пример #11
0
import socket

from sauna.plugins import Plugin, PluginRegister

my_plugin = PluginRegister('SimpleDomain')


@my_plugin.plugin()
class SimpleDomain(Plugin):

    @my_plugin.check()
    def request(self, check_config):
        domain = check_config.get('domain')
        if check_config.get('ip_version') == 6:
            af = socket.AF_INET6
        elif check_config.get('ip_version') == 4:
            af = socket.AF_INET
        else:
            af = 0

        try:
            result = socket.getaddrinfo(domain, 0, af)
        except Exception as e:
            return Plugin.STATUS_CRIT, '{}'.format(e)

        ips = [ip[4][0] for ip in result]
        return (
            Plugin.STATUS_OK,
            'Domain was resolved with {}'.format(', '.join(ips))
        )
Пример #12
0
import re

from sauna.plugins import PluginRegister
from sauna.plugins.base import PsutilPlugin

my_plugin = PluginRegister('Processes')


@my_plugin.plugin()
class Processes(PsutilPlugin):
    @my_plugin.check()
    def count(self, check_config):
        num_pids = len(self.psutil.pids())
        return (self._value_to_status_less(num_pids, check_config),
                '{} processes'.format(num_pids))

    @my_plugin.check()
    def zombies(self, check_config):
        zombies = [
            p for p in self.psutil.process_iter() if p.status() == 'zombie'
        ]
        num_zombies = len(zombies)
        return (self._value_to_status_less(num_zombies, check_config),
                '{} zombies'.format(num_zombies))

    def _count_running_processes(self, check_config):
        """Count the number of times a process is running.

        Processes are identified by their first argument 'exec' and
        additional 'args'.
        :rtype int
Пример #13
0
import socket
import re
import subprocess

from sauna.plugins import Plugin
from sauna.plugins import PluginRegister

my_plugin = PluginRegister('Postfix')


@my_plugin.plugin()
class Postfix(Plugin):
    def __init__(self, config):
        super().__init__(config)
        self.config = {
            'host': config.get('host', 'localhost'),
            'port': config.get('port', 4280),
            'timeout': config.get('timeout', 5),
            'method': config.get('method', 'mailq')
        }
        self._mailq_output = None

    @my_plugin.check()
    def queue_size(self, check_config):
        queue_size = self._get_queue_size()
        return (self._value_to_status_less(queue_size, check_config),
                '{} mail(s) in queue'.format(queue_size))

    @property
    def mailq_output(self):
        if not self._mailq_output:
Пример #14
0
from sauna.plugins import Plugin, PluginRegister
from sauna.plugins.ext.http import HTTP
from sauna import DependencyError
import re
import json

my_plugin = PluginRegister('HTTP-JSON')


@my_plugin.plugin()
class HTTPJSON(HTTP):
    def __init__(self, config):
        super().__init__(config)
        try:
            import jsonpath_rw as jsonpath
            self.jsonpath = jsonpath
        except ImportError:
            raise DependencyError(self.__class__.__name__,
                                  'jsonpath_rw',
                                  pypi='jsonpath-rw')

    @my_plugin.check()
    def request(self, check_config):
        code = check_config.get('code', 200)
        expect = check_config.get('expect', None)

        try:
            r = self._do_http_request(check_config)
        except Exception as e:
            return Plugin.STATUS_CRIT, '{}'.format(e)
Пример #15
0
 def test_get_plugin(self):
     import sauna
     sauna.Sauna.import_submodules('sauna.plugins.ext')
     load_plugin = PluginRegister.get_plugin('Load')
     self.assert_(issubclass(load_plugin['plugin_cls'], Plugin))
     self.assertIsNone(PluginRegister.get_plugin('Unknown'))
Пример #16
0
import xmlrpc.client
import http.client
import socket

from sauna.plugins import Plugin, PluginRegister

my_plugin = PluginRegister('Supervisor')


@my_plugin.plugin()
class Supervisor(Plugin):
    def __init__(self, config):
        super().__init__(config)

        serverurl = config.get('serverurl', 'unix:///var/run/supervisor.sock')
        timeout = config.get('timeout', 5)
        if serverurl.startswith('unix://'):
            serverurl = serverurl.replace('unix://', '', 1)
            # xmlrpc.client does not support Unix sockets, so we must provide
            # a custom transport layer
            transport = UnixStreamTransport(serverurl, timeout=timeout)
            server = xmlrpc.client.ServerProxy('http://noop',
                                               transport=transport)
        else:
            transport = CustomHTTPTransport(timeout=timeout)
            server = xmlrpc.client.ServerProxy(serverurl, transport=transport)

        rpc_namespace = config.get('rpc_namespace', 'supervisor')
        self.supervisor = getattr(server, rpc_namespace)
        self.supervisor_addr = serverurl
Пример #17
0
Файл: load.py Проект: wayt/sauna
import os

from sauna.plugins import Plugin
from sauna.plugins import PluginRegister

my_plugin = PluginRegister('Load')


@my_plugin.plugin()
class Load(Plugin):
    def __init__(self, config):
        super().__init__(config)
        self._load = None

    @my_plugin.check()
    def load1(self, check_config):
        return (self._value_to_status_less(self.load[0], check_config),
                'Load 1: {}'.format(self.load[0]))

    @my_plugin.check()
    def load5(self, check_config):
        return (self._value_to_status_less(self.load[1], check_config),
                'Load 5: {}'.format(self.load[1]))

    @my_plugin.check()
    def load15(self, check_config):
        return (self._value_to_status_less(self.load[2], check_config),
                'Load 15: {}'.format(self.load[2]))

    @property
    def load(self):
Пример #18
0
import os
import glob
from collections import namedtuple
from functools import reduce

from sauna.plugins import Plugin, PluginRegister

Sensor = namedtuple('Sensor', ['device_name', 'label', 'value'])

my_plugin = PluginRegister('Hwmon')


@my_plugin.plugin()
class Hwmon(Plugin):
    """Linux hardware monitoring plugin.

    This plugin crawls Linux's /sys/class/hwmon to find usable sensors. Be
    warned that this method is quite fragile since exotic hardware may present
    values that need offsets or conversions.

    A more solid approach could be to use lm-sensors, but:
    - it requires to install and configure lm-sensors
    - there is no proper python bindings to the library
    - parsing the output of 'sensors' is not fun nor efficient
    """
    @my_plugin.check()
    def temperature(self, check_config):
        dummy_sensor = Sensor(device_name='Dummy', label='Dummy', value=-1000)
        sensors = self._get_temperatures()
        if check_config.get('sensors'):
            sensors = [
Пример #19
0
import socket

from sauna.plugins import (Plugin, PluginRegister)

my_plugin = PluginRegister('TCP')


@my_plugin.plugin()
class Tcp(Plugin):
    @my_plugin.check()
    def request(self, check_config):
        try:
            with socket.create_connection(
                (check_config['host'], check_config['port']),
                    timeout=check_config['timeout']):
                pass
        except Exception as e:
            return Plugin.STATUS_CRIT, "{}".format(e)
        else:
            return Plugin.STATUS_OK, "OK"

    @staticmethod
    def config_sample():
        return '''
        # Tcp
        - type: TCP
          checks:
            - type: request
              host: localhost
              port: 11211
              timeout: 5
Пример #20
0
from functools import lru_cache
import time

from sauna.plugins.base import PsutilPlugin
from sauna.plugins import human_to_bytes, bytes_to_human, PluginRegister

my_plugin = PluginRegister('Network')


@my_plugin.plugin()
class Network(PsutilPlugin):
    def __init__(self, config):
        super().__init__(config)

    @my_plugin.check()
    def upload_data_speed(self, check_config):
        ul, _, _, _ = self.get_network_data(
            interface=check_config['interface'])
        ul = round(ul, 2)

        return (self._value_to_status_less(ul, check_config, human_to_bytes),
                'Upload speed: {}/s'.format(bytes_to_human(ul)))

    @my_plugin.check()
    def download_data_speed(self, check_config):
        _, dl, _, _ = self.get_network_data(
            interface=check_config['interface'])
        dl = round(dl, 2)
        return (self._value_to_status_less(dl, check_config, human_to_bytes),
                'Download speed: {}/s'.format(bytes_to_human(dl)))