Python Logging模塊 輸出日志顏色、過期清理和日志滾動備份


# coding:utf-8
import logging
from logging.handlers import RotatingFileHandler # 按文件大小滾動備份
import colorlog  # 控制台日志輸入顏色
import time
import datetime
import os

cur_path = os.path.dirname(os.path.realpath(__file__))  # log_path是存放日志的路徑
log_path = os.path.join(os.path.dirname(cur_path), 'logs')
if not os.path.exists(log_path): os.mkdir(log_path)  # 如果不存在這個logs文件夾,就自動創建一個
logName = os.path.join(log_path, '%s.log' % time.strftime('%Y-%m-%d'))  # 文件的命名

log_colors_config = {
    'DEBUG': 'cyan',
    'INFO': 'green',
    'WARNING': 'yellow',
    'ERROR': 'red',
    'CRITICAL': 'red',
}


class Log:
    def __init__(self, logName=logName):
        self.logName = logName
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)
        self.formatter = colorlog.ColoredFormatter(
            '%(log_color)s[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s]- %(message)s',
            log_colors=log_colors_config)  # 日志輸出格式
        self.handle_logs()

    def get_file_sorted(self, file_path):
        """最后修改時間順序升序排列 os.path.getmtime()->獲取文件最后修改時間"""
        dir_list = os.listdir(file_path)
        if not dir_list:
            return
        else:
            dir_list = sorted(dir_list, key=lambda x: os.path.getmtime(os.path.join(file_path, x)))
            return dir_list

    def TimeStampToTime(self, timestamp):
        """格式化時間"""
        timeStruct = time.localtime(timestamp)
        return str(time.strftime('%Y-%m-%d', timeStruct))

    def handle_logs(self):
        """處理日志過期天數和文件數量"""
        dir_list = ['report']  # 要刪除文件的目錄名
        for dir in dir_list:
            dirPath = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + '\\' + dir  # 拼接刪除目錄完整路徑
            file_list = self.get_file_sorted(dirPath)  # 返回按修改時間排序的文件list
            if file_list:  # 目錄下沒有日志文件
                for i in file_list:
                    file_path = os.path.join(dirPath, i)  # 拼接文件的完整路徑
                    t_list = self.TimeStampToTime(os.path.getctime(file_path)).split('-')
                    now_list = self.TimeStampToTime(time.time()).split('-')
                    t = datetime.datetime(int(t_list[0]), int(t_list[1]),
                                          int(t_list[2]))  # 將時間轉換成datetime.datetime 類型
                    now = datetime.datetime(int(now_list[0]), int(now_list[1]), int(now_list[2]))
                    if (now - t).days > 6:  # 創建時間大於6天的文件刪除
                        self.delete_logs(file_path)
                if len(file_list) > 4:  # 限制目錄下記錄文件數量
                    file_list = file_list[0:-4]
                    for i in file_list:
                        file_path = os.path.join(dirPath, i)
                        print(file_path)
                        self.delete_logs(file_path)

    def delete_logs(self, file_path):
        try:
            os.remove(file_path)
        except PermissionError as e:
            Log().warning('刪除日志文件失敗:{}'.format(e))

    def __console(self, level, message):
        # 創建一個FileHandler,用於寫到本地
        fh = RotatingFileHandler(filename=self.logName, mode='a', maxBytes=1024 * 1024 * 5, backupCount=5,
                                 encoding='utf-8')  # 使用RotatingFileHandler類,滾動備份日志
        fh.setLevel(logging.DEBUG)
        fh.setFormatter(self.formatter)
        self.logger.addHandler(fh)

        # 創建一個StreamHandler,用於輸出到控制台
        ch = colorlog.StreamHandler()
        ch.setLevel(logging.DEBUG)
        ch.setFormatter(self.formatter)
        self.logger.addHandler(ch)

        if level == 'info':
            self.logger.info(message)
        elif level == 'debug':
            self.logger.debug(message)
        elif level == 'warning':
            self.logger.warning(message)
        elif level == 'error':
            self.logger.error(message)
        # 這兩行代碼是為了避免日志輸出重復問題
        self.logger.removeHandler(ch)
        self.logger.removeHandler(fh)
        fh.close()  # 關閉打開的文件

    def debug(self, message):
        self.__console('debug', message)

    def info(self, message):
        self.__console('info', message)

    def warning(self, message):
        self.__console('warning', message)

    def error(self, message):
        self.__console('error', message)


if __name__ == "__main__":
    log = Log()
    log.debug("---測試開始----")
    log.info("操作步驟")
    log.warning("----測試結束----")
    log.error("----測試錯誤----")
參考:logging- Python的記錄工具

萬能日志輸出,可直接使用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM