Как настроить ведение журнала в syslog в Python?



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



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


Но этот скрипт не производит никаких записей журнала в syslog. - Что случилось?

754   10  

10 ответов:

Измените строку следующим образом:

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

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

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

Собирая вещи вместе отсюда и из других мест, это то, что я придумал, что работает на unbunt 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")

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

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

local3.* /var/log/mylog

В syslog, то вы захотите использовать:

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

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

- это ваш системный журнал.conf настроен на обработку объекта=пользователь?

Вы можете задать объект, используемый python logger с аргументом facility, примерно так:

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

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

import syslog
syslog.syslog("This is a test message")
syslog.syslog(syslog.LOG_INFO, "Test message at INFO priority")
Есть и другие вещи, которые вы могли бы сделать, но даже только первые две строки из этого дадут вам то, о чем вы просили, как я понимаю.

Из 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')
import syslog
syslog.openlog(ident="LOG_IDENTIFIER",logoption=syslog.LOG_PID, facility=syslog.LOG_LOCAL0)
syslog.syslog('Log processing initiated...')

Приведенный выше скрипт будет регистрироваться в LOCAL0 facility с помощью нашего пользовательского "LOG_IDENTIFIER"... вы можете использовать LOCAL[0-7] для локальных целей.

Вот способ 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 является специфичным для ОС.

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

Comments

    Ничего не найдено.