前一段时间,我看到了一个带有彩色输出的Mono应用程序,大概是因为它的日志系统(因为所有消息都是标准化的)。
现在,Python具有logging
模块,该模块可让您指定许多选项来定制输出。 因此,我在想使用Python可能会发生类似的事情,但是我找不到在任何地方执行此操作的方法。
有什么方法可以使Python logging
模块以彩色输出吗?
我想要的(例如)红色错误,蓝色或黄色调试消息等等。
当然,这可能需要兼容的终端(大多数现代终端都需要)。 但是如果不支持颜色,我可能会退回到原始logging
输出。
有什么想法可以使用日志记录模块获取彩色输出吗?
#1楼
这是一个可以在任何平台上运行的解决方案。 如果不只是告诉我,我会进行更新。
工作原理:在支持ANSI转义的平台上(非Windows)正在使用它们,而在Windows上,它确实使用API调用来更改控制台颜色。
该脚本确实从标准库中破解了logging.StreamHandler.emit方法,并为其添加了一个包装器。
TestColorer.py
# Usage: add Colorer.py near you script and import it.
import logging
import Colorer
logging.warn("a warning")
logging.error("some error")
logging.info("some info")
着色器
#!/usr/bin/env python
# encoding: utf-8
import logging
# now we patch Python code to add color support to logging.StreamHandler
def add_coloring_to_emit_windows(fn):
# add methods we need to the class
def _out_handle(self):
import ctypes
return ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
out_handle = property(_out_handle)
def _set_color(self, code):
import ctypes
# Constants from the Windows API
self.STD_OUTPUT_HANDLE = -11
hdl = ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
ctypes.windll.kernel32.SetConsoleTextAttribute(hdl, code)
setattr(logging.StreamHandler, '_set_color', _set_color)
def new(*args):
FOREGROUND_BLUE = 0x0001 # text color contains blue.
FOREGROUND_GREEN = 0x0002 # text color contains green.
FOREGROUND_RED = 0x0004 # text color contains red.
FOREGROUND_INTENSITY = 0x0008 # text color is intensified.
FOREGROUND_WHITE = FOREGROUND_BLUE|FOREGROUND_GREEN |FOREGROUND_RED
# winbase.h
STD_INPUT_HANDLE = -10
STD_OUTPUT_HANDLE = -11
STD_ERROR_HANDLE = -12
# wincon.h
FOREGROUND_BLACK = 0x0000
FOREGROUND_BLUE = 0x0001
FOREGROUND_GREEN = 0x0002
FOREGROUND_CYAN = 0x0003
FOREGROUND_RED = 0x0004
FOREGROUND_MAGENTA = 0x0005
FOREGROUND_YELLOW = 0x0006
FOREGROUND_GREY = 0x0007
FOREGROUND_INTENSITY = 0x0008 # foreground color is intensified.
BACKGROUND_BLACK = 0x0000
BACKGROUND_BLUE = 0x0010
BACKGROUND_GREEN = 0x0020
BACKGROUND_CYAN = 0x0030
BACKGROUND_RED = 0x0040
BACKGROUND_MAGENTA = 0x0050
BACKGROUND_YELLOW = 0x0060
BACKGROUND_GREY = 0x0070
BACKGROUND_INTENSITY = 0x0080 # background color is intensified.
levelno = args[1].levelno
if(levelno>=50):
color = BACKGROUND_YELLOW | FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY
elif(levelno>=40):
color = FOREGROUND_RED | FOREGROUND_INTENSITY
elif(levelno>=30):
color = FOREGROUND_YELLOW | FOREGROUND_INTENSITY
elif(levelno>=20):
color = FOREGROUND_GREEN
elif(levelno>=10):
color = FOREGROUND_MAGENTA
else:
color = FOREGROUND_WHITE
args[0]._set_color(color)
ret = fn(*args)
args[0]._set_color( FOREGROUND_WHITE )
#print "after"
return ret
return new
def add_coloring_to_emit_ansi(fn):
# add methods we need to the class
def new(*args):
levelno = args[1].levelno
if(levelno>=50):
color = '\x1b[31m' # red
elif(levelno>=40):
color = '\x1b[31m' # red
elif(levelno>=30):
color = '\x1b[33m' # yellow
elif(levelno>=20):
color = '\x1b[32m' # green
elif(levelno>=10):
color = '\x1b[35m' # pink
else:
color = '\x1b[0m' # normal
args[1].msg = color + args[1].msg + '\x1b[0m' # normal
#print "after"
return fn(*args)
return new
import platform
if platform.system()=='Windows':
# Windows does not support ANSI escapes and we are using API calls to set the console color
logging.StreamHandler.emit = add_coloring_to_emit_windows(logging.StreamHandler.emit)
else:
# all non-Windows platforms are supporting ANSI escapes so we use them
logging.StreamHandler.emit = add_coloring_to_emit_ansi(logging.StreamHandler.emit)
#log = logging.getLogger()
#log.addFilter(log_filter())
#//hdlr = logging.StreamHandler()
#//hdlr.setFormatter(formatter())
#2楼
刚刚回答了同样的类似的问题: Python的| 更改外壳中的文本颜色
这个想法是使用clint库。 它支持MAC,Linux和Windows Shell(CLI)。
#3楼
多年前,我写了一个彩色的流处理程序供自己使用。 然后,我浏览了此页面,发现了人们正在复制/粘贴的代码片段集合:-(。我的流处理程序当前仅在UNIX(Linux,Mac OS X)上可用,但是优点是可以在PyPI (和GitHub)上使用 ),而且使用起来非常简单,还具有Vim语法模式:-)。 将来我可能会将其扩展到Windows上。
要安装软件包:
$ pip install coloredlogs
确认它有效:
$ coloredlogs --demo
要开始使用自己的代码:
$ python
> import coloredlogs, logging
> coloredlogs.install()
> logging.info("It works!")
2014-07-30 21:21:26 peter-macbook root[7471] INFO It works!
上例中显示的默认日志格式包含日期,时间,主机名,记录器的名称,PID,日志级别和日志消息。 实际上是这样的:

