Как настроить ведение журнала в системный журнал в Python? - PullRequest
106 голосов
/ 19 октября 2010

Я не могу разобраться с модулем logging в Python.Мои потребности очень просты: я просто хочу записать все в системный журнал.После прочтения документации я пришел к следующему простому тестовому сценарию:

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')

Но этот сценарий не создает никаких записей в системном журнале.Что не так?

Ответы [ 10 ]

130 голосов
/ 19 октября 2010

Измените строку на эту:

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

Это работает для меня

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')
21 голосов
/ 17 января 2013

Вы должны всегда использовать локальный хост для ведения журнала, будь то / dev / log или localhost через стек TCP.Это позволяет полностью совместимому с RFC и многофункциональному системному журналу регистрации обрабатывать системный журнал.Это устраняет необходимость в работе удаленного демона и обеспечивает расширенные возможности, например, таких демонов syslog, как rsyslog и syslog-ng.Та же философия относится и к SMTP.Просто отдайте его местному программному обеспечению SMTP.В этом случае используйте «режим программы», а не демон, но это та же идея.Позвольте более способному программному обеспечению справиться с этим.Становятся возможными повторные попытки, постановка в очередь, локальная буферизация, использование TCP вместо UDP для системного журнала и т. Д.Вы также можете [заново] настроить эти демоны отдельно от своего кода, как и должно быть.

Сохраните код для своего приложения, чтобы другие программы выполняли свою работу согласованно.

15 голосов
/ 16 июля 2014

Я нашел модуль системного журнала , чтобы упростить получение описанного вами базового поведения ведения журнала:

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

Есть и другие вещи, которые вы могли бы сделать, но даже простопервые две строчки помогут вам получить то, о чем вы просили, насколько я понимаю.

14 голосов
/ 14 октября 2013

Соединяя вещи отсюда и из других мест, это то, что я придумал, это работает на unbuntu 12.04 и centOS6

Создайте файл в /etc/rsyslog.d/, заканчивающийся на .conf, и добавьте следующий текст

local6.*        /var/log/my-logfile

Перезапустите rsyslog, перезагрузка, похоже, не работает для новых файлов журнала.Может быть, он только перезагружает существующие файлы conf?

sudo restart rsyslog

Тогда вы можете использовать эту тестовую программу, чтобы убедиться, что она действительно работает.

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")
11 голосов
/ 09 марта 2012

Я добавляю небольшой дополнительный комментарий на тот случай, если он кому-нибудь поможет, потому что я нашел этот обмен полезным, но мне понадобился этот небольшой дополнительный кусочек информации, чтобы все это заработало.

Чтобы войти в конкретное средство с помощью SysLogHandler, вынужно указать стоимость объекта.Скажем, например, что вы определили:

local3.* /var/log/mylog

в системном журнале, тогда вы захотите использовать:

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

ивам также нужно прослушивать системный журнал по UDP, чтобы использовать localhost вместо /dev/log.

10 голосов
/ 19 октября 2010

Ваш syslog.conf настроен для обработки средства = пользователя?

Вы можете установить средство, используемое регистратором python, с аргументом средства, примерно так:

handler = logging.handlers.SysLogHandler(facility=SysLogHandler.LOG_DAEMON)
7 голосов
/ 17 июля 2013

С 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 __name__ == '__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')
6 голосов
/ 21 июня 2012
import syslog
syslog.openlog(ident="LOG_IDENTIFIER",logoption=syslog.LOG_PID, facility=syslog.LOG_LOCAL0)
syslog.syslog('Log processing initiated...')

вышеприведенный скрипт будет входить в систему LOCAL0 с нашим пользовательским «LOG_IDENTIFIER» ... Вы можете использовать LOCAL [0-7] для локальных целей.

3 голосов
/ 13 января 2018

Вот способ yaml dictConfig, рекомендуемый для 3.2 и более поздних версий.

В журнале 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

Загрузите конфигурацию, используя:

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

Настроенои системный журнал & прямой файл.Обратите внимание, что /dev/log зависит от ОС.

0 голосов
/ 26 октября 2013

Вы также можете добавить обработчик файла или вращающийся обработчик файла, чтобы отправить свои журналы в локальный файл: http://docs.python.org/2/library/logging.handlers.html

...