当前位置:  开发笔记 > 编程语言 > 正文

如何为Python日志输出着色?

如何解决《如何为Python日志输出着色?》经验,为你挑选了16个好方法。

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

现在,Python有了这个logging模块,它允许你指定很多选项来自定义输出.所以,我想象Python可能会有类似的东西,但我无法在任何地方找到如何做到这一点.

有没有办法让Python logging模块输出颜色?

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

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

有关如何使用记录模块获得彩色输出的任何想法?



1> airmind..:

我已经知道了颜色逃逸,我刚才在我的bash提示中使用过它们.不管怎么说,还是要谢谢你.
我想要的是将它与日志记录模块集成,我最终在经过几次尝试和错误之后做了.
这是我最终得到的:

BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)

#The background is set with 40 plus the number of the color, and the foreground with 30

#These are the sequences need to get colored ouput
RESET_SEQ = "\033[0m"
COLOR_SEQ = "\033[1;%dm"
BOLD_SEQ = "\033[1m"

def formatter_message(message, use_color = True):
    if use_color:
        message = message.replace("$RESET", RESET_SEQ).replace("$BOLD", BOLD_SEQ)
    else:
        message = message.replace("$RESET", "").replace("$BOLD", "")
    return message

COLORS = {
    'WARNING': YELLOW,
    'INFO': WHITE,
    'DEBUG': BLUE,
    'CRITICAL': YELLOW,
    'ERROR': RED
}

class ColoredFormatter(logging.Formatter):
    def __init__(self, msg, use_color = True):
        logging.Formatter.__init__(self, msg)
        self.use_color = use_color

    def format(self, record):
        levelname = record.levelname
        if self.use_color and levelname in COLORS:
            levelname_color = COLOR_SEQ % (30 + COLORS[levelname]) + levelname + RESET_SEQ
            record.levelname = levelname_color
        return logging.Formatter.format(self, record)

要使用它,请创建自己的Logger:

# Custom logger class with multiple destinations
class ColoredLogger(logging.Logger):
    FORMAT = "[$BOLD%(name)-20s$RESET][%(levelname)-18s]  %(message)s ($BOLD%(filename)s$RESET:%(lineno)d)"
    COLOR_FORMAT = formatter_message(FORMAT, True)
    def __init__(self, name):
        logging.Logger.__init__(self, name, logging.DEBUG)                

        color_formatter = ColoredFormatter(self.COLOR_FORMAT)

        console = logging.StreamHandler()
        console.setFormatter(color_formatter)

        self.addHandler(console)
        return


logging.setLoggerClass(ColoredLogger)

以防万一其他人需要它.

如果您使用多个记录器或处理程序,请小心:ColoredFormatter正在更改记录对象,该记录对象将进一步传递给其他处理程序或传播到其他记录程序.如果您已配置文件记录器等,则可能不希望在日志文件中包含颜色.为了避免这种情况,最好在返回格式化字符串之前简单地在操作levelname属性之前创建recordwith 的副本copy.copy(),或者将levelname重置为之前的值(在评论中记入Michael).


我不相信你应该为此创建一个记录器子类 - 你的答案很好,只要创建一个专门的`Formatter`并在`StreamHandler`上指定它的使用.但是不需要记录器子类.实际上,使用logger类会为每个创建的记录器添加一个处理程序,这不是您通常想要的.
"ColoredFormatter"的一面注释.它正在更改记录对象,该记录对象将进一步传递给其他处理程序或传播到其他记录程序.如果您已配置文件记录器等,则可能不希望在日志文件中包含颜色.为了避免这种情况,在返回格式化字符串之前,最好在操作levelname属性之前简单地创建带有`copy.copy()`的`record`副本,或者将levelname重置为之前的值.
@simon:http://plumberjack.blogspot.co.uk/2010/12/colorizing-logging-output-in-terminals.html

2> xolox..:

