系统日志中的多行日志logging

所以我configuration了我的Python应用程序,用Python的SysLogHandlerlogin到syslog,一切正常。 除了多线处理。 不是我需要发出多行日志logging(我做了一点),但我需要能够读取Python的exception。 我使用rsyslog 4.2.0的Ubuntu。 这是我得到的:

Mar 28 20:11:59 telemachos root: ERROR 'EXCEPTION'#012Traceback (most recent call last):#012 File "./test.py", line 22, in <module>#012 foo()#012 File "./test.py", line 13, in foo#012 bar()#012 File "./test.py", line 16, in bar#012 bla()#012 File "./test.py", line 19, in bla#012 raise Exception("EXCEPTION!")#012Exception: EXCEPTION! 

testing代码,以防您需要它:

 import logging from logging.handlers import SysLogHandler logger = logging.getLogger() logger.setLevel(logging.INFO) syslog = SysLogHandler(address='/dev/log', facility='local0') formatter = logging.Formatter('%(name)s: %(levelname)s %(message)r') syslog.setFormatter(formatter) logger.addHandler(syslog) def foo(): bar() def bar(): bla() def bla(): raise Exception("EXCEPTION!") try: foo() except: logger.exception("EXCEPTION") 

另外,如果你想保持你的系统日志完整的parsing,你可以在查看日志时replace字符。

 tail -f /var/log/syslog | sed 's/#012/\n\t/g' 

好,终于想出来了…

rsyslog默认转义所有奇怪的字符(ASCII <32),这包括换行符(以及制表符和其他)。 只需将此添加到您的rsyslogconfigurationclosures此:

 $EscapeControlCharactersOnReceive off 

另一个select是对SysLogHandler进行子类化并重写emit() – 然后可以在发送的文本中为每一行调用超类emit() 。 就像是:

 from logging import LogRecord from logging.handlers import SysLogHandler class MultilineSysLogHandler(SysLogHandler): def emit(self, record): if '\n' in record.msg: record_args = [record.args] if isinstance(record.args, dict) else record.args for single_line in record.msg.split('\n'): single_line_record = LogRecord( name=record.name, level=record.levelno, pathname=record.pathname, msg=single_line, args=record_args, exc_info=record.exc_info, func=record.funcName ) super(MultilineSysLogHandler, self).emit(single_line_record) else: super(MultilineSysLogHandler, self).emit(record)