Python日志输出不同颜色字体并打印到日志文件

不管是客户端还是服务端,总是有大量的log在打印,想找到关键的几条真是不容易。调查了一下在Python里打印带颜色log的办法,这里应该是最简单的了,不需要任何外部库,并且Windows和Linux都支持。

使用方法

进入Python命令行,程序入口处执行个os.system(''),以后在想打印的字符两边插入几个特殊字符就可以了

这里,\033是八进制的27,也就是ASCII里的Escape。[31m指的是后面的东西变成红色,[0m指的是后面的东西恢复默认。 [32m指的是后面的东西变成绿色,[0m指的是后面的东西恢复默认。

需要注意的是,程序开始执行的时候,必须执行一下os.system(''),也就是执行一个空的cmd命令。如果不执行,会无法识别颜色指令。

基本颜色

\033[31m 看作\033[3xm,里面的x的取值范围是0到7,分别对应了

上图来在维基百科,直接搜“ansi escape code”就可以找到。

https://en.wikipedia.org/wiki/ANSI_escape_code​en.wikipedia.org

 

封装一下,就可以随意打印带颜色的log了!

原理

这些就是ANSI escape code,上面的百科网页里有详细说明。为啥是“escape”?就是这里的八进制\033,也就是十进制27,也就是十六进制0x1B,也就是ASCII里的Esc。 还有一个搜索关键字是 VT100 Emulation。

就是说,Console不只可以输出原始字符,还可以更改字符的格式,甚至操作光标之类。

其他使用方法

可以在cmd里直接echo出带颜色的字符串么?当然可以,但是,要学会输入Escape字符才行。本人试验必须是cmd,Powershell不行。

怎么输入escape呢?看上去有两种。第一种,按住Alt的时候按27,然后松开Alt;第二种,按Ctrl+[。

虽然显示的是个^[,但是,直接输入一个^一个[是不行的。

文本文件里可以么?虽然不能用编辑器直接查看,但是如果打印到命令行里,也是可以的。

打开Notepad++,输入

这个ESC怎么输入呢?找一个现成的复制,或者,按住Alt,按27,松开Alt,就会出来一个ESC了!ASCII里的其他控制字符也可以这样输入。

然后可以在命令行里打印

如果直接写在一个batch文件里,也可以这样echo带颜色的字符。

其他格式

仔细研究维基上的文章,还有不少其他的格式,刚才说的[3xm是前景色,还有[4xm是背景色,[9xm是明亮前景色 ,[10xm是明亮背景色。

这里有个脚本,打印了这4种模式 * 8种颜色的所有32种组合。

class Color:
    Black = 0
    Red = 1
    Green = 2
    Yellow = 3
    Blue = 4
    Magenta = 5
    Cyan = 6
    White = 7

class Mode:
    Foreground = 30
    Background = 40
    ForegroundBright = 90
    BackgroundBright = 100

def tcolor(c, m=Mode.Foreground):
    return '\033[{}m'.format(m + c)

def treset():
    return '\033[0m'

if __name__ == '__main__':
    import os
    os.system('')

    # usage
    print(tcolor(Color.Red) + 'hello' + treset())
    print(tcolor(Color.Green, Mode.Background) + 'color' + treset())
    print()

    COLOR_NAMES = ['Black', 'Red', 'Green', 'Yellow', 'Blue', 'Magenta', 'Cyan', 'White']
    MODE_NAMES = ['Foreground', 'Background', 'ForegroundBright', 'BackgroundBright']

    fmt = '{:11}' * len(COLOR_NAMES)
    print(' ' * 20 + fmt.format(*COLOR_NAMES))

    for mode_name in MODE_NAMES:
        print('{:20}'.format(mode_name), end='')
        for color_name in COLOR_NAMES:
            mode = getattr(Mode, mode_name)
            color = getattr(Color, color_name)
            print(tcolor(color, mode) + 'HelloColor' + treset(), end=' ')
        print()
 

在VSCode console里的输出

在Powershell里的输出

在cmd里的输出

在raspbian里的输出

正如维基里说的,不同的console,每种颜色对应的实际RGB值可能有出入。

实际上,还有高亮,划掉,下划线等等各种格式。可以仔细研究维基,或者看这里的一个脚本

win10colors.cmd

https://stackoverflow.com/questions/2048509/how-to-echo-with-different-colors-in-the-windows-command-line​stackoverflow.com

 

下面是这个win10colors.cmd前几行的输出,有粗体和下划线。

不同的console可能不会完全支持所有功能。

为什么需要os.system('')

如果不要这一句,Windows下颜色指令会不生效。其实,是利用了这句话的副作用,副作用就是执行cmd的时候,会打开VT100模拟。其实更“正确”的做法,是使用Windows提供的SetConsoleMode。

How to use the new support for ANSI escape sequences in the Windows 10 console?​stackoverflow.com图标

Linux不需要这个os.system('')

有兴趣的话可以找找IPython之类的库是怎么开启这个VT100模拟的。

其他

可以把print覆盖掉,或者封装几个print_infoprint_warningprint_error 之类的函数。

或者每个人使用自己的print函数,例如wyh_print,这样可以在本地自由开关所有人的 log,并且给自己加颜色,而不影响其他人。

如果可以和logging结合,配置不同级别,不同模块的log的颜色就太好了。

主要参考

 

https://stackoverflow.com/questions/287871/how-to-print-colored-text-in-terminal-in-python​stackoverflow.com

 

https://stackoverflow.com/questions/2048509/how-to-echo-with-different-colors-in-the-windows-command-line​stackoverflow.com

 

https://en.wikipedia.org/wiki/ANSI_escape_code​en.wikipedia.org

 

https://docs.microsoft.com/en-us/windows/console/setconsolemode?redirectedfrom=MSDN#ENABLE_VIRTUAL_TERMINAL_PROCESSING​docs.microsoft.com

 

Bonus

上面说的一堆,在IDLE是不生效的,但是IDLE里确实可以输出各种颜色。忘了在哪里抄的了,但是下面的代码可以在IDLE里打印颜色字符

import sys

try:
    shell = sys.stdout.shell
except AttributeError:
    raise RuntimeError("you must run this program in IDLE")

shell.write("Wanna go explore? ","KEYWORD")
shell.write("OPTIONS","STRING")
shell.write(" : ","KEYWORD")
shell.write("Yes","DEFINITION")
shell.write(" or ","KEYWORD")
shell.write("No","COMMENT")

print()
print("here are all the valid tags:\n")

valid_tags = ('SYNC', 'stdin', 'BUILTIN', 'STRING', 'console', 'COMMENT', 'stdout',
              'TODO','stderr', 'hit', 'DEFINITION', 'KEYWORD', 'ERROR', 'sel')

for tag in valid_tags:
    shell.write(tag+"\n",tag)
    

IDLE里的输出

 

发布于 2020-04-25

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以通过给 `logging` 模块的输出添加颜色来更好地区分不同级别的日志。具体方法是创建一个自定义的 `Formatter` 类,并在其中添加 ANSI 转义序列来修改文本颜色。 以下是一个示例代码: ```python import logging class ColoredFormatter(logging.Formatter): """ 自定义日志格式,添加颜色 """ def format(self, record): if record.levelno == logging.DEBUG: # 绿色字体 color_start = '\033[32m' elif record.levelno == logging.INFO: # 默认字体颜色 color_start = '' elif record.levelno == logging.WARNING: # 黄色字体 color_start = '\033[33m' elif record.levelno == logging.ERROR: # 红色字体 color_start = '\033[31m' elif record.levelno == logging.CRITICAL: # 紫色字体 color_start = '\033[35m' else: color_start = '' color_end = '\033[0m' self._style._fmt = color_start + self._style._fmt + color_end return super().format(record) # 创建 logger logger = logging.getLogger('my_logger') logger.setLevel(logging.DEBUG) # 创建 StreamHandler,并添加到 logger 中 handler = logging.StreamHandler() handler.setLevel(logging.DEBUG) # 创建 Formatter,并添加到 handler 中 formatter = ColoredFormatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) # 添加 handler 到 logger 中 logger.addHandler(handler) # 输出不同级别的日志 logger.debug('This is a debug message') logger.info('This is an info message') logger.warning('This is a warning message') logger.error('This is an error message') logger.critical('This is a critical message') ``` 在这个例子中,我们创建了一个自定义的 `Formatter` 类 `ColoredFormatter`,并在其中根据不同日志级别添加了不同颜色。然后将这个 `Formatter` 添加到 `StreamHandler` 中,并将其添加到 logger 中,从而实现了对输出日志颜色控制。 注意,为了保证每个日志输出颜色都是正确的,我们每次都需要在 `format` 方法中重新设置 `_style._fmt`。如果不这么做,可能会出现某些日志输出颜色不正确的情况。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值