前段时间,我看到一个Mono应用程序的输出是彩色的,可能是因为它的日志系统(因为所有的消息都是标准化的)。

现在,Python有了日志记录模块,它允许您指定许多选项来定制输出。所以,我想象类似的事情可能与Python,但我不知道如何在任何地方做到这一点。

是否有办法使Python日志模块输出为彩色?

我想要的(例如)错误显示为红色,调试消息显示为蓝色或黄色,等等。

当然,这可能需要一个兼容的终端(大多数现代终端都是);但如果不支持颜色,我可以退回到原始的日志输出。

有什么想法,我可以得到彩色输出与日志模块?


当前回答

虽然其他解决方案看起来不错,但它们存在一些问题。有些人会给整条线上色,有时这是不需要的,有些人会省略你可能在一起的任何配置。下面的解决方案只影响消息本身。

Code

class ColoredFormatter(logging.Formatter):
    def format(self, record):
        if record.levelno == logging.WARNING:
            record.msg = '\033[93m%s\033[0m' % record.msg
        elif record.levelno == logging.ERROR:
            record.msg = '\033[91m%s\033[0m' % record.msg
        return logging.Formatter.format(self, record)

例子

logger = logging.getLogger('mylogger')
handler = logging.StreamHandler()

log_format = '[%(asctime)s]:%(levelname)-7s:%(message)s'
time_format = '%H:%M:%S'
formatter = ColoredFormatter(log_format, datefmt=time_format)
handler.setFormatter(formatter)
logger.addHandler(handler)

logger.warn('this should be yellow')
logger.error('this should be red')

输出

[17:01:36]:WARNING:this should be yellow
[17:01:37]:ERROR  :this should be red

如您所见,其他所有内容仍然输出并保持初始颜色。如果您想要更改消息以外的任何内容,您可以简单地将颜色代码传递给示例中的log_format。

其他回答

一个方便的带有tput颜色的bash脚本

# Simple using tput
bold=$(tput bold)
reset=$(tput sgr0)

fblack=$(tput setaf 0)
fred=$(tput setaf 1)
fgreen=$(tput setaf 2)
fyellow=$(tput setaf 3)
fblue=$(tput setaf 4)
fmagenta=$(tput setaf 5)
fcyan=$(tput setaf 6)
fwhite=$(tput setaf 7)
fnotused=$(tput setaf 8)
freset=$(tput setaf 9)

bblack=$(tput setab 0)
bred=$(tput setab 1)
bgreen=$(tput setab 2)
byellow=$(tput setab 3)
bblue=$(tput setab 4)
bmagenta=$(tput setab 5)
bcyan=$(tput setab 6)
bwhite=$(tput setab 7)
bnotused=$(tput setab 8)
breset=$(tput setab 9)

# 0 - Emergency (emerg)       $fred       # something is wrong... go red
# 1 - Alerts (alert)          $fred       # something is wrong... go red
# 2 - Critical (crit)         $fred       # something is wrong... go red
# 3 - Errors (err)            $fred       # something is wrong... go red
# 4 - Warnings (warn)         $fyellow    # yellow yellow dirty logs
# 5 - Notification (notice)   $fwhite     # common stuff
# 6 - Information (info)      $fblue      # sky is blue
# 7 - Debug (debug)           $fgreen     # lot of stuff to read... go green 

现在有一个发布的PyPi模块,用于自定义彩色日志输出:

https://pypi.python.org/pypi/rainbow_logging_handler/

and

https://github.com/laysakura/rainbow_logging_handler

支持Windows 支持Django 可定制的颜色

由于它是作为Python卵分发的,因此非常容易为任何Python应用程序安装它。

更新:因为这是我长久以来一直想要解决的问题,所以我为像我这样只想用简单方法做事的懒人写了一个库:zenlog

Colorlog在这方面非常出色。它在PyPI上可用(因此可以通过pip install colorlog进行安装),并且是主动维护的。

下面是一个快速复制粘贴代码片段,用于设置日志记录和打印像样的日志消息:

import logging
LOG_LEVEL = logging.DEBUG
LOGFORMAT = "  %(log_color)s%(levelname)-8s%(reset)s | %(log_color)s%(message)s%(reset)s"
from colorlog import ColoredFormatter
logging.root.setLevel(LOG_LEVEL)
formatter = ColoredFormatter(LOGFORMAT)
stream = logging.StreamHandler()
stream.setLevel(LOG_LEVEL)
stream.setFormatter(formatter)
log = logging.getLogger('pythonConfig')
log.setLevel(LOG_LEVEL)
log.addHandler(stream)

log.debug("A quirky message only developers care about")
log.info("Curious users might want to know this")
log.warn("Something is wrong and any user should be informed")
log.error("Serious stuff, this is red for a reason")
log.critical("OH NO everything is on fire")

输出:

虽然其他解决方案看起来不错,但它们存在一些问题。有些人会给整条线上色,有时这是不需要的,有些人会省略你可能在一起的任何配置。下面的解决方案只影响消息本身。

Code

class ColoredFormatter(logging.Formatter):
    def format(self, record):
        if record.levelno == logging.WARNING:
            record.msg = '\033[93m%s\033[0m' % record.msg
        elif record.levelno == logging.ERROR:
            record.msg = '\033[91m%s\033[0m' % record.msg
        return logging.Formatter.format(self, record)

例子

logger = logging.getLogger('mylogger')
handler = logging.StreamHandler()

log_format = '[%(asctime)s]:%(levelname)-7s:%(message)s'
time_format = '%H:%M:%S'
formatter = ColoredFormatter(log_format, datefmt=time_format)
handler.setFormatter(formatter)
logger.addHandler(handler)

logger.warn('this should be yellow')
logger.error('this should be red')

输出

[17:01:36]:WARNING:this should be yellow
[17:01:37]:ERROR  :this should be red

如您所见,其他所有内容仍然输出并保持初始颜色。如果您想要更改消息以外的任何内容,您可以简单地将颜色代码传递给示例中的log_format。

请看下面的解决方案。流处理程序应该是做着色的事情,然后你可以选择着色单词而不仅仅是整行(与Formatter)。

http://plumberjack.blogspot.com/2010/12/colorizing-logging-output-in-terminals.html