Exemple #1
0
    def test_handlers_args(self):
        """Lecture des arguments d'un 'handler'."""
        # Note : on ne peut pas changer la configuration du logger_root
        # car nose effectue déjà des modifications de celui-ci (qui sont
        # prioritaires sur notre configuration).
        self.load_conf_from_string("""
[loggers]
keys=test

[handlers]
keys=test

[logger_test]
level=DEBUG
handlers=test
qualname=%s

[handler_test]
class=StreamHandler
level=INFO
; En remplace le flux par défaut (stderr) par stdout.
args=(sys.stdout, )
""" % __name__)
        fileConfig()
        logger = get_logger(__name__)

        # Le logger doit avoir le bon niveau, le bon nombre d'handlers
        # et surtout le handler doit avoir la bonne configuration de flux.
        self.assertEquals(logger.level, logging.DEBUG)
        self.assertEquals(len(logger.handlers), 1)
        handler = logger.handlers[0]
        self.assertTrue(isinstance(handler, logging.StreamHandler),
                        handler.__class__.__name__)
        self.assertEquals(handler.level, logging.INFO)
        self.assertEquals(handler.stream, sys.stdout)
Exemple #2
0
    def setUp(self):
        # On prépare la base de données et le serveur MemcacheD.
        helpers.setup_db()
        self.context_factory = helpers.ContextStubFactory()

        # On récupère le logger 'vigilo.correlator.syslog'
        # défini dans les settings.
        self.logger = get_logger('vigilo.correlator.syslog')

        # On crée une instance de la classe test_log_handler()
        # pour intercepter les logs du corrélateur, et on
        # construit un StreamHandler à partir de cette instance.
        self.stream = LogHandlerStub()
        self.handler = logging.StreamHandler(self.stream)

        # On associe ce handler au logger.
        self.logger.addHandler(self.handler)

        # On crée un formatter (qui comme son nom l'indique permet de
        # spécifier le format des messages) qu'on associe lui-même au handler.
        formatter = logging.Formatter("%(message)s")
        self.handler.setFormatter(formatter)

        # Initialisation de l'identifiant des messages XML.
        self.msgid = 0
        return defer.succeed(None)
Exemple #3
0
def makeService(options):
    """ the service that wraps everything the connector needs. """
    from vigilo.connector.options import getSettings
    settings = getSettings(options, __name__)

    from vigilo.common.logging import get_logger
    LOGGER = get_logger(__name__)

    from vigilo.common.gettext import translate
    _ = translate(__name__)

    from vigilo.connector.client import client_factory
    from vigilo.connector.handlers import buspublisher_factory
    from vigilo.connector.handlers import backupprovider_factory
    from vigilo.connector.socket import socketlistener_factory
    from vigilo.connector_nagios.nagioscommand import nagioscmdh_factory
    from vigilo.connector_nagios.nagiosconf import nagiosconffile_factory

    try:
        socket_filename = settings['connector-nagios']['listen_unix']
        # Statement seems to have no effect # pylint: disable-msg=W0104
        settings['connector-nagios']['nagios_pipe']
        settings["bus"]["queue"]
    except KeyError, e:
        LOGGER.error(_("Missing configuration option: %s"), str(e))
        sys.exit(1)
Exemple #4
0
    def _db_thread(self):
        """
        Cette méthode est exécutée dans un thread séparé.
        C'est elle qui traite les demandes d'opérations sur la base de données
        et retourne les résultats sous la forme d'un objet C{Deferred}.

        @note: Cette méthode ne retourne pas tant que la méthode
            L{DatabaseWrapper.shutdown} n'a pas été appelée.
        """
        from vigilo.common.logging import get_logger
        from vigilo.common.gettext import translate

        logger = get_logger(__name__)
        _ = translate(__name__)

        while True:
            op = self.queue.get()
            if op is None:
                return
            else:
                func, args, kwargs, d, txn = op

            if txn:
                transaction.begin()
            try:
                result = d.callback, func(*args, **kwargs)
                if txn:
                    transaction.commit()
            except Exception:
                if txn:
                    transaction.abort()
                result = d.errback, Failure()
            self.queue.task_done()
            reactor.callFromThread(*result)
