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

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

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

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

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

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

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

local3.* /var/log/mylog

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

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

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

Ответ 6

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

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

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

Ответ 7

import syslog
syslog.openlog(ident="LOG_IDENTIFIER",logoption=syslog.LOG_PID, facility=syslog.LOG_LOCAL0)
syslog.syslog('Log processing initiated...')

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

Ответ 8

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

Ответ 9

Здесь способ 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)

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

Ответ 10

Я фиксирую это на своем ноутбуке. Служба rsyslog не прослушивала службу сокетов.

Я настроил эту строку ниже в файле /etc/rsyslog.conf и решил проблему:

$SystemLogSocketName /dev/log

Ответ 11

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