python 使用轉義序列,打印不同顏色的日誌級別記錄

在pycharm的終端控制檯,打印出來的日誌記錄都是紅色的,看着很不順眼,因此希望能夠自定義日誌顏色。
實現過程:
由於控制檯是一個終端,終端的字符顏色是用轉義序列控制的,是文本模式下的系統顯示功能,和具體的語言無關。
轉義序列是以ESC開頭,即用\033來完成(ESC的ASCII碼用十進制表示是27,用八進制表示就是033)。

一、結合轉義序列打印不同顏色的日誌記錄

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

import logging
import time


class Logger(object):
    def __init__(self, custom_color=True):
        """
        構造日誌器和處理器,以及設定常用的方法
        :param custom_color: 是否自定義顏色開關
        """

        self.custom_color = custom_color  # 自定義顏色

        try:
            # 創建一個logger(初始化logger)
            self.logger = logging.getLogger(__name__)
            self.logger.setLevel(logging.DEBUG)

            # 判斷是否已存在handler,有則初始化handlers爲[]
            if self.logger.handlers:
                self.logger.handlers = []

            # 定義日誌文件的路徑以及名稱
            log_name = 'log.log'

            # 創建日誌文件和控制檯的handler
            self.fh = logging.FileHandler(log_name, encoding='utf-8')
            self.ch = logging.StreamHandler()

            # 定義輸出格式
            formatter = logging.Formatter('[%(asctime)s] - [%(name)s] - [%(levelname)s] - %(message)s')
            self.fh.setFormatter(formatter)
            self.ch.setFormatter(formatter)

            # 定義處理器的日誌級別
            self.fh.setLevel(logging.INFO)
            self.ch.setLevel(logging.DEBUG)

            # 給logger添加handler
            self.logger.addHandler(self.fh)
            self.logger.addHandler(self.ch)

        except Exception as e:
            print("輸出日誌失敗! %s" % e)

    def record_color(self, color):
        """
        給日誌記錄加上顏色
        :param color: 顏色參數
        :return:
        """
        # 控制檯不同的日誌等級輸出不同的顏色
        formatter = logging.Formatter(color % '[%(asctime)s] - [%(levelname)s] - %(message)s')
        # 定義handler的輸出格式
        self.ch.setFormatter(formatter)

    # 日誌接口,用戶只需調用這裏的接口即可
    # 設置顏色格式:\033[顯示方式;字體顏色;背景顏色m\033[0m
    def debug(self, msg):
        if self.custom_color is True:
            self.record_color("\033[0;{};0m%s\033[0m".format(0))  # 0:白色;數字對應不同的顏色
        self.logger.debug(msg)

    def info(self, msg):
        if self.custom_color is True:
            self.record_color("\033[0;{};0m%s\033[0m".format(96))  # 96:強藍色;數字對應不同的顏色
        self.logger.info(msg)

    def warning(self, msg):
        if self.custom_color is True:
            self.record_color("\033[0;{};0m%s\033[0m".format(93))  # 93:金色;數字對應不同的顏色
        self.logger.warning(msg)

    def error(self, msg):
        if self.custom_color is True:
            self.record_color("\033[0;{};0m%s\033[0m".format(31))  # 31:紅色;數字對應不同的顏色
        self.logger.error(msg)
        
    def critical(self, msg):
        if self.custom_color is True:
            self.record_color("\033[0;{};0m%s\033[0m".format(93))  # 93:金色;數字對應不同的顏色
        self.logger.critical(msg)

    def del_handler(self):
        #  在記錄日誌之後移除handler
        self.logger.removeHandler(self.ch)
        self.logger.removeHandler(self.fh)


if __name__ == '__main__':
    logger = Logger()
    logger.debug("====================【測試用例開始】====================")
    logger.info("====================【測試用例開始】====================")
    logger.warning("====================【測試用例開始】====================")
    logger.error("====================【測試用例開始】====================")
    logger.critical("====================【測試用例開始】====================")

輸出結果:
在這裏插入圖片描述

二、顏色表

logger_color: 運行腳本,查看對應數字的顏色