Exemple #5
0
    def _log_correvent(self, info_dictionary):
        """
        Enregistre un résumé du traitement de l'événement
        dans les journaux système.

        @param info_dictionary: Dictionnaire contenant les informations
            sur l'événement courant.
        @type info_dictionary: C{dict}
        """
        try:
            log_level = settings['correlator'].as_int('syslog_data_level')
        except KeyError:
            log_level = logging.INFO

        data_logger = get_logger('vigilo.correlator.syslog')
        if not data_logger.isEnabledFor(log_level):
            return

        LOGGER.debug(_('Sending the correlated event to syslog'))
        data_logger.log(log_level,
                        '%s|%s|%s|%s|%s|%s|%s',
                        info_dictionary['idcorrevent'],
                        info_dictionary['update'] and
                            'CHANGE' or 'NEW',
                        info_dictionary['host'],
                        info_dictionary['service'] or '',
                        info_dictionary['state'],
                        info_dictionary['priority'],
                        info_dictionary.get('message', ''),
                    )
Exemple #6
0
def log_initialized(silent_load=False):
    """
    Cette fonction est appelée une fois la configuration chargée
    afin d'indiquer le nom du fichier qui a été chargé.
    """
    if silent_load:
        return
    from vigilo.common.logging import get_logger
    LOGGER = get_logger(__name__)
    LOGGER.debug('Loaded settings from paths: %s',
                 ", ".join(settings.filenames))
Exemple #7
0
def setup_plugins_path(plugins_path):
    """Très fortement inspiré de Trac"""
    from vigilo.common.logging import get_logger
    LOGGER = get_logger(__name__)
    LOGGER.debug("Loading plugins from %s" % plugins_path)

    distributions, errors = pkg_resources.working_set.find_plugins(
        pkg_resources.Environment([plugins_path])
    )
    for dist in distributions:
        if dist in pkg_resources.working_set:
            continue
        LOGGER.debug('Adding plugin %(plugin)s from %(location)s', {
            'plugin': dist,
            'location': dist.location,
        })
        pkg_resources.working_set.add(dist)

    def _log_error(item, e):
        if isinstance(e, pkg_resources.DistributionNotFound):
            LOGGER.debug('Skipping "%(item)s": ("%(module)s" not found)', {
                'item': item,
                'module': e,
            })
        elif isinstance(e, pkg_resources.VersionConflict):
            LOGGER.error(_('Skipping "%(item)s": (version conflict '
                           '"%(error)s")'),
                         {'item': item, 'error': e})
        elif isinstance(e, pkg_resources.UnknownExtra):
            LOGGER.error(_('Skipping "%(item)s": (unknown extra "%(error)s")'),
                         {'item': item, 'error': e })
        elif isinstance(e, ImportError):
            LOGGER.error(_('Skipping "%(item)s": (can\'t import "%(error)s")'),
                         {'item': item, 'error': e })
        else:
            LOGGER.error(_('Skipping "%(item)s": (error "%(error)s")'), {
                'item': item,
                'error': e,
            })

    for dist, e in errors.iteritems():
        _log_error(dist, e)
Exemple #8
0
    def run(self, msgid):
        logger = get_logger(__name__)
        logger.debug(u'Rule runner: process begins for rule "%s" (msgid=%r)',
                     self._name, msgid)

        def commit(res):
            transaction.commit()
            return res

        def abort(fail):
            error_message = fail.getErrorMessage()

            if not isinstance(error_message, unicode):
                error_message = unicode(error_message, 'utf-8', 'replace')

            logger.error(_('Got an exception while running rule ''"%(rule)s". '
                            'Running the correlator in the foreground '
                            '(service vigilo-correlator debug) may help '
                            'troubleshooting (%(error)s)'), {
                                'rule': self._name,
                                'error': error_message,
                            })
            transaction.abort()
            return fail

        def log_end(res):
            logger.debug(u'Rule runner: process ends for rule "%s"', self._name)
            return res

        transaction.begin()
        d = defer.maybeDeferred(
            self._rule.process,
            self._dispatcher,
            msgid)
        d.addCallback(commit)
        d.addErrback(abort)
        d.addBoth(log_end)
        return d
