在 Python 中使用日志记录模块进行颜色记录

Posted

技术标签:

【中文标题】在 Python 中使用日志记录模块进行颜色记录【英文标题】:Color logging using logging module in Python 【发布时间】:2014-01-09 11:25:32 【问题描述】:

让我们简化一下。我的目标是使用 Python 中的 logging 模块在终端中进行颜色输出。我希望信息有一个绿色前缀,警告有一个黄色前缀,错误有一个红色前缀。为了简单起见,让我们使用*** 作为前缀,即

*** log text
*** another message with another prefix color

到目前为止我做了什么

# declaration of function (global scope)
log = None
warn = None
error = None 
def build_log_funcs():
    # why I initialize it inside the function ?
    # because script doesnt have to know about logging method
    # the function just provide log  functions
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)

    sh = logging.StreamHandler()
    # LOG_FORMAT just global variable with pattern including %(levelmarks)s
    # it will be replaced with ** with proper color 
    formatter = logging.Formatter(LOG_FORMAT)
    sh.setFormatter(formatter)
    logger.addHandler(sh)

    def make_log_func(func, color, is_exit = False):
        color_string = "\x1b[;1m***\x1b[0m".format(color)
        def newfunc(*args, **kwargs):
            func(*args, extra='levelmarks':color_string, **kwargs)
            if is_exit:
                sys.exit(-1)

        return newfunc
    # 32, 33, 31 are color codes
    log = make_log_func(logger.info, 32)
    warn = make_log_func(logger.warning, 33)
    error = make_log_func(logger.error, 31, is_exit = True)

    return log, warn, error

并将其用作

log, warn, error = build_log_funcs()

它有效,但我不喜欢:(从小到大的问题)

    我隐藏了logging 模块的功能。例如启用/禁用调试消息 我应该在函数初始化之前使用函数的全局声明,因为我不能在函数声明之前调用函数。 阅读和维护代码太难了。我相信一切都应该尽可能简单。

我为什么不做简单的日志,警告,简单的功能?我不知道。 logging 是一个非常全面的模块,所以我将来可能需要它的功能。

我的问题是你将如何解决这个问题?可能有一个我不知道的简单明显的方法。

【问题讨论】:

使用装饰器会更好。看到这个出色的答案here 你见过this吗? 【参考方案1】:

感谢 Dominic Kexel 提供this 链接。我看到了这个,但没有注意答案。 下面的代码或多或少适合我

def setup_logger(logger):
    logger.setLevel(logging.DEBUG)

    sh = logging.StreamHandler()
    formatter = logging.Formatter(LOG_FORMAT)
    sh.setFormatter(formatter)

    def decorate_emit(fn):
    # add methods we need to the class
        def new(*args):
            levelno = args[0].levelno
            if(levelno >= logging.CRITICAL):
                color = '\x1b[31;1m'
            elif(levelno >= logging.ERROR):
                color = '\x1b[31;1m'
            elif(levelno >= logging.WARNING):
                color = '\x1b[33;1m'
            elif(levelno >= logging.INFO):
                color = '\x1b[32;1m'
            elif(levelno >= logging.DEBUG):
                color = '\x1b[35;1m'
            else:
                color = '\x1b[0m'
            # add colored *** in the beginning of the message
            args[0].msg = "0***\x1b[0m 1".format(color, args[0].msg)

            # new feature i like: bolder each args of message 
            args[0].args = tuple('\x1b[1m' + arg + '\x1b[0m' for arg in args[0].args)
            return fn(*args)
        return new
    sh.emit = decorate_emit(sh.emit)
    logger.addHandler(sh)

这有一个缺陷:我无法控制***在模式中的位置,但正如我所说的那样合适。

【讨论】:

以上是关于在 Python 中使用日志记录模块进行颜色记录的主要内容,如果未能解决你的问题,请参考以下文章

Python logging模块使用配置文件记录日志

Python 日志记录配置文件模块和包

在多个模块中使用日志记录

在 python 项目中如何记录日志

python的logging模块

在Python日志记录模块中禁止换行