几年前我写了一个彩色的流处理程序供我自己使用.然后我遇到了这个页面,发现了一些人们正在复制/粘贴的代码片段:-(.我的流处理程序目前只适用于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,日志级别和日志消息.这就是它在实践中的样子:

有色日志输出的屏幕截图


这看起来很漂亮.不幸的是,它破坏了很多东西; 特别是,它使对logging.basicConfig的调用无效.例如,这使得无法使用自定义格式化程序.
很有趣,我只是想在这个帖子中添加一个链接到"https://pypi.python.org/pypi/coloredlogs/0.4.7"!

3> sorin..:

这是一个适用于任何平台的解决方案.如果它不只是告诉我,我会更新它.

工作原理:在支持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")

Colorer.py

#!/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())


我基于此编写了一个StreamHandler类,请参阅https://gist.github.com/mooware/a1ed40987b6cc9ab9c65.
这对我有用!第90行:应为args [1] .msg = color + str(args [1] .msg)+'\ x1b [0m'#normal”。

4> rlafuente..:

更新:因为这是我长期以来一直想要抓住的一个痒,我继续为像我这样只想要简单方法做事的懒人写了一个库: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")

输出:

Colorlog输出


很好的答案; +1.可以修剪代码示例(真的需要三次调用`setLevel`吗?)

5> 小智..:

针对预定义日志级别的快速而脏的解决方案,无需定义新类.

logging.addLevelName( logging.WARNING, "\033[1;31m%s\033[1;0m" % logging.getLevelName(logging.WARNING))
logging.addLevelName( logging.ERROR, "\033[1;41m%s\033[1;0m" % logging.getLevelName(logging.ERROR))


应用和理解最简单,最干净的解决方案.
由于只有日志级别的名称是彩色的,因此您必须确保将日志级别名称打印到控制台.这对我来说不是开箱即用的.这些方面的内容将有所帮助:`logging.basicConfig(format ='%(asctime)s [%(name)s] [%(levelname)s]%(message)s')`当然`%(levelnames) )s`很重要.

6> KCJ..:

好吧,我想我也可以添加我的彩色记录器的变化.

这并不奇怪,但它使用起来非常简单,并且不会更改记录对象,从而避免在使用文件处理程序时将ANSI转义序列记录到日志文件中.它不会影响日志消息格式.

如果您已经在使用日志记录模块的Formatter,那么要获得彩色级别名称,您只需要使用ColoredFormatter替换您的建议处理程序Formatter.如果您要记录整个应用程序,则只需要为顶级记录器执行此操作.

colored_log.py

#!/usr/bin/env python

from copy import copy
from logging import Formatter

MAPPING = {
    'DEBUG'   : 37, # white
    'INFO'    : 36, # cyan
    'WARNING' : 33, # yellow
    'ERROR'   : 31, # red
    'CRITICAL': 41, # white on red bg
}

PREFIX = '\033['
SUFFIX = '\033[0m'

class ColoredFormatter(Formatter):

    def __init__(self, patern):
        Formatter.__init__(self, patern)

    def format(self, record):
        colored_record = copy(record)
        levelname = colored_record.levelname
        seq = MAPPING.get(levelname, 37) # default white
        colored_levelname = ('{0}{1}m{2}{3}') \
            .format(PREFIX, seq, levelname, SUFFIX)
        colored_record.levelname = colored_levelname
        return Formatter.format(self, colored_record)

用法示例

app.py

#!/usr/bin/env python

import logging
from colored_log import ColoredFormatter

# Create top level logger
log = logging.getLogger("main")

# Add console handler using our custom ColoredFormatter
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
cf = ColoredFormatter("[%(name)s][%(levelname)s]  %(message)s (%(filename)s:%(lineno)d)")
ch.setFormatter(cf)
log.addHandler(ch)

# Add file handler
fh = logging.FileHandler('app.log')
fh.setLevel(logging.DEBUG)
ff = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(ff)
log.addHandler(fh)

# Set log level
log.setLevel(logging.DEBUG)

# Log some stuff
log.debug("app has started")
log.info("Logging to 'app.log' in the script dir")
log.warning("This is my last warning, take heed")
log.error("This is an error")
log.critical("He's dead, Jim")

# Import a sub-module 
import sub_module

sub_module.py

#!/usr/bin/env python

import logging
log = logging.getLogger('main.sub_module')

log.debug("Hello from the sub module")

结果

终端输出

终端输出

app.log内容

2017-09-29 00:32:23,434 - main - DEBUG - app has started
2017-09-29 00:32:23,434 - main - INFO - Logging to 'app.log' in the script dir
2017-09-29 00:32:23,435 - main - WARNING - This is my last warning, take heed
2017-09-29 00:32:23,435 - main - ERROR - This is an error
2017-09-29 00:32:23,435 - main - CRITICAL - He's dead, Jim
2017-09-29 00:32:23,435 - main.sub_module - DEBUG - Hello from the sub module

当然,您可以根据需要设置格式化终端和日志文件输出.只有日志级别才会着色.

我希望有人觉得这很有用,而且不仅仅是太多了.:)