注意:使用带有MinTTY的Git Bash时
Windows上的Git Bash有一些已记录的怪癖: Winpty和Git Bash
对于ANSI转义码以及ncurses样式字符重写和动画,您需要在命令winpty
加上winpty
。
$ winpty coloredlogs --demo
$ winpty python your_colored_logs_script.py
#4楼
现在有一个已发布的PyPi模块,用于自定义彩色日志输出:
https://pypi.python.org/pypi/rainbow_logging_handler/
和
https://github.com/laysakura/rainbow_logging_handler
支持Windows
支持Django
可自定义的颜色
由于它是作为Python鸡蛋分发的,因此对于任何Python应用程序都非常容易安装。
#5楼
我修改了Sorin提供的原始示例,并将StreamHandler子类化为ColorizedConsoleHandler。
他们解决方案的缺点是它修改了消息,并且因为那是在修改实际的日志消息,所以其他任何处理程序也将获得修改后的消息。
在我们的例子中,这导致在日志文件中带有颜色代码,因为我们使用了多个记录器。
下面的类仅在支持ansi的平台上起作用,但是向其添加Windows颜色代码应该是微不足道的。
import copy
import logging
class ColoredConsoleHandler(logging.StreamHandler):
def emit(self, record):
# Need to make a actual copy of the record
# to prevent altering the message for other loggers
myrecord = copy.copy(record)
levelno = myrecord.levelno
if(levelno >= 50): # CRITICAL / FATAL
color = '\x1b[31m' # red
elif(levelno >= 40): # ERROR
color = '\x1b[31m' # red
elif(levelno >= 30): # WARNING
color = '\x1b[33m' # yellow
elif(levelno >= 20): # INFO
color = '\x1b[32m' # green
elif(levelno >= 10): # DEBUG
color = '\x1b[35m' # pink
else: # NOTSET and anything else
color = '\x1b[0m' # normal
myrecord.msg = color + str(myrecord.msg) + '\x1b[0m' # normal
logging.StreamHandler.emit(self, myrecord)
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3194890