Как настроить ведение журнала в 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. - Что случилось?
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 rsyslogimport 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