可以从这个GitHub Gist下载Python示例文件:https: //gist.github.com/KurtJacobson/48e750701acec40c7161b5a2f79e6bfd


顺便说一句,要为消息本身添加颜色,只需在return之前添加以下行:colored_record.msg =('{0} {1} m {2} {3}')。format(self.PREFIX,seq,colored_record。 getMessage(),self.SUFFIX)`

7> camillobruni..:

我从airmind支持前景和背景标签更新了示例.只需在日志格式化程序字符串中使用颜色变量$ BLACK - $ WHITE.设置背景只需使用$ BG-BLACK - $ BG-WHITE.

import logging

BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)

COLORS = {
    'WARNING'  : YELLOW,
    'INFO'     : WHITE,
    'DEBUG'    : BLUE,
    'CRITICAL' : YELLOW,
    'ERROR'    : RED,
    'RED'      : RED,
    'GREEN'    : GREEN,
    'YELLOW'   : YELLOW,
    'BLUE'     : BLUE,
    'MAGENTA'  : MAGENTA,
    'CYAN'     : CYAN,
    'WHITE'    : WHITE,
}

RESET_SEQ = "\033[0m"
COLOR_SEQ = "\033[1;%dm"
BOLD_SEQ  = "\033[1m"

class ColorFormatter(logging.Formatter):

    def __init__(self, *args, **kwargs):
        # can't do super(...) here because Formatter is an old school class
        logging.Formatter.__init__(self, *args, **kwargs)

    def format(self, record):
        levelname = record.levelname
        color     = COLOR_SEQ % (30 + COLORS[levelname])
        message   = logging.Formatter.format(self, record)
        message   = message.replace("$RESET", RESET_SEQ)\
                           .replace("$BOLD",  BOLD_SEQ)\
                           .replace("$COLOR", color)
        for k,v in COLORS.items():
            message = message.replace("$" + k,    COLOR_SEQ % (v+30))\
                             .replace("$BG" + k,  COLOR_SEQ % (v+40))\
                             .replace("$BG-" + k, COLOR_SEQ % (v+40))
        return message + RESET_SEQ

logging.ColorFormatter = ColorFormatter

所以现在您可以在配置文件中简单地执行以下操作:

[formatter_colorFormatter]
class=logging.ColorFormatter
format= $COLOR%(levelname)s $RESET %(asctime)s $BOLD$COLOR%(name)s$RESET %(message)s



8> maxschlepzig..:

您可以导入colorlog模块并将其ColoredFormatter用于着色日志消息.

主模块的锅炉板:

import logging
import os
import sys
try:
    import colorlog
except ImportError:
    pass

def setup_logging():
    root = logging.getLogger()
    root.setLevel(logging.DEBUG)
    format      = '%(asctime)s - %(levelname)-8s - %(message)s'
    date_format = '%Y-%m-%d %H:%M:%S'
    if 'colorlog' in sys.modules and os.isatty(2):
        cformat = '%(log_color)s' + format
        f = colorlog.ColoredFormatter(cformat, date_format,
              log_colors = { 'DEBUG'   : 'reset',       'INFO' : 'reset',
                             'WARNING' : 'bold_yellow', 'ERROR': 'bold_red',
                             'CRITICAL': 'bold_red' })
    else:
        f = logging.Formatter(format, date_format)
    ch = logging.StreamHandler()
    ch.setFormatter(f)
    root.addHandler(ch)

setup_logging()
log = logging.getLogger(__name__)

如果安装了colorlog模块并且输出实际上发送到终端,则代码仅启用日志消息中的颜色.这样可以避免在重定向日志输出时将转义序列写入文件.

此外,设置自定义颜色方案,更适合具有深色背景的终端.

一些示例记录调用:

log.debug   ('Hello Debug')
log.info    ('Hello Info')
log.warn    ('Hello Warn')
log.error   ('Hello Error')
log.critical('Hello Critical')

输出:

在此输入图像描述


也可以使用`colorlog.basicConfig`代替`logging.basicConfig`,它有一些很好的默认值

9> 小智..:

我将Sorin提供的原始示例和子类化的StreamHandler修改为ColorizedConsoleHandler.

他们的解决方案的缺点是它修改了消息,因为这正在修改实际的logmessage,任何其他处理程序也将获得修改后的消息.

由于我们使用多个记录器,因此在我们的案例中导致了带有颜色代码的日志文件.

下面的类只适用于支持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)



10> Nick..:

请看以下解决方案.流处理程序应该是着色的东西,然后你可以选择着色单词而不是整行(使用Formatter).

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



11> Mikko Ohtama..:

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

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

https://github.com/laysakura/rainbow_logging_handler

支持Windows

支持Django

可定制的颜色

由于它是作为Python egg分发的,因此很容易为任何Python应用程序安装.



12> Sergey Plesh..:
2019代码,无需其他软件包,Python 3

定义一个班级

import logging

class CustomFormatter(logging.Formatter):
    """Logging Formatter to add colors and count warning / errors"""

    grey = "\x1b[38;21m"
    yellow = "\x1b[33;21m"
    red = "\x1b[31;21m"
    bold_red = "\x1b[31;1m"
    reset = "\x1b[0m"
    format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)"

    FORMATS = {
        logging.DEBUG: grey + format + reset,
        logging.INFO: grey + format + reset,
        logging.WARNING: yellow + format + reset,
        logging.ERROR: red + format + reset,
        logging.CRITICAL: bold_red + format + reset
    }

    def format(self, record):
        log_fmt = self.FORMATS.get(record.levelno)
        formatter = logging.Formatter(log_fmt)
        return formatter.format(record)

实例化记录器

# create logger with 'spam_application'
logger = logging.getLogger("My_app")
logger.setLevel(logging.DEBUG)

# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

ch.setFormatter(CustomFormatter())

logger.addHandler(ch)

并使用!

logger.debug("debug message")
logger.info("info message")
logger.warning("warning message")
logger.error("error message")
logger.critical("critical message")

结果



13> lain..:

有很多回应.但没有人在谈论装饰者.所以这是我的.

因为它更简单.

不需要导入任何东西,也不需要编写任何子类:

#!/usr/bin/env python
# -*- coding: utf-8 -*-


import logging


NO_COLOR = "\33[m"
RED, GREEN, ORANGE, BLUE, PURPLE, LBLUE, GREY = \
    map("\33[%dm".__mod__, range(31, 38))

logging.basicConfig(format="%(message)s", level=logging.DEBUG)
logger = logging.getLogger(__name__)

# the decorator to apply on the logger methods info, warn, ...
def add_color(logger_method, color):
  def wrapper(message, *args, **kwargs):
    return logger_method(
      # the coloring is applied here.
      color+message+NO_COLOR,
      *args, **kwargs
    )
  return wrapper

for level, color in zip((
  "info", "warn", "error", "debug"), (
  GREEN, ORANGE, RED, BLUE
)):
  setattr(logger, level, add_color(getattr(logger, level), color))

# this is displayed in red.
logger.error("Launching %s." % __file__)

这将错误设置为红色,将调试消息设置为蓝色,等等.就像问题中的问题一样.

我们甚至可以调整包装器来使用color动态设置消息颜色的参数logger.debug("message", color=GREY)

编辑:所以这里是适应装饰器在运行时设置颜色:

def add_color(logger_method, _color):
  def wrapper(message, *args, **kwargs):
    color = kwargs.pop("color", _color)
    if isinstance(color, int):
      color = "\33[%dm" % color
    return logger_method(
      # the coloring is applied here.
      color+message+NO_COLOR,
      *args, **kwargs
    )
  return wrapper

# blah blah, apply the decorator...

# this is displayed in red.
logger.error("Launching %s." % __file__)
# this is displayed in blue
logger.error("Launching %s." % __file__, color=34)
# and this, in grey
logger.error("Launching %s." % __file__, color=GREY)



14> gravitation..:

airmind方法的另一个小混音,将所有内容保持在一个类中:

class ColorFormatter(logging.Formatter):
  FORMAT = ("[$BOLD%(name)-20s$RESET][%(levelname)-18s]  "
            "%(message)s "
            "($BOLD%(filename)s$RESET:%(lineno)d)")

  BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)

  RESET_SEQ = "\033[0m"
  COLOR_SEQ = "\033[1;%dm"
  BOLD_SEQ = "\033[1m"

  COLORS = {
    'WARNING': YELLOW,
    'INFO': WHITE,
    'DEBUG': BLUE,
    'CRITICAL': YELLOW,
    'ERROR': RED
  }

  def formatter_msg(self, msg, use_color = True):
    if use_color:
      msg = msg.replace("$RESET", self.RESET_SEQ).replace("$BOLD", self.BOLD_SEQ)
    else:
      msg = msg.replace("$RESET", "").replace("$BOLD", "")
    return msg

  def __init__(self, use_color=True):
    msg = self.formatter_msg(self.FORMAT, use_color)
    logging.Formatter.__init__(self, msg)
    self.use_color = use_color

  def format(self, record):
    levelname = record.levelname
    if self.use_color and levelname in self.COLORS:
      fore_color = 30 + self.COLORS[levelname]
      levelname_color = self.COLOR_SEQ % fore_color + levelname + self.RESET_SEQ
      record.levelname = levelname_color
    return logging.Formatter.format(self, record)

要使用将格式化程序附加到处理程序,例如:

handler.setFormatter(ColorFormatter())
logger.addHandler(handler)



15> 小智..:
import logging
import sys

colors = {'pink': '\033[95m', 'blue': '\033[94m', 'green': '\033[92m', 'yellow': '\033[93m', 'red': '\033[91m',
      'ENDC': '\033[0m', 'bold': '\033[1m', 'underline': '\033[4m'}

logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)


def str_color(color, data):
    return colors[color] + str(data) + colors['ENDC']

params = {'param1': id1, 'param2': id2}

logging.info('\nParams:' + str_color("blue", str(params)))`



