我喜欢lithoxyl的外观,并希望逐步替换flask.logger的当前用法。
是否有一种让两个日志记录框架共存的好方法?
到目前为止,我有以下内容:
from flask import current_app
from werkzeug.local import LocalProxy
logger = LocalProxy(lambda: current_app.logger)
class LogAdaptor(object):
"""file-like object that will write messages to the logger"""
def write(self, msg):
if msg.strip():
logger.info(msg)
from lithoxyl import StreamEmitter, SensibleFormatter
emtr = StreamEmitter(LogAdaptor())
fmtr = SensibleFormatter('{level_name_upper} {module_name} {end_message}')
# ... the rest is basically the same as http://lithoxyl.readthedocs.io/en/latest/overview.html#logging-sensibly
这或多或少有效,但输出中的日志级别丢失,例如:
DEBUG backend: log message from app.logger.debug
INFO logger: CRITICAL "backend" "critical action failed"
INFO logger: DEBUG "backend" "action succeeded"
DEBUG backend: log message from app.logger.debug
我猜测所需的是一个更复杂的发射器,或者是一种在Flask.logger处理程序中访问底层流的.write的方法(绕过格式化等)。
或者这只是咆哮错误的树,我应该只使用拆分日志文件,直到它全部重构?
答案 0 :(得分:1)
I've managed to make some improvements as I found https://github.com/mahmoud/lithoxyl/blob/master/lithoxyl/_syslog_emitter.py and created a similar class:
import logging
from lithoxyl.common import DEBUG, INFO, CRITICAL, get_level
class LoggerEmitter(object):
priority_map = {DEBUG: {'success': logging.DEBUG,
'failure': logging.INFO,
'warn': logging.INFO,
'exception': logging.WARNING},
INFO: {'success': logging.INFO,
'failure': logging.WARNING,
'warn': logging.WARNING,
'exception': logging.ERROR},
CRITICAL: {'success': logging.WARNING,
'failure': logging.ERROR,
'warn': logging.ERROR,
'exception': logging.CRITICAL}}
def __init__(self, logger):
self.logger = logger
def on_begin(self, begin_event, entry):
level = self._get_level('begin', begin_event)
self.logger.log(level, entry)
def on_warn(self, warn_event, entry):
level = self._get_level('warn', warn_event)
self.logger.log(level, entry)
def on_end(self, end_event, entry):
level = self._get_level('end', end_event)
self.logger.log(level, entry)
def _get_level(self, event_name, action):
level = get_level(action.level)
if event_name == 'warn':
status = 'warn'
elif event_name == 'begin':
status = 'begin'
else:
status = action.status
return self.priority_map[level][status]
emtr = LoggerEmitter(logger)
The output is now something like:
DEBUG backend: log message from app.logger.debug
ERROR logger: "backend" "critical action failed"
DEBUG logger: "backend" "action succeeded"
DEBUG backend: log message from app.logger.debug
Which is better, but it would be nice if the module name was passed through properly too.