Python 培训(通用)日志模块

最简单的用法

  • 首先,logging 将信息分成了 6 个级别,分别是 NOTSET、DEBUG、INFO、WARNING、ERROR、CRITICAL,显然,越往后说明问题越严重。

  • logging 模块有 5 个方法,分别为 debug、info、warning、error、critical,分别对应上面五个等级信息,(确实没有 notset 这个函数),logging 默认忽略 INFO 和其以下级别的信息,也就是说只有 WARNING 以上的级别才会在控制台像 print 一样输出。

  • 显然,有一个函数要设置 logging 显示信息的级别以及输出形式等,这个函数就是 basicConfig,下面是其主要用到的参数:

    • level:要显示的级别(包括 level 后面跟的那个级别)

    • filename:存储文件路径

    • filemode:打开文件方式,默认为 a

    • format:日志显示格式,抄一个好看的就行了,懒得看怎么定义的

    • datefmt:日期显示格式,同抄

  • 上次我们写代码的时候,就已经用到这些知识了,但是发现,指定 filename、filemode 以后,就会将符合条件的信息记录在文件中,而不会在控制台输出了。相关代码如下所示,非常简单:

import logging

LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
DATE_FORMAT = "%m/%d/%Y %H:%M:%S %p"
logging.basicConfig(filename='scrapLog.txt', level=logging.DEBUG, format=LOG_FORMAT, datefmt=DATE_FORMAT)

logging.debug('debug')
logging.info('info')

小小的扩展

  • 上面已经说了,这样以后只将信息保存在文件中,而不会输出了,我们希望既有输出又有记录。在网上随意找了一下,有如下代码:
import logging
import logging.handlers

logger = logging.getLogger("logger")

handler1 = logging.StreamHandler()
handler2 = logging.FileHandler(filename="test.log")

logger.setLevel(logging.DEBUG)
handler1.setLevel(logging.WARNING)
handler2.setLevel(logging.INFO)

formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
handler1.setFormatter(formatter)
handler2.setFormatter(formatter)

logger.addHandler(handler1)
logger.addHandler(handler2)

logger.debug('This is a customer debug message')
logger.info('This is an customer info message')
logger.warning('This is a customer warning message')
logger.error('This is an customer error message')
logger.critical('This is a customer critical message')
  • 这段代码很好懂,handle1 就是控制台输出,handle2 就是文件输出,分别设置了 level,就实现了控制台和文件的分级输出,嗯,有这个就够了。
  • 顺便说一句,这里面的 logging.getLogger("logger"),那个字符串,是在文件里面的一个名字,可以随便设置。

封装代码

  • 在项目中,要写上面的代码显然很烦人,我们写一个脚本,之后学习一下 python 定义模块的方法,然后把它放到路径里面去,现在就只先写一下脚本。
  • 上次我们发现 matplotlib 里有很多 debug 的信息,我们就退一步,将信息全部设置为 info 及以上的信息,结合本人习惯,喜欢在控制台看程序的进度,而 log 文件只是后面把程序打包以后才用的,所以默认的级别把文件设高一点。
import logging
import logging.handlers


class MyLog:
    def __init__(self, filename='myLog.log', streamLevel=logging.INFO, fileLevel=logging.WARNING):
        self.logger = logging.getLogger('TTJQ')
        handlerStream = logging.StreamHandler()
        handlerFile = logging.FileHandler(filename=filename)

        self.logger.setLevel(logging.DEBUG)
        handlerStream.setLevel(streamLevel)
        handlerFile.setLevel(fileLevel)

        formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
        handlerFile.setFormatter(formatter)
        handlerStream.setFormatter(formatter)

        self.logger.addHandler(handlerStream)
        self.logger.addHandler(handlerFile)

    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.critical(msg)


本文章使用limfx的vsocde插件快速发布