16> Jonathan Har..:

用于着色任何终端文本的简单但非常灵活的工具是" colout ".

pip install colout
myprocess | colout REGEX_WITH_GROUPS color1,color2...

'myprocess'输出中与正则表达式组1匹配的任何文本将使用color1,第2组使用color2等进行着色.

例如:

tail -f /var/log/mylogfile | colout '^(\w+ \d+ [\d:]+)|(\w+\.py:\d+ .+\(\)): (.+)$' white,black,cyan bold,bold,normal

即第一个正则表达式组(parens)匹配日志文件中的初始日期,第二个组匹配python文件名,行号和函数名称,第三个组匹配之后的日志消息.我还使用'粗体/法线'的并行序列以及颜色序列.这看起来像:

带有彩色格式的日志文件

请注意,与我的任何正则表达式不匹配的行或部分行仍然会回显,因此这不像'grep --color' - 没有任何内容从输出中过滤掉.

显然这很灵活,你可以在任何进程中使用它,而不仅仅是拖尾日志文件.我通常只要想要为某些东西着色,就可以动态地制作一个新的正则表达式.出于这个原因,我更喜欢colout到任何自定义日志文件着色工具,因为我只需要学习一个工具,无论我着色的是什么:日志,测试输出,语法突出显示终端中的代码片段等.

它还避免在日志文件本身中实际转储ANSI代码,这是一个坏主意,因为它会破坏日志文件中的模式,除非你总是记得匹配grep正则表达式中的ANSI代码.

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有