Python log文件定义- 自用

由于自己在工作中需要是用到log文件,一直都是随用随写,没次都不一样,导致自己都觉得烦心。所以这次自己写了一个log文件,以供以后可以循环使用。在此做个备份


最近更新 2021年1月29日10:02:23

  • 由于在实际操作中与测试中有误差,在此更新记录下
  • 在单元测试中的logger 输出为
  • 而在实际运用中logger输出为logging默认的
  • 这也就导致了,所有的比warning等级低的都无法记录
  • 具体修改方式:在__init__中实例化self.logger下方将logger.level修改为logging.NOTSET

  • 文件目录
    • Logger.py: 具体的日志文件
    • test.py: 测试及调用方法

Logger.py

#!/usr/bin/python3
# coding: utf-8
# @Time: 2021/1/26 15:47
# @Project: None...
# @File: logger.py
# @Author: Lpliner
# @Description: 日志文件

import os
import logging
import logging.handlers
from logging import Logger

from typing_extensions import Literal       # >=3.8 USE: from typing import Literal


class BaseLogger(object):

    def __init__(self, LogPath: str, logName: str = "log",  when: str = "D", backup: int = 7) -> None:
        """
        初始化logger
        Args:
            LogPath: log文件存储位置及名称,建议是指定存储的文件夹,文件夹可以不存在,会新建
            when: 更新时间
            backup:
        """
        super().__init__()
        self.formatter = logging.Formatter(
            fmt=" - ".join([
                # "%(name)s",                       # UserName
                # "%(relativeCreated)d",            # RelativeCreatedTime
                "%(asctime)s",
                # "%(filename)s",                   # File
                "%(pathname)s",                     # FileAbspath
                "%(funcName)s",                     # Function
                "[%(levelname)s]",                  # LogLevel
                # "[%(levelno)d]",                  # LogLevelNo.
                "Line:%(lineno)d",                  # LineNo.
                "Module:%(module)s",                # Module
                ":".join(["%(processName)s",        # ProcessName
                          "%(process)d"]),          # ProcessID
                ":".join(["%(threadName)s",         # ThreadName
                          "%(thread)d"]),           # ThreadID
                "Msg: %(message)s"
            ]),
            datefmt="%Y-%m-%d %H:%M:%S")

        # 检查日志存储路径的有效性
        if not os.path.exists(LogPath):
            try:
                os.mkdir(LogPath)
            except Exception:
                raise ValueError(
                    "The `LogPath` entered is wrong! please check the correctness for it。")

        self.when = when
        self.backup = backup

        self.logger_dict = dict(
            debug=dict(filename=os.path.join(LogPath, logName + "_debug.log"), level=logging.DEBUG),
            info=dict(filename=os.path.join(LogPath, logName + "_info.log"), level=logging.INFO),
            warning=dict(filename=os.path.join(LogPath, logName + "_warning.log"), level=logging.WARNING),
            error=dict(filename=os.path.join(LogPath, logName + "_error.log"), level=logging.ERROR))
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.NOTSET)		# 清空logging默认的level(logging.WARNING)

    def __add_logger(self, logger: Logger, loggerType: Literal["debug", "info", "warning", "error"]) -> Logger:
        """

        Returns: initialization logger

        """

        # handler
        handler = logging.handlers.TimedRotatingFileHandler(
            filename=self.logger_dict[loggerType]["filename"],
            when=self.when,
            backupCount=self.backup
        )
        handler.setLevel(level=self.logger_dict[loggerType]["level"])
        handler.setFormatter(fmt=self.formatter)

        # add filter
        log_filter = logging.Filter()
        log_filter.filter = lambda record: record.levelno == self.logger_dict[loggerType]["level"]
        handler.addFilter(log_filter)

        logger.addHandler(hdlr=handler)

        return logger

    @property
    def initLoggerDebug(self) -> Logger:
        """
        Add debug logger
        Returns: None

        """
        logger = self.__add_logger(logger=self.logger, loggerType="debug")
        return logger

    @property
    def initLoggerInfo(self) -> Logger:
        """
        Add info logger
        Returns: None

        """
        logger = self.__add_logger(logger=self.logger, loggerType="info")
        return logger

    @property
    def initLoggerWarning(self) -> Logger:
        """
        Add warning logger
        Returns: None

        """
        logger = self.__add_logger(logger=self.logger, loggerType="warning")
        return logger

    @property
    def initLoggerError(self) -> Logger:
        """
        Add error logger
        Returns: None

        """
        logger = self.__add_logger(logger=self.logger, loggerType="error")
        return logger

    def initLoggerInConsole(self, loggerType: Literal["debug", "info", "warning", "error"]) -> None:
        """
        指定日志级别类型,输出到console中
        Args:
            loggerType: 需要输出到console中的日志级别

        Returns: None

        """
        console = logging.StreamHandler()
        console.setLevel(self.logger_dict[loggerType]["level"])
        console.setFormatter(fmt=self.formatter)
        self.logger.addHandler(hdlr=console)

    @property
    def initLoggerAll(self) -> Logger:
        """
        创建所有日志级别类型,所有日志级别都需存储
        Returns:

        """
        self.logger = self.initLoggerDebug
        self.logger = self.initLoggerInfo
        self.logger = self.initLoggerWarning
        self.logger = self.initLoggerError
        logger = self.logger
        return logger


调用测试

test.py

import unittest

from .Logger import BaseLogger


class MyTestCase(unittest.TestCase):

    def test_something(self):
        logger = BaseLogger(LogPath="./testlog").initLoggerAll
        logger.debug("debug")
        logger.info("info")
        logger.warning("warning")
        logger.error("error")


if __name__ == '__main__':
    unittest.main()

你可能感兴趣的:(学习,python,logging)