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

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

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

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

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

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


当前回答

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

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

and

https://github.com/laysakura/rainbow_logging_handler

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

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

其他回答

我从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

这是airmind示例的另一个Python3变体。我想要一些在其他例子中没有看到的特性

为终端使用颜色,但不要在文件处理程序中写入不可打印的字符(我为此定义了2个格式化器) 能够覆盖特定日志消息的颜色 从一个文件(在本例中是yaml)配置记录器

注意:我使用了colorama,但是你可以修改它,这样就不需要了。对于我的测试,我只是运行python文件,所以我的类在模块__main__中。你必须更改():__main__。ColoredFormatter到你的模块。

pip install colorama pyyaml

logging.yaml

---
version: 1
disable_existing_loggers: False
formatters:
  simple:
    format: "%(threadName)s - %(name)s - %(levelname)s - %(message)s"
  color:
    format: "%(threadName)s - %(name)s - %(levelname)s - %(message)s"
    (): __main__.ColoredFormatter
    use_color: true

handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: color
    stream: ext://sys.stdout

  info_file_handler:
    class: logging.handlers.RotatingFileHandler
    level: INFO
    formatter: simple
    filename: app.log
    maxBytes: 20971520 
    backupCount: 20
    encoding: utf8

  error_file_handler:
    class: logging.handlers.RotatingFileHandler
    level: ERROR
    formatter: simple
    filename: errors.log
    maxBytes: 10485760 
    backupCount: 20
    encoding: utf8

root:
  level: DEBUG
  handlers: [console, info_file_handler, error_file_handler]

main.py

import logging
import logging.config
import os
from logging import Logger

import colorama
import yaml
from colorama import Back, Fore, Style

COLORS = {
    "WARNING": Fore.YELLOW,
    "INFO": Fore.CYAN,
    "DEBUG": Fore.BLUE,
    "CRITICAL": Fore.YELLOW,
    "ERROR": Fore.RED,
}


class ColoredFormatter(logging.Formatter):
    def __init__(self, *, format, use_color):
        logging.Formatter.__init__(self, fmt=format)
        self.use_color = use_color

    def format(self, record):
        msg = super().format(record)
        if self.use_color:
            levelname = record.levelname
            if hasattr(record, "color"):
                return f"{record.color}{msg}{Style.RESET_ALL}"
            if levelname in COLORS:
                return f"{COLORS[levelname]}{msg}{Style.RESET_ALL}"
        return msg


with open("logging.yaml", "rt") as f:
    config = yaml.safe_load(f.read())
    logging.config.dictConfig(config)

logger: Logger = logging.getLogger(__name__)
logger.info("Test INFO", extra={"color": Back.RED})
logger.info("Test INFO", extra={"color": f"{Style.BRIGHT}{Back.RED}"})
logger.info("Test INFO")
logger.debug("Test DEBUG")
logger.warning("Test WARN")

输出:

coloredlogs

Instalation

pip install coloredlogs

使用

最小的用法:

import logging
import coloredlogs

coloredlogs.install()  # install a handler on the root logger

logging.debug('message with level debug')
logging.info('message with level info')
logging.warning('message with level warning')
logging.error('message with level error')
logging.critical('message with level critical')

结果:

从消息级调试开始:

import logging
import coloredlogs

coloredlogs.install(level='DEBUG')  # install a handler on the root logger with level debug

logging.debug('message with level debug')
logging.info('message with level info')
logging.warning('message with level warning')
logging.error('message with level error')
logging.critical('message with level critical')

结果:

从库中隐藏消息:

import logging
import coloredlogs

logger = logging.getLogger(__name__)  # get a specific logger object
coloredlogs.install(level='DEBUG')  # install a handler on the root logger with level debug
coloredlogs.install(level='DEBUG', logger=logger)  # pass a specific logger object

logging.debug('message with level debug')
logging.info('message with level info')
logging.warning('message with level warning')
logging.error('message with level error')
logging.critical('message with level critical')

结果:

格式化日志消息:

import logging
import coloredlogs

logger = logging.getLogger(__name__)  # get a specific logger object
coloredlogs.install(level='DEBUG')  # install a handler on the root logger with level debug
coloredlogs.install(level='DEBUG', logger=logger)  # pass a specific logger object
coloredlogs.install(
    level='DEBUG', logger=logger,
    fmt='%(asctime)s.%(msecs)03d %(filename)s:%(lineno)d %(levelname)s %(message)s'
)

logging.debug('message with level debug')
logging.info('message with level info')
logging.warning('message with level warning')
logging.error('message with level error')
logging.critical('message with level critical')

结果:

可用的格式属性:

%(asctime)s - Time as human-readable string, when logging call was issued %(created)f - Time as float when logging call was issued %(filename)s - File name %(funcName)s - Name of function containing the logging call %(hostname)s - System hostname %(levelname)s - Text logging level %(levelno)s - Integer logging level %(lineno)d - Line number where the logging call was issued %(message)s - Message passed to logging call (same as %(msg)s) %(module)s - File name without extension where the logging call was issued %(msecs)d - Millisecond part of the time when logging call was issued %(msg)s - Message passed to logging call (same as %(message)s) %(name)s - Logger name %(pathname)s - Full pathname to file containing the logging call %(process)d - Process ID %(processName)s - Process name %(programname)s - System programname %(relativeCreated)d - Time as integer in milliseconds when logging call was issued, relative to the time when logging module was loaded %(thread)d - Thread ID %(threadName)s - Thread name %(username)s - System username

来源:

Coloredlogs包

日志库

只要你不想去发明轮子。

只需pip安装loguru,然后:

from loguru import logger

if __name__ == '__main__':
    message = "Message text"

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

输出:

您可以更改格式,颜色,写入文件从盒子…这里是文档

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

注意:当使用Git Bash与MinTTY

Git Bash在windows上有一些记录的怪癖: Winpty和Git Bash

对于ANSI转义代码和ncurses风格的字符重写和动画,你需要用winpty作为命令的前缀。

$ winpty coloredlogs --demo
$ winpty python your_colored_logs_script.py