web-dev-qa-db-fra.com

Comment configurer la journalisation sur syslog en Python?

Je n'arrive pas à comprendre le module logging de Python. Mes besoins sont très simples: je veux juste tout enregistrer dans syslog. Après avoir lu la documentation, je suis arrivé à ce script de test simple:

import logging
import logging.handlers

my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.DEBUG)

handler = logging.handlers.SysLogHandler()

my_logger.addHandler(handler)

my_logger.debug('this is debug')
my_logger.critical('this is critical')

Mais ce script ne produit aucun enregistrement de journal dans syslog. Qu'est-ce qui ne va pas?

109
thor

Changer la ligne à ceci:

handler = SysLogHandler(address='/dev/log')

Ça marche pour moi

import logging
import logging.handlers

my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.DEBUG)

handler = logging.handlers.SysLogHandler(address = '/dev/log')

my_logger.addHandler(handler)

my_logger.debug('this is debug')
my_logger.critical('this is critical')
132
dr jimbob

Vous devez toujours utiliser l'hôte local pour la journalisation, que ce soit vers/dev/log ou localhost via la pile TCP. Ceci permet au démon de journalisation système entièrement conforme à RFC pour gérer syslog. Cela évite au démon distant de fonctionner et vous offre les fonctionnalités améliorées des démons syslog tels que rsyslog et syslog-ng, par exemple. La même philosophie s’applique à SMTP. Il suffit de la transmettre au logiciel SMTP local. dans ce cas, utilisez le 'mode programme', pas le démon, mais la même idée. Laissez le logiciel le plus capable s'en charger. Retrying, mise en file d'attente, mise en file d'attente locale, en utilisant TCP au lieu de UDP pour syslog, etc.) Vous pouvez aussi [re] configurer ces démons séparément de votre code, comme il se doit.

Enregistrez votre code pour votre application, laissez les autres logiciels faire leur travail de concert.

21
egrep

J'ai trouvé le module syslog pour faciliter l'obtention du comportement de journalisation de base que vous décrivez:

import syslog
syslog.syslog("This is a test message")
syslog.syslog(syslog.LOG_INFO, "Test message at INFO priority")

Vous pouvez également faire d’autres choses, mais même les deux premières lignes vous donneront ce que vous avez demandé tel que je le comprends.

18
lindes-hw

Assembler des objets ici et ailleurs, voici ce que j'ai trouvé qui fonctionne sur unbuntu 12.04 et centOS6

Créer un fichier dans /etc/rsyslog.d/ qui se termine par .conf et ajoute le texte suivant

local6.*        /var/log/my-logfile

Redémarrez rsyslog, le rechargement ne semble PAS fonctionner pour les nouveaux fichiers journaux. Peut-être qu'il ne recharge que les fichiers de configuration existants?

Sudo restart rsyslog

Ensuite, vous pouvez utiliser ce programme de test pour vous assurer qu'il fonctionne réellement.

import logging, sys
from logging import config

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(module)s P%(process)d T%(thread)d %(message)s'
            },
        },
    'handlers': {
        'stdout': {
            'class': 'logging.StreamHandler',
            'stream': sys.stdout,
            'formatter': 'verbose',
            },
        'sys-logger6': {
            'class': 'logging.handlers.SysLogHandler',
            'address': '/dev/log',
            'facility': "local6",
            'formatter': 'verbose',
            },
        },
    'loggers': {
        'my-logger': {
            'handlers': ['sys-logger6','stdout'],
            'level': logging.DEBUG,
            'propagate': True,
            },
        }
    }

config.dictConfig(LOGGING)


logger = logging.getLogger("my-logger")

logger.debug("Debug")
logger.info("Info")
logger.warn("Warn")
logger.error("Error")
logger.critical("Critical")
14
boatcoder

J'ajoute un petit commentaire supplémentaire au cas où cela pourrait aider quelqu'un parce que je trouvais cet échange utile mais que j'avais besoin de ce petit supplément d'informations pour que tout fonctionne.

Pour vous connecter à une installation spécifique à l'aide de SysLogHandler, vous devez spécifier la valeur de l'installation. Disons par exemple que vous avez défini:

local3.* /var/log/mylog

dans syslog, vous voudrez utiliser:

handler = logging.handlers.SysLogHandler(address = ('localhost',514), facility=19)

et vous devez également que syslog écoute sur UDP pour utiliser localhost au lieu de/dev/log.

11
Oliver Henriot

Est-ce que votre syslog.conf est configuré pour gérer facility = user?

Vous pouvez définir la facilité utilisée par le = python logger avec l'argument facility, quelque chose comme ceci:

handler = logging.handlers.SysLogHandler(facility=SysLogHandler.LOG_DAEMON)
10
bstpierre