# 顏色調試用腳本
"""
終端的字符顏色是用轉義序列控制的,是文本模式下的系統顯示功能,和具體的語言無關。
轉義序列是以ESC開頭,即用\033來完成(ESC的ASCII碼用十進制表示是27,用八進制表示就是033)。
書寫格式:
開頭部分:\033[顯示方式;前景色;背景色m + 結尾部分:\033[0m
注意:開頭部分的三個參數:顯示方式,前景色,背景色是可選參數,可以只寫其中的某一個;另外由於表示三個參數不同含義的數值都是唯一的沒有重複的,所以三個參數的書寫先後順序沒有固定要求,系統都能識別;但是,建議按照默認的格式規範書寫。
對於結尾部分,其實也可以省略,但是爲了書寫規範,建議\033[***開頭,\033[0m結尾。
數值表示的參數含義:
#格式:
  設置顏色開始 :\033[顯示方式;前景色;背景色m
#說明:
前景色            背景色           顏色
---------------------------------------
30                40              黑色
31                41              紅色
32                42              綠色
33                43              黃色
34                44              藍色
35                45              紫紅色
36                46              青藍色
37                47              白色
顯示方式           意義
-------------------------
0                終端默認設置
1                高亮顯示
4                使用下劃線
5                閃爍
7                反白顯示
8                不可見
#例子:
\033[1;31;40m    <!--1-高亮顯示 31-前景色紅色  40-背景色黑色-->
\033[0m          <!--採用終端默認設置,即取消顏色設置-->
"""

# 設置控制檯字體顏色
# 代碼格式:\033[顏色;顯示方式m code \033[0m

class Colors():
    # 顏色枚舉
    white = "white"  # default
    red = "red"
    green = "green"
    brown = "brown"  # 棕色
    Pink = "Pink"
    Violet = "Viole"  #紫色
    blue = "blue"
    black = "black"

class FontColor():
    """不同的版本可能顏色不一樣
    調用方式:顏色/背景色/+下劃線標誌 + 需要加顏色的文字 + 結束標誌
    """
    # 顏色碼
    white = "\033[30;"  # default
    red = "\033[31;"
    green = "\033[32;"
    brown = "\033[33;"
    Pink = "\033[34;"
    Violet = "\033[35;"  # 紫色
    blue = "\033[36;"
    black = "\033[37;"

    # 背景色
    white_background = "\033[40;"  # default
    red_background = "\033[41;"
    green_background = "\033[42;"
    brown_background = "\033[43;"
    Pink_background = "\033[44;"
    Violet_background = "\033[45;"  # 紫色
    blue_background = "\033[46;"
    black_background = "\033[47;"

    # 下劃線標誌
    default = "0m"  # default
    underline = "4m"

    # 結束標誌位
    end = "\033[0m"

    # 設置字體色方法
    @classmethod
    def set_color(self, text, color="white", underline=False):
        if hasattr(self, color):
            if underline:
                return getattr(self, color) + self.underline + text + self.end
            else:
                return getattr(self, color) + self.default + text + self.end
        else:
            return text

    # 設置背景色
    @classmethod
    def set_backcolor(self, text, backcolor="white", underline=False):
        color = backcolor + "_background"
        if hasattr(self, color):
            if underline:
                return getattr(self, color) + self.underline + text + self.end
            else:
                return getattr(self, color) + self.default + text + self.end
        else:
            return text


if __name__ == "__main__":
    # 顏色測試
    for i in range(0, 120):
        print("{} \033[{};0mhello\033[0m".format(i, str(i)))

    # 1.原始調用方式:
    print("\033[31;1mhello\033[0m")  # 紅色

    print("\033[31;4mhello\033[0m")  # 紅色加下劃線

    print("\033[41;1mhello\033[0m")  # 紅色背景

    print("\033[41;4mhello\033[0m")  # 紅色背景加下劃線

    # 2.通過FontColor類變量設置
    # 綠色
    print(FontColor.green + FontColor.default + "hello" + FontColor.end)

    # 綠色加下劃線
    print(FontColor.green + FontColor.underline + "hello" + FontColor.end)

    # 綠色背景
    print(FontColor.green_background + FontColor.default + "hello" + FontColor.end)

    # 綠色背景加下劃線
    print(FontColor.green_background + FontColor.underline + "hello" + FontColor.end)

    # 3.通過FontColor類方法設置
    print(FontColor.set_color("你好", "red"))  # 紅色

    print(FontColor.set_color("你好", Colors.green))  # 綠色

    #  綠色加下劃線
    print(FontColor.set_color("你好", Colors.green, underline=True))

    print(FontColor.set_backcolor("你好", Colors.blue))  # 藍色背景

    #  藍色背景加下劃線
    print(FontColor.set_backcolor("你好", Colors.blue, underline=True))

輸出結果:
在這裏插入圖片描述

三、常見問題

你可能會遇到一種問題,輸出HTML報告的時候,日誌記錄前後有轉義符的序列信息,但是在終端不會出現。
在這裏插入圖片描述這是因爲轉義符只能在終端體現出來顏色,但是在非終端上的程序,由於不能轉換,所以顯示出來序列信息

關於這個問題,如果你不想在報告上有這些序列信息,只能在輸出報告的時候,不執行操作轉義顏色。

注意:網上有一些庫,也可以實現打印不同顏色的效果,但是輸出報告的時候,也會顯示序列信息,所以我猜測本質上也是用的終端序轉義序列

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章