Exemple #9
0
    def run(self, func, *args, **kwargs):
        """
        Exécute une fonction interagissant avec la base de données.


        @param func: La fonction à exécuter qui utilise la base de données.
        @type func: C{callable}
        @note: Les arguments supplémentaires passés à cette méthode
            sont transmis à la fonction indiquée par C{func} lorsque
            celle-ci est appelée.
        @note: Cette méthode accepte également un paramètre nommé
            C{transaction} qui indique si le traitement doit avoir
            lieu dans une transaction ou non. Si le paramètre C{disable_txn}
            a été positionné à True à l'initialisation de l'objet,
            le traitement NE SERA PAS encapsulé dans une transaction,
            quelle que soit la valeur de ce paramètre.
        @return: Un Deferred qui sera appelé avec le résultat de
            l'exécution de la fonction.
        @rtype: L{defer.Deferred}
        """
        from vigilo.common.logging import get_logger
        logger = get_logger(__name__)

        txn = kwargs.pop('transaction', True) and not self.disable_txn
        if txn:
            transaction.begin()
        try:
            res = func(*args, **kwargs)
            if txn:
                transaction.commit()
        except KeyboardInterrupt:
            raise
        except:
            res = Failure()
            if txn:
                transaction.abort()
            self.logger.error(res)
        return self._return(res)
Exemple #10
0
################################################################################
"""
Ce module contient la classe de base pour un serveur Vigilo: L{Server}.
"""

from __future__ import absolute_import

import os
import shutil
import glob
import re

from vigilo.common.conf import settings

from vigilo.common.logging import get_logger
LOGGER = get_logger(__name__)

from vigilo.common.gettext import translate
_ = translate(__name__)

from vigilo.vigiconf import conf
from vigilo.vigiconf.lib import VigiConfError
from vigilo.vigiconf.lib.systemcommand import SystemCommand, SystemCommandError


class ServerError(VigiConfError):
    """Exception concernant un objet L{Server}"""

    def __init__(self, value, iServerName = ''):
        super(ServerError, self).__init__(value)
        self.value = value
