JS.*_*JS. 11 logging python-3.x
我在这里问了python 2的这个问题,但是当Python 3.2.3的答案不再有效时再次遇到了问题.
这里的代码适用于Python 2.7.3:
import logging
# Attempt to set up a Python3 logger than will print custom messages
# based on each message's logging level.
# The technique recommended for Python2 does not appear to work for
# Python3
class CustomConsoleFormatter(logging.Formatter):
"""
Modify the way DEBUG messages are displayed.
"""
def __init__(self, fmt="%(levelno)d: %(msg)s"):
logging.Formatter.__init__(self, fmt=fmt)
def format(self, record):
# Remember the original format
format_orig = self._fmt
if record.levelno == logging.DEBUG:
self._fmt = "DEBUG: %(msg)s"
# Call the original formatter to do the grunt work
result = logging.Formatter.format(self, record)
# Restore the original format
self._fmt = format_orig
return result
# Set up a logger
my_logger = logging.getLogger("my_custom_logger")
my_logger.setLevel(logging.DEBUG)
my_formatter = CustomConsoleFormatter()
console_handler = logging.StreamHandler()
console_handler.setFormatter(my_formatter)
my_logger.addHandler(console_handler)
my_logger.debug("This is a DEBUG-level message")
my_logger.info("This is an INFO-level message")
Run Code Online (Sandbox Code Playgroud)
使用Python 2.7.3运行:
tcsh-16: python demo_python_2.7.3.py
DEBUG: This is a DEBUG-level message
20: This is an INFO-level message
Run Code Online (Sandbox Code Playgroud)
据我所知,转换为Python3只需要一个稍微修改CustomConsoleFormatter.init():
def __init__(self):
super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')
Run Code Online (Sandbox Code Playgroud)
在Python 3.2.3上:
tcsh-26: python3 demo_python_3.2.3.py
10: This is a DEBUG-level message
20: This is an INFO-level message
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我想用'DEBUG'代替'10'的愿望被挫败了.
我已经尝试在Python3源码中进行挖掘,看起来PercentStyle实例化在我之后破坏了self._fmt,好吧,我自己就破坏了它.
我的伐木剁停止了能够解决这种皱纹.
任何人都可以推荐另一种方式或者指出我忽略的东西吗?
JS.*_*JS. 15
通过一些挖掘,我能够修改Python 2解决方案以使用Python 3.在Python2中,有必要暂时覆盖Formatter._fmt
.在Python3中,对多种格式字符串类型的支持要求我们临时覆盖Formatter._style._fmt
.
# Custom formatter
class MyFormatter(logging.Formatter):
err_fmt = "ERROR: %(msg)s"
dbg_fmt = "DBG: %(module)s: %(lineno)d: %(msg)s"
info_fmt = "%(msg)s"
def __init__(self):
super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')
def format(self, record):
# Save the original format configured by the user
# when the logger formatter was instantiated
format_orig = self._style._fmt
# Replace the original format with one customized by logging level
if record.levelno == logging.DEBUG:
self._style._fmt = MyFormatter.dbg_fmt
elif record.levelno == logging.INFO:
self._style._fmt = MyFormatter.info_fmt
elif record.levelno == logging.ERROR:
self._style._fmt = MyFormatter.err_fmt
# Call the original formatter class to do the grunt work
result = logging.Formatter.format(self, record)
# Restore the original format configured by the user
self._style._fmt = format_orig
return result
Run Code Online (Sandbox Code Playgroud)
这里是Halloleo的例子,说明如何在你的脚本中使用上述内容(来自这个问题的Python2版本):
fmt = MyFormatter()
hdlr = logging.StreamHandler(sys.stdout)
hdlr.setFormatter(fmt)
logging.root.addHandler(hdlr)
logging.root.setLevel(DEBUG)
Run Code Online (Sandbox Code Playgroud)
sez*_*zeb 11
我更喜欢这个,因为它更短、更简单,并且不需要像“ERROR”这样的字符串进行硬编码。无需重置._fmt
,因为else:
可以很好地处理。
另外,使用"%(msg)s"
不适用于惰性日志记录!
class Formatter(logging.Formatter):
def format(self, record):
if record.levelno == logging.INFO:
self._style._fmt = "%(message)s"
else:
self._style._fmt = "%(levelname)s: %(message)s"
return super().format(record)
Run Code Online (Sandbox Code Playgroud)
使用示例:
import logging
logger = logging.getLogger()
handler = logging.StreamHandler()
handler.setFormatter(Formatter())
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
logger.debug('foo')
logger.info('bar %d', 4)
Run Code Online (Sandbox Code Playgroud)
DEBUG: foo
bar 4
Run Code Online (Sandbox Code Playgroud)
如果您想让关卡名称着色:
DEBUG: foo
bar 4
Run Code Online (Sandbox Code Playgroud)
请参阅https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit了解颜色编号
归档时间: |
|
查看次数: |
4662 次 |
最近记录: |