python对日志处理的封装
Posted 北风之神0509
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python对日志处理的封装相关的知识,希望对你有一定的参考价值。
一个适应性范围较广的日志处理
# coding=utf8 """ @author bfzs """ import os import logging from logging.handlers import TimedRotatingFileHandler, RotatingFileHandler from cloghandler import ConcurrentRotatingFileHandler format_dict = { 1: logging.Formatter(‘%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(message)s‘, "%Y-%m-%d %H:%M:%S"), 2: logging.Formatter(‘%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(message)s‘, "%Y-%m-%d %H:%M:%S"), 3: logging.Formatter(‘%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(message)s‘, "%Y-%m-%d %H:%M:%S"), 4: logging.Formatter(‘%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(message)s‘, "%Y-%m-%d %H:%M:%S"), 5: logging.Formatter(‘%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(message)s‘, "%Y-%m-%d %H:%M:%S"), } class LogLevelException(Exception): def __init__(self, log_level): err = ‘设置的日志级别是 {0}, 设置错误,请设置为1 2 3 4 5 范围的数字‘.format(log_level) Exception.__init__(self, err) class Log(object): """ 一个日志类,用于创建和捕获日志,支持将日志打印到控制台打印和写入日志文件。 """ def __init__(self, logger_name=None, log_level_int=1, is_add_stream_handler=True, log_path=None, log_filename=None): """ :param logger_name: 日志名称,当为None时候打印所有日志 :param log_level_int: 日志级别,设置为 1 2 3 4 5,分别对应DEBUG,INFO,WARNING,ERROR,CRITICAL :param is_add_stream_handler: 是否打印日志到控制台 :param log_path: 设置存放日志的文件夹路径 :param log_filename: 日志的名字,仅当log_path和log_filename都不为None时候才写入到日志文件。 :type logger_name :str :type log_level_int :int :type is_add_stream_handler :bool :type log_path :str :type log_filename :str """ self.logger = logging.getLogger(logger_name) self.__check_log_level(log_level_int) self._logger_level = self.__transform_logger_level(log_level_int) self._is_add_stream_handler = is_add_stream_handler self._log_path = log_path self._log_filename = log_filename self._formatter = format_dict[log_level_int] self.__set_logger_level() self.__add_handlers() def debug(self, msg): self.logger.debug(msg) def info(self, msg): self.logger.info(msg) def warning(self, msg): self.logger.warning(msg) def error(self, msg): self.logger.error(msg) def critical(self, msg): self.logger.critical(msg) def __set_logger_level(self): self.logger.setLevel(self._logger_level) @staticmethod def __check_log_level(log_level_int): if log_level_int not in [1, 2, 3, 4, 5]: raise LogLevelException(log_level_int) @staticmethod def __transform_logger_level(log_level_int): logger_level = None if log_level_int == 1: logger_level = logging.DEBUG elif log_level_int == 2: logger_level = logging.INFO elif log_level_int == 3: logger_level = logging.WARNING elif log_level_int == 4: logger_level = logging.ERROR elif log_level_int == 5: logger_level = logging.CRITICAL return logger_level def __add_handlers(self): if self._is_add_stream_handler: self.__add_stream_handler() if all([self._log_path, self._log_filename]): self.__add_file_handler() def __add_stream_handler(self): """ 日志显示到控制台 """ stream_handler = logging.StreamHandler() stream_handler.setLevel(self._logger_level) stream_handler.setFormatter(self._formatter) self.logger.addHandler(stream_handler) def __add_file_handler(self): """ 日志写入日志文件 """ if not os.path.exists(self._log_path): os.makedirs(self._log_path) log_file = os.path.join(self._log_path, self._log_filename) os_name = os.name print os_name rotate_file_handler = None if os_name == ‘nt‘: # windows下用这个,非进程安全 rotate_file_handler = RotatingFileHandler(log_file, mode="a", maxBytes=10 * 1024 * 1024, backupCount=10, encoding="utf-8") if os_name == ‘posix‘: # linux下可以使用ConcurrentRotatingFileHandler,进程安全的日志方式 rotate_file_handler = ConcurrentRotatingFileHandler(log_file, mode="a", maxBytes=10 * 1024 * 1024, backupCount=10, encoding="utf-8") rotate_file_handler.setLevel(logging.DEBUG) rotate_file_handler.setFormatter(self._formatter) self.logger.addHandler(rotate_file_handler) def test_func(): """测试日志打印,单独运行test_func函数是不会打印出这条日志,没有添加handler""" logger = logging.getLogger(‘test‘) logger.info(u‘需要被打印的日志‘) if __name__ == "__main__": test_log = Log(‘test‘, 1, log_path=‘./logs‘, log_filename=‘test.log‘) test_func() test_log.info(u‘添加一条日志‘) import requests request_log = Log(‘urllib3.connectionpool‘, 1) # 测试三方包的日志 resp = requests.get(‘https://www.baidu.com‘)
场景:将不同的日志写入到不同的文件,分析业务问题,查看三方包的日志。
有的三方包的日志是必须捕获,例如concurrent包的日志,线程池运行错误都是通过日志的方式报错,如果不对日志进行打印捕获,很多语法错误或者流程错误都看不到,可能会以为写的东西没毛病呢。
以上是关于python对日志处理的封装的主要内容,如果未能解决你的问题,请参考以下文章