Exemple #11
0
@todo: gérer un I{pool} de process RRDTool
@note: U{http://twistedmatrix.com/documents/current/core/howto/process.html}
"""

import os
import stat
import urllib
from signal import SIGINT, SIGTERM

from twisted.internet import reactor, protocol, defer
from twisted.internet.error import ProcessDone, ProcessTerminated

from vigilo.common import get_rrd_path

from vigilo.common.logging import get_logger
LOGGER = get_logger(__name__, silent_load=True)

from vigilo.common.gettext import translate
_ = translate(__name__)


from vigilo.connector_metro.exceptions import CreationError
from vigilo.connector_metro.exceptions import NotInConfiguration
from vigilo.connector_metro.exceptions import MissingConfigurationData


class NoAvailableProcess(Exception):
    """
    Il n'y a plus de process rrdtool disponible, et pourtant le sémaphore a
    autorisé l'accès
    """
Exemple #12
0
def makeService(options):
    """ the service that wraps everything the connector needs. """
    from vigilo.connector.options import getSettings, parseSubscriptions

    settings = getSettings(options, __name__)

    from vigilo.common.logging import get_logger

    LOGGER = get_logger(__name__)

    from vigilo.common.gettext import translate

    _ = translate(__name__)

    from vigilo.connector.client import client_factory
    from vigilo.connector.handlers import buspublisher_factory

    from vigilo.connector_metro.rrdtool import RRDToolPoolManager
    from vigilo.connector_metro.rrdtool import RRDToolManager
    from vigilo.connector_metro.confdb import MetroConfDB
    from vigilo.connector_metro.threshold import ThresholdChecker
    from vigilo.connector_metro.bustorrdtool import BusToRRDtool

    root_service = service.MultiService()

    # Client du bus
    client = client_factory(settings)
    client.setServiceParent(root_service)
    providers = []

    # Configuration
    try:
        conffile = settings["connector-metro"]["config"]
    except KeyError:
        LOGGER.error(
            _("Please set the path to the configuration " "database generated by VigiConf in the settings.ini.")
        )
        sys.exit(1)
    confdb = MetroConfDB(conffile)
    confdb.setServiceParent(root_service)

    try:
        must_check_th = settings["connector-metro"].as_bool("check_thresholds")
    except KeyError:
        must_check_th = True

    # Gestion RRDTool
    rrd_base_dir = settings["connector-metro"]["rrd_base_dir"]
    rrd_path_mode = settings["connector-metro"]["rrd_path_mode"]
    rrd_bin = settings["connector-metro"].get("rrd_bin", "/usr/bin/rrdtool")
    rrdcached = settings["connector-metro"].get("rrdcached", None)
    try:
        pool_size = settings["connector-metro"].as_int("rrd_processes")
    except KeyError:
        pool_size = None
    rrdtool_pool = RRDToolPoolManager(
        rrd_base_dir, rrd_path_mode, rrd_bin, check_thresholds=must_check_th, rrdcached=rrdcached, pool_size=pool_size
    )
    rrdtool = RRDToolManager(rrdtool_pool, confdb)

    # Gestion des seuils
    if must_check_th:
        threshold_checker = ThresholdChecker(rrdtool, confdb)
        bus_publisher = buspublisher_factory(settings, client)
        bus_publisher.registerProducer(threshold_checker, streaming=True)
        providers.append(bus_publisher)
    else:
        threshold_checker = None

    # Gestionnaire principal des messages
    bustorrdtool = BusToRRDtool(confdb, rrdtool, threshold_checker)
    bustorrdtool.setClient(client)
    subs = parseSubscriptions(settings)
    queue = settings["bus"]["queue"]
    queue_messages_ttl = int(settings["bus"].get("queue_messages_ttl", 0))
    bustorrdtool.subscribe(queue, queue_messages_ttl, subs)
    providers.append(bustorrdtool)

    # Statistiques
    from vigilo.connector.status import statuspublisher_factory

    status_publisher = statuspublisher_factory(settings, client, providers=providers)

    return root_service
Exemple #13
0
def main(*args):
    """
    Point d'entrée du script qui ferme les événements en vert
    dans le bac à événements (VigiBoard).

    @note: Cette fonction ne rend pas la main, mais quitte
        l'exécution de Python à la fin de sa propre exécution.
        Les codes de retour possibles pour le script sont :
        * 0 : pas d'erreur
        * 1 : exception levée durant l'exécution
        * 2 : paramètres / options incorrects pour le script
    """
    parser = OptionParser()
    parser.add_option("-d", "--days", action="store", dest="days",
        type="int", default=None, help=_("Close events which are "
        "at least DAYS old. DAYS must be a positive non-zero integer."))
    parser.add_option("-u", "--up", action="store_true", dest="state_up",
        default=False, help=_("Close events for hosts in the 'UP' state."))
    parser.add_option("-k", "--ok", action="store_true", dest="state_ok",
        default=False, help=_("Close events for services in the 'OK' state."))
    parser.add_option("-c", "--config", action="store", dest="config",
        type="string", default=None, help=_("Load configuration from "
        "this file."))

    (options, args) = parser.parse_args()

    from vigilo.common.conf import settings
    if options.config:
        settings.load_file(options.config)
    else:
        settings.load_module(__name__)

    from vigilo.common.logging import get_logger
    logger = get_logger(__name__)

    if args:
        logger.error(_('Too many arguments'))
        sys.exit(2)

    from vigilo.models.configure import configure_db
    try:
        configure_db(settings['database'], 'sqlalchemy_')
    except KeyError:
        logger.error(_('No database configuration found'))
        sys.exit(2)

    # Le script doit être appelé avec au moins une
    # des deux options parmi -k et -u pour être utile.
    if not options.state_up and not options.state_ok:
        parser.error(N_(
            "Either -k or -u must be used. "
            "See %s --help for more information.") % sys.argv[0])
        sys.exit(2)

    try:
        res = close_green(logger, options)
        transaction.commit()
    except Exception: # pylint: disable-msg=W0703
        # W0703: Catch "Exception"
        logger.exception(_('Some error occurred:'))
        transaction.abort()
        sys.exit(1)

    logger.info(
        _("Successfully closed %d events matching the given criteria."),
        res
    )
    sys.exit(0)
Exemple #14
0
def main(*args):
    """
    Point d'entrée du script qui supprime les événements
    obsolètes du bac à événements (VigiBoard).

    @note: Cette fonction ne rend pas la main, mais quitte
        l'exécution de Python à la fin de sa propre exécution.
        Les codes de retour possibles pour le script sont :
        * 0 : pas d'erreur
        * 1 : exception levée durant l'exécution
        * 2 : paramètres / options incorrects pour le script
    """
    parser = OptionParser()
    parser.add_option("-d", "--days", action="store", dest="days",
        type="int", default=None, help=_("Remove closed events which are "
        "at least DAYS old. DAYS must be a positive non-zero integer."))
    parser.add_option("-s", "--size", action="store", dest="size",
        type="int", default=None, help=_("Remove closed events, starting "
        "with the oldest ones, when the Vigilo database starts occupying "
        "more then SIZE bytes. SIZE must be a positive non-zero integer."))
    parser.add_option("-c", "--config", action="store", dest="config",
        type="string", default=None, help=_("Load configuration from "
        "this file."))

    (options, args) = parser.parse_args()

    from vigilo.common.conf import settings
    if options.config:
        settings.load_file(options.config)
    else:
        settings.load_module(__name__)

    from vigilo.common.logging import get_logger
    logger = get_logger(__name__)

    if args:
        logger.error(_('Too many arguments'))
        sys.exit(2)

    from vigilo.models.configure import configure_db
    try:
        configure_db(settings['database'], 'sqlalchemy_')
    except KeyError:
        logger.error(_('No database configuration found'))
        sys.exit(2)

    url = make_url(settings['database']['sqlalchemy_url'])

    if options.days is None and options.size is None:
        parser.error(N_(
            "Either -d or -s must be used. "
            "See %s --help for more information.") % sys.argv[0])
        sys.exit(2)

    try:
        clean_vigiboard(logger, options, url)
        transaction.commit()
        sys.exit(0)
    except Exception: # pylint: disable-msg=W0703
        # W0703: Catch "Exception"
        logger.exception(_('Some error occurred:'))
        transaction.abort()
        sys.exit(1)
Exemple #15
0
def change_password(*args):
    """
    Change le mot de passe d'un utilisateur
    dans la base de données de Vigilo.
    """

    from vigilo.common.gettext import translate
    _ = translate(__name__)

    usage=_("%prog [options] [username]"),
    parser = OptionParser(
        description=_("Changes Vigilo's password for user 'username' "
            "or the currently logged in user if this argument is omitted."),
    )
    parser.add_option("-c", "--config", action="store", dest="config",
        type="string", default=None, help=_("Load configuration from "
        "this file."))
    parser.add_option("-f", action="store", dest="passfile", metavar="FILE",
        type="string", default=None, help=_("Read the new password from "
        "this file."))

    (options, args) = parser.parse_args()

    from vigilo.common.conf import settings
    if options.config:
        settings.load_file(options.config)
    else:
        settings.load_module(__name__)

    from vigilo.common.logging import get_logger
    logger = get_logger(__name__)

    if len(args) > 1:
        print _('Too many arguments')
        sys.exit(1)

    from vigilo.models.configure import configure_db
    try:
        configure_db(settings['database'], 'sqlalchemy_')
    except KeyError:
        print _('No database configuration found')
        sys.exit(1)

    from vigilo.models.session import DBSession
    from vigilo.models import tables

    current_password = None
    current_user = pwd.getpwuid(os.getuid())
    username = current_user.pw_name

    if len(args) > 0:
        username = args[0]

    msg = _("Changing Vigilo password for user '%s'.")
    logger.info(msg, username)
    print msg % username

    # Si l'utilisateur n'est pas "root" (UID 0),
    # alors on demande le mot de passe actuel.
    if current_user.pw_uid != 0:
        current_password = getpass.getpass(_("Enter current password: "******"Bad login or password.")
        sys.exit(1)

    if options.passfile:
        passfile = open(options.passfile, "r")
        new_password = new_password2 = passfile.readline().strip()
        passfile.close()
    else:
        new_password = getpass.getpass(_("Enter new password: "******"Confirm new password: "******"Sorry, passwords do not match.")
        sys.exit(1)

    # Si le nouveau mot de passe est le même
    # que l'ancien, il n'y a rien à faire.
    if current_password == new_password:
        print _("Password unchanged.")
        sys.exit(0)

    user.password = new_password
    try:
        DBSession.flush()
        transaction.commit()
    except Exception: # pylint: disable-msg=W0703
        # W0703: Catch "Exception"
        msg = _("An exception occurred while updating password for user '%s'.")
        logger.exception(msg, username)
        print msg % username
        sys.exit(1)

    # Si on arrive ici, c'est que tout s'est bien passé.
    msg = _("Successfully updated password for user '%s'.")
    logger.info(msg, username)
    print msg % username
    sys.exit(0)