De https://github.com/luismartingil/per.scripts/tree/master/python_syslog

#!/usr/bin/python
# -*- coding: utf-8 -*-

'''
Implements a new handler for the logging module which uses the pure syslog python module.

@author:  Luis Martin Gil
@year: 2013
'''
import logging
import syslog

class SysLogLibHandler(logging.Handler):
    """A logging handler that emits messages to syslog.syslog."""
    FACILITY = [syslog.LOG_LOCAL0,
                syslog.LOG_LOCAL1,
                syslog.LOG_LOCAL2,
                syslog.LOG_LOCAL3,
                syslog.LOG_LOCAL4,
                syslog.LOG_LOCAL5,
                syslog.LOG_LOCAL6,
                syslog.LOG_LOCAL7]
    def __init__(self, n):
        """ Pre. (0 <= n <= 7) """
        try:
            syslog.openlog(logoption=syslog.LOG_PID, facility=self.FACILITY[n])
        except Exception , err:
            try:
                syslog.openlog(syslog.LOG_PID, self.FACILITY[n])
            except Exception, err:
                try:
                    syslog.openlog('my_ident', syslog.LOG_PID, self.FACILITY[n])
                except:
                    raise
        # We got it
        logging.Handler.__init__(self)

    def emit(self, record):
        syslog.syslog(self.format(record))

if __== '__main__':
    """ Lets play with the log class. """
    # Some variables we need
    _id = 'myproj_v2.0'
    logStr = 'debug'
    logFacilityLocalN = 1

    # Defines a logging level and logging format based on a given string key.
    LOG_ATTR = {'debug': (logging.DEBUG,
                          _id + ' %(levelname)-9s %(name)-15s %(threadName)-14s +%(lineno)-4d %(message)s'),
                'info': (logging.INFO,
                         _id + ' %(levelname)-9s %(message)s'),
                'warning': (logging.WARNING,
                            _id + ' %(levelname)-9s %(message)s'),
                'error': (logging.ERROR,
                          _id + ' %(levelname)-9s %(message)s'),
                'critical': (logging.CRITICAL,
                             _id + ' %(levelname)-9s %(message)s')}
    loglevel, logformat = LOG_ATTR[logStr]

    # Configuring the logger
    logger = logging.getLogger()
    logger.setLevel(loglevel)

    # Clearing previous logs
    logger.handlers = []

    # Setting formaters and adding handlers.
    formatter = logging.Formatter(logformat)
    handlers = []
    handlers.append(SysLogLibHandler(logFacilityLocalN))
    for h in handlers:
        h.setFormatter(formatter)
        logger.addHandler(h)

    # Yep!
    logging.debug('test debug')
    logging.info('test info')
    logging.warning('test warning')
    logging.error('test error')
    logging.critical('test critical')
7
luismartingil
import syslog
syslog.openlog(ident="LOG_IDENTIFIER",logoption=syslog.LOG_PID, facility=syslog.LOG_LOCAL0)
syslog.syslog('Log processing initiated...')

le script ci-dessus se connectera à l'installation LOCAL0 avec notre "LOG_IDENTIFIER" personnalisé ... vous pouvez utiliser LOCAL [0-7] à des fins locales.

7
San

Voici la méthode yaml dictConfig recommandée pour les versions 3.2 et ultérieures.

Dans le journal cfg.yml:

version: 1
disable_existing_loggers: true

formatters:
    default:
        format: "[%(process)d] %(name)s(%(funcName)s:%(lineno)s) - %(levelname)s: %(message)s"

handlers:
    syslog:
        class: logging.handlers.SysLogHandler
        level: DEBUG
        formatter: default
        address: /dev/log
        facility: local0

    rotating_file:
        class: logging.handlers.RotatingFileHandler
        level: DEBUG
        formatter: default
        filename: rotating.log
        maxBytes: 10485760 # 10MB
        backupCount: 20
        encoding: utf8

root:
    level: DEBUG
    handlers: [syslog, rotating_file]
    propogate: yes

loggers:
    main:
        level: DEBUG
        handlers: [syslog, rotating_file]
        propogate: yes

Chargez la configuration en utilisant:

log_config = yaml.safe_load(open('cfg.yml'))
logging.config.dictConfig(log_config)

Configuré à la fois syslog et un fichier direct. Notez que le /dev/log est spécifique à l'OS.

3
Bruce Edge

Je le répare sur mon cahier. Le service rsyslog n'a pas écouté le service de socket.

Je config cette ligne ci-dessous dans /etc/rsyslog.conf fichier et résolu le problème:

$SystemLogSocketName /dev/log

0
Anderson Madureira