Python学习:日志

系统 1578 0

日志

如果你曾经在代码中加入 print() 语句,在程序运行时输出某些变量的值,你就使用了记日志的方式来调试代码。记日志是一种很好的方式,可以理解程序中发生的事,以及事情发生的顺序。 Python 的 logging 模块使得你很容易创建自定义的消息记录。这些日志消息将描述程序执行何时到达日志函数调用,并列出你指定的任何变量当时的值。另一方面,缺失日志信息表明有一部分代码被跳过,从未执行。

使用日志模块

要启用 logging 模块 ,在程序运行时将日志信息显示在屏幕上,请将下面的代码复制到程序顶部(但在 Python 的#!行之下):

            
              
                import
              
               logging
logging
              
                .
              
              basicConfig
              
                (
              
              
	level
              
                =
              
              logging
              
                .
              
              DEBUG
              
                ,
              
              
                format
              
              
                =
              
              
                ' %(asctime)s - %(levelname)s- %(message)s'
              
              
                # 日志打印格式
              
              
                )
              
            
          

基本上,当 Python 记录一个事件的日志时,它会创建一个 LogRecord 对象,保存关于该事件的信息。 logging 模块的函数让你指定想看到的这个 LogRecord 对象的细节,以及希望的细节展示方式。
假如你编写了一个函数,计算一个数的阶乘。在数学上, 4 的阶乘是1 × 2 × 3 × 4,即 24。 7 的阶乘是 1 × 2 × 3 × 4 × 5 × 6 × 7,即 5040。打开一个新的文件编辑器窗口,输入以下代码。其中有一个缺陷,但你也会输入一些日志信息,帮助你弄清楚哪里出了问题。

            
              
                import
              
               logging
logging
              
                .
              
              basicConfig
              
                (
              
              level
              
                =
              
              logging
              
                .
              
              DEBUG
              
                ,
              
              
                format
              
              
                =
              
              
                ' %(asctime)s - %(levelname)s- %(message)s'
              
              
                )
              
              
logging
              
                .
              
              debug
              
                (
              
              
                'Start of program'
              
              
                )
              
              
                def
              
              
                factorial
              
              
                (
              
              n
              
                )
              
              
                :
              
              
    logging
              
                .
              
              debug
              
                (
              
              
                'Start of factorial(%s%%)'
              
              
                %
              
              
                (
              
              n
              
                )
              
              
                )
              
              
    total 
              
                =
              
              
                1
              
              
                for
              
               i 
              
                in
              
              
                range
              
              
                (
              
              n 
              
                +
              
              
                1
              
              
                )
              
              
                :
              
              
        total 
              
                *=
              
               i
        logging
              
                .
              
              debug
              
                (
              
              
                'i is '
              
              
                +
              
              
                str
              
              
                (
              
              i
              
                )
              
              
                +
              
              
                ', total is '
              
              
                +
              
              
                str
              
              
                (
              
              total
              
                )
              
              
                )
              
              
    logging
              
                .
              
              debug
              
                (
              
              
                'End of factorial(%s%%)'
              
              
                %
              
              
                (
              
              n
              
                )
              
              
                )
              
              
                return
              
               total


              
                print
              
              
                (
              
              factorial
              
                (
              
              
                5
              
              
                )
              
              
                )
              
              
logging
              
                .
              
              debug
              
                (
              
              
                'End of program'
              
              
                )
              
            
          
            
              输出:
0
 2019-06-17 14:17:35,350 - DEBUG- Start of program
 2019-06-17 14:17:35,350 - DEBUG- Start of factorial(5%)
 2019-06-17 14:17:35,350 - DEBUG- i is 0, total is 0
 2019-06-17 14:17:35,350 - DEBUG- i is 1, total is 0
 2019-06-17 14:17:35,350 - DEBUG- i is 2, total is 0
 2019-06-17 14:17:35,350 - DEBUG- i is 3, total is 0
 2019-06-17 14:17:35,350 - DEBUG- i is 4, total is 0
 2019-06-17 14:17:35,350 - DEBUG- i is 5, total is 0
 2019-06-17 14:17:35,350 - DEBUG- End of factorial(5%)
 2019-06-17 14:17:35,350 - DEBUG- End of program

            
          

打印日志信息时,使用 logging.debug() 函数。这个 debug() 函数将调用 basicConfig(),打印一行信息。这行信息的格式是我们在 basicConfig()函数中指定的,并且包括我们传递给 debug() 的消息。

factorial() 函数返回 0 作为 5 的阶乘,这是不对的。 for 循环应该用从 1 到 5的数,乘以 total 的值。但 logging.debug() 显示的日志信息表明, i 变量从 0 开始,而不是 1。因为 0 乘任何数都是 0,所以接下来的迭代中, total 的值都是错的。日志消息提供了可以追踪的痕迹,帮助你弄清楚何时事情开始不对。将代码行 for i in range(n + 1) :改为 for i in range(1, n + 1): ,再次运行程序。
输出看起来像这样:

            
              	输出:
	120
	 2019-06-17 14:22:30,612 - DEBUG- Start of program
	 2019-06-17 14:22:30,612 - DEBUG- Start of factorial(5%)
	 2019-06-17 14:22:30,612 - DEBUG- i is 1, total is 1
	 2019-06-17 14:22:30,612 - DEBUG- i is 2, total is 2
	 2019-06-17 14:22:30,612 - DEBUG- i is 3, total is 6
	 2019-06-17 14:22:30,612 - DEBUG- i is 4, total is 24
	 2019-06-17 14:22:30,612 - DEBUG- i is 5, total is 120
	 2019-06-17 14:22:30,612 - DEBUG- End of factorial(5%)
	 2019-06-17 14:22:30,612 - DEBUG- End of program

            
          

日志级别

“日志级别”提供了一种方式,按重要性对日志消息进行分类。 5 个日志级别如表所示,从最不重要到最重要。利用不同的日志函数,消息可以按某个级别记入日志。
在这里插入图片描述
Python学习:日志_第1张图片
日志的级别

            
              
                import
              
               logging  
logging
              
                .
              
              debug
              
                (
              
              
                'debug message'
              
              
                )
              
                
logging
              
                .
              
              info
              
                (
              
              
                'info message'
              
              
                )
              
                
logging
              
                .
              
              warning
              
                (
              
              
                'warning message'
              
              
                )
              
                
logging
              
                .
              
              error
              
                (
              
              
                'error message'
              
              
                )
              
                
logging
              
                .
              
              critical
              
                (
              
              
                'critical message'
              
              
                )
              
            
          

灵活配置日志级别,日志格式,输出位置

除了将日志消息显示在屏幕上,还可以将它们写入文本文件。 logging.basicConfig() 函数 接受 filename 关键字参数,

            
              
                import
              
               logging
logging
              
                .
              
              basicConfig
              
                (
              
              
	filename
              
                =
              
              
                'myProgramLog.txt'
              
              
                ,
              
               
	level
              
                =
              
              logging
              
                .
              
              DEBUG
              
                ,
              
              
                format
              
              
                =
              
              
                '%(asctime)s - %(levelname)s - %(message)s'
              
              
                )
              
            
          

日志信息将被保存到 myProgramLog.txt 文件中。虽然日志消息很有用,但它们可能塞满屏幕,让你很难读到程序的输出。将日志信息写入到文件,让屏幕保持干净,又能保存信息,这样在运行程序后,可以阅读这些信息。可以用任何文件编辑器打开这个文本文件,诸如 Notepad 或 TextEdit。
日志文本默认的是 追加方式进行写入的 ,可以更改写入的方式 filemode=‘w

            
              logging
              
                .
              
              basicConfig
              
                (
              
              
	filename
              
                =
              
              
                'myProgramLog.txt'
              
              
                ,
              
              
	level
              
                =
              
              logging
              
                .
              
              DEBUG
              
                ,
              
              
                format
              
              
                =
              
              
                '%(asctime)s - %(levelname)s - %(message)s'
              
              
                ,
              
              
    filemode
              
                =
              
              
                'w'
              
              
                )
              
            
          

logging.basicConfig()函数 中可通过具体参数来更改logging模块默认行为,可用参数有

  • filename :用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
  • filemode :文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
  • format :指定handler使用的日志显示格式。
  • datefmt :指定日期时间格式。
  • level :设置rootlogger的日志级别
  • stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,‘w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
            
              
                import
              
               logging  
logging
              
                .
              
              basicConfig
              
                (
              
              level
              
                =
              
              logging
              
                .
              
              DEBUG
              
                ,
              
              
                format
              
              
                =
              
              
                '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s'
              
              
                ,
              
                
                    datefmt
              
                =
              
              
                '%a, %d %b %Y %H:%M:%S'
              
              
                ,
              
                
                    filename
              
                =
              
              
                'test.log'
              
              
                ,
              
                
                    filemode
              
                =
              
              
                'w'
              
              
                )
              
                
  
logging
              
                .
              
              debug
              
                (
              
              
                'debug message'
              
              
                )
              
                
logging
              
                .
              
              info
              
                (
              
              
                'info message'
              
              
                )
              
                
logging
              
                .
              
              warning
              
                (
              
              
                'warning message'
              
              
                )
              
                
logging
              
                .
              
              error
              
                (
              
              
                'error message'
              
              
                )
              
                
logging
              
                .
              
              critical
              
                (
              
              
                'critical message'
              
              
                )
              
            
          

输出:test.log
Python学习:日志_第2张图片
format参数中可能用到的格式化串:

  • %(name)s Logger的名字
  • %(levelno)s 数字形式的日志级别
  • %(levelname)s 文本形式的日志级别
  • %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
  • %(filename)s 调用日志输出函数的模块的文件名
  • %(module)s 调用日志输出函数的模块名
  • %(funcName)s 调用日志输出函数的函数名
  • %(lineno)d 调用日志输出函数的语句所在的代码行
  • %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
  • %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
  • %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
  • %(thread)d 线程ID。可能没有
  • %(threadName)s 线程名。可能没有
  • %(process)d 进程ID。可能没有
  • %(message)s用户输出的消息

logger对象

上述几个例子中我们了解到了logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical()(分别用以记录不同级别的日志信息),logging.basicConfig()(用默认日志格式(Formatter)为日志系统建立一个默认的流处理器(StreamHandler),设置基础配置(如日志级别等)并加到root logger(根Logger)中)这几个logging模块级别的函数,另外还有一个模块级别的函数是logging.getLogger([name])(返回一个logger对象,如果没有指定名字将返回root logger)

一个最简单的过程:

            
              
                import
              
               logging

logger 
              
                =
              
               logging
              
                .
              
              getLogger
              
                (
              
              
                )
              
              
                # 创建一个handler,用于写入日志文件
              
              
fh 
              
                =
              
               logging
              
                .
              
              FileHandler
              
                (
              
              
                'test11.log'
              
              
                ,
              
              mode
              
                =
              
              
                'w'
              
              
                )
              
              
                # 再创建一个handler,用于输出到控制台
              
              
ch 
              
                =
              
               logging
              
                .
              
              StreamHandler
              
                (
              
              
                )
              
              

formatter 
              
                =
              
               logging
              
                .
              
              Formatter
              
                (
              
              
                '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
              
              
                )
              
              

fh
              
                .
              
              setFormatter
              
                (
              
              formatter
              
                )
              
              
ch
              
                .
              
              setFormatter
              
                (
              
              formatter
              
                )
              
              

logger
              
                .
              
              addHandler
              
                (
              
              fh
              
                )
              
              
                #logger对象可以添加多个fh和ch对象
              
              
logger
              
                .
              
              addHandler
              
                (
              
              ch
              
                )
              
              
logger
              
                .
              
              setLevel
              
                (
              
              logging
              
                .
              
              DEBUG
              
                )
              
              
                #设置日志的级别。对于低于该级别的日志消息将被忽略.
              
              



logger
              
                .
              
              debug
              
                (
              
              
                'logger debug message'
              
              
                )
              
              
logger
              
                .
              
              info
              
                (
              
              
                'logger info message'
              
              
                )
              
              
logger
              
                .
              
              warning
              
                (
              
              
                'logger warning message'
              
              
                )
              
              
logger
              
                .
              
              error
              
                (
              
              
                'logger error message'
              
              
                )
              
              
logger
              
                .
              
              critical
              
                (
              
              
                'logger critical message'
              
              
                )
              
            
          
  • FileHandler(StreamHandler):
    A handler class which writes formatted logging records to disk files.
    def init (self, filename, mode=‘a’, encoding=None, delay=False):

  • logging库提供了多个组件: Logge r、 Handler Filter Formatter 。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。

  • Logger是一个树形层级结构,输出信息之前都要获得一个Logger(如果没有显示的获取则自动创建并使用root Logger,)。 logger = logging.getLogger()返回一个默认的Logger也即root Logger,并应用默认的日志级别、Handler和Formatter设置。
    当然也可以通过 Logger.setLevel(lel) 指定最低的日志级别,可用的日志级别有 logging.DEBUG、``logging.INFO logging.WARNING logging.ERROR logging.CRITICAL

  • Logger.debug() Logger.info() Logger.warning() Logger.error() Logger.critical() 输出不同级别的日志,只有日志等级大于或等于设置的日志级别的日志才会被输出

可以将上述logging进行函数化

            
              
                import
              
               logging

              
                def
              
              
                logger
              
              
                (
              
              
                )
              
              
                :
              
              
    logger 
              
                =
              
               logging
              
                .
              
              getLogger
              
                (
              
              
                )
              
              
                # 创建一个handler,用于写入日志文件
              
              
    fh 
              
                =
              
               logging
              
                .
              
              FileHandler
              
                (
              
              
                'test10.log'
              
              
                ,
              
              mode
              
                =
              
              
                'w'
              
              
                )
              
              
                # 再创建一个handler,用于输出到控制台
              
              
    ch 
              
                =
              
               logging
              
                .
              
              StreamHandler
              
                (
              
              
                )
              
              

    formatter 
              
                =
              
               logging
              
                .
              
              Formatter
              
                (
              
              
                '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
              
              
                )
              
              

    fh
              
                .
              
              setFormatter
              
                (
              
              formatter
              
                )
              
              
    ch
              
                .
              
              setFormatter
              
                (
              
              formatter
              
                )
              
              

    logger
              
                .
              
              addHandler
              
                (
              
              fh
              
                )
              
              
                #logger对象可以添加多个fh和ch对象
              
              
    logger
              
                .
              
              addHandler
              
                (
              
              ch
              
                )
              
              
    logger
              
                .
              
              setLevel
              
                (
              
              logging
              
                .
              
              DEBUG
              
                )
              
              
                #设置日志的级别。对于低于该级别的日志消息将被忽略.
              
              
                return
              
                logger


logger
              
                =
              
              logger
              
                (
              
              
                )
              
              

logger
              
                .
              
              debug
              
                (
              
              
                'logger debug message'
              
              
                )
              
              
logger
              
                .
              
              info
              
                (
              
              
                'logger info message'
              
              
                )
              
              
logger
              
                .
              
              warning
              
                (
              
              
                'logger warning message'
              
              
                )
              
              
logger
              
                .
              
              error
              
                (
              
              
                'logger error message'
              
              
                )
              
              
logger
              
                .
              
              critical
              
                (
              
              
                'logger critical message'
              
              
                )
              
            
          

更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论