Как установить строку идентификатора при использовании logging.SysLogHandler в Python 2.6? - PullRequest
6 голосов
/ 24 ноября 2010

У меня настроено ведение журнала с помощью logging.fileConfig (). У меня есть корневой логгер, идущий к обработчику, который использует SysLogHandler ('/ dev / log', handlers.SysLogHandler.LOG_USER)

Это все работает отлично, и я вижу свои записи в журнале /var/log/user.log

.

Вопрос в том, как установить строку идентификатора системного журнала в нечто отличное от python? Похоже, модуль системного журнала в стандартной библиотеке позволяет установить это при открытии журнала, но обработчик ведения журнала не предлагает эту функцию.

Было бы решение подкласса SysLogHandler и использовать библиотеку syslog внутри его метода emit? Это программа только для Unix, поэтому использование syslog напрямую не создает проблем с переносимостью.

Ответы [ 4 ]

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

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

Начиная с Python 3.3, SysLogHandler атрибут класса .ident именно для этой цели;значение по умолчанию для него ''.

Пример:

import logging
from logging.handlers import SysLogHandler

h = SysLogHandler(address=('some.destination.com',514), facility=SysLogHandler.LOG_LOCAL6)
h.setFormatter(
    logging.Formatter('%(name)s %(levelname)s %(message)s')
)
h.ident = 'conmon'

syslog = logging.getLogger('syslog')
syslog.setLevel(logging.DEBUG)
syslog.addHandler(h)

syslog.debug('foo syslog message')
3 голосов
/ 13 декабря 2016

Реализации системного журнала, принимающие RFC3164 сообщения, должны распознавать первую часть сообщения ("foo:" в примере) как TAG.

Часть MSG имеет два поля, известные какПоле TAG и поле CONTENT.Значением в поле TAG будет имя программы или процесса, который сгенерировал сообщение.

Код Python ..

import logging
from logging.handlers import SysLogHandler

h = SysLogHandler(address='/dev/log')
h.setFormatter(logging.Formatter('foo: %(message)s'))
logging.getLogger().addHandler(h)

logging.error('bar')

.. отправит его в сокет системного журнала

connect(3, {sa_family=AF_UNIX, sun_path="/dev/log"}, 10) = 0
sendto(3, "<11>foo: bar\0", 13, 0, NULL, 0) = 13
close(3)

Что, в свою очередь, приводит к этому в журнале systemd.

Dec 13 14:48:20 laptop foo[1928]: bar

Подробности сообщения журнала:

{
  ..
  "PRIORITY" : "3",
  "SYSLOG_FACILITY" : "1",
  "SYSLOG_IDENTIFIER" : "foo",
  "MESSAGE" : "bar",
  "_PID" : "1928",
}

Работает с Py2.6, 2.7,3.4, 3.5 и системный журнал Systemd.Он также может работать с другими реализациями системного журнала (если они принимают RFC3164).Это решение, вероятно, сломается, когда SysLogHandler в Python по умолчанию установит новый RFC5424.

3 голосов
/ 24 ноября 2010

AFAIK, строка идентификатора является артефактом API системного журнала, см. эту страницу .Он просто использует C argv [0], который, конечно, будет «python».

Я удивлен, что вы получаете это, используя SysLogHandler с сокетом домена, как сообщение, отправленное демонам syslogчерез домен или сокеты TCP это просто строка с приоритетом всопровождаемое отформатированным сообщением и байтом NUL.Строка идентификатора, указанная в SysLogHandler, не указана, так как она не использует API системного журнала (в некоторых версиях есть проблемы с безопасностью потоков, IIRC).

2 голосов
/ 04 сентября 2015

Для Python 2.7 вы можете сделать что-то вроде этого:

class MySysLogHandler(logging.handlers.SysLogHandler):
    def __init__(self):
        super(MySysLogHandler, self).__init__(address='/dev/log')
    def emit(self, record):
        priority = self.encodePriority(self.facility, self.mapPriority(record.levelname))
        record.ident = "My[" + str(priority) + "]:"
        super(MySysLogHandler, self).emit(record)

handler = MySysLogHandler()
handler.formatter = logging.Formatter(fmt="%(ident)s %(levelname)s: %(message)s")
logging.root.addHandler(handler)
logging.info("hello world")

Это выдаст в системном журнале:

Sep 3 16:28:53 hostname My[14]: INFO: hello world

...