python logger日誌通用配置文件

閱讀須知⚠️

1.示例代碼可直接放在項目py文件中便可使用
2.project_name,logfile_name變量需根據你的項目進行修改
3.日誌輸出格式format選擇(可根據你的須要替換或修改示例代碼中的format)less

%(levelno)s: 打印日誌級別的數值
 %(levelname)s: 打印日誌級別名稱
 %(pathname)s: 打印當前執行程序的路徑,其實就是sys.argv[0]
 %(filename)s: 打印當前執行程序名
 %(funcName)s: 打印日誌的當前函數
 %(lineno)d: 打印日誌的當前行號
 %(asctime)s: 打印日誌的時間
 %(thread)d: 打印線程ID
 %(threadName)s: 打印線程名稱
 %(process)d: 打印進程ID
 %(message)s: 打印日誌信息

示例代碼

import os
import re
import logging.config
# 定義三種日誌輸出格式
# 其中name爲make_logger的參數name
standard_format = '[%(levelname)s][%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s]' \
                  '\n[%(filename)s:%(lineno)d][%(message)s]'

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'

# 項目名
project_name = 'dev'
# 日誌文件名
logfile_name = 'logs'

# 日誌配置
LOGGING_DIC = {
    'version': 1,
    # 禁用已經存在的logger實例
    'disable_existing_loggers': False,
    # 日誌格式化(負責配置log message 的最終順序,結構,及內容)
    'formatters': {
        'distinct': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
        'less_simple': {
            'format': id_simple_format
        },
    },
    # 過濾器,決定哪一個log記錄被輸出
    'filters': {},
    # 負責將Log message 分派到指定的destination
    'handlers': {
        # 打印到終端的日誌
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'distinct'
        },
        # 打印到common文件的日誌,收集info及以上的日誌
        'common': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
            'formatter': 'simple',
            'filename': './%s/access.log' % logfile_name,       # 日誌文件路徑
            'maxBytes': 1024*1024*5,  # 日誌大小 5M
            'backupCount': 5, # 備份5個日誌文件
            'encoding': 'utf-8',  # 日誌文件的編碼,不再用擔憂中文log亂碼了
        },
        # 打印到importance文件的日誌,收集error及以上的日誌
        'importance': {
                    'level': 'ERROR',
                    'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                    'formatter': 'distinct',
                    'filename': './%s/importance.log' % logfile_name,  # 日誌文件
                    # 'maxBytes': 1024*1024*5,  # 日誌大小 5M
                    'maxBytes': 300,  # 日誌大小 5M
                    'backupCount': 5, # 備份5個日誌文件
                    'encoding': 'utf-8',  # 日誌文件的編碼,不再用擔憂中文log亂碼了
                },
    },
    # logger實例
    'loggers': {
        # 默認的logger應用以下配置
        '': {
            'handlers': ['console'],  # log數據打印到控制檯
            'level': 'DEBUG',
            'propagate': True,  # 向上(更高level的logger)傳遞
        },
        'default': {
            'handlers': ['console', 'common', 'importance'],  
            'level': 'INFO',
            'propagate': True,  # 向上(更高level的logger)傳遞
        },
        'common': {
            'handlers': ['console', 'common'],  # 這裏把上面定義的兩個handler都加上,即log數據既寫入文件又打印到控制檯
            'level': 'INFO',
            'propagate': True,  # 向上(更高level的logger)傳遞
        },
        'importance': {
            'handlers': ['console', 'importance'],  # 這裏把上面定義的兩個handler都加上,即log數據既寫入文件又打印到控制檯
            'level': 'ERROR'
        },
        
    },
}


class Log(object):
    @staticmethod
    def isdir_logs():
        """
        判斷日誌文件是否存在,不存在則建立
        :return:
        """
        # 當前文件的目錄

        basedir = os.path.dirname(os.path.abspath(__file__))
        pattern = '(.*/%s)' % project_name
        project_dir = re.search(pattern, basedir).group()
        # logs文件的路徑
        log_path = os.path.join(project_dir, logfile_name)
        # 判斷日誌文件夾是否在項目文件中
        if not os.path.isdir(log_path):
            os.mkdir(log_path)

    @staticmethod
    def make_logger(name=None):
        """
        1. 若是不傳name,則根據__name__去loggers裏查找__name__對應的logger配置(__name__爲調用文件名)
        獲取logger對象經過方法logging.getLogger(__name__),不一樣的文件__name__不一樣,這保證了打印日誌時標識信息不一樣,
        2. 若是傳name,則根據name獲取loggers對象
        3. 若是拿着name或者__name__去loggers裏找key名時卻發現找不到,因而默認使用key=''的配置
        :return: logger
        """
        logging.config.dictConfig(LOGGING_DIC)  # 導入上面定義的logging配置
        if name:
            logger = logging.getLogger(name)
        else:
            logger = logging.getLogger(__name__)
        return logger


if __name__ == '__main__':
    Log().isdir_logs()
    importance_logger = Log.make_logger('default')
    importance_logger.error('787878')
相關文章
相關標籤/搜索