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)
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)
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)
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)
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', ''), )
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))
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)
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
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)
################################################################################ """ 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
@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 """
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
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)
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)
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)