Python logging 模块详解

Python Logging 模块详解 Python logging 日志学习记录 阅读详情
简单将日志打印到屏幕:
[python]  view plain  copy
  1. import logging  
  2. logging.debug('debug message')  
  3. logging.info('info message')  
  4. logging.warning('warning message')  
  5. logging.error('error message')  
  6. logging.critical('critical message')  

输出:

WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message

可见,默认情况下 python 的 logging 模块将日志打印到了标准输出中,且只显示了大于等于 WARNING 级别的日志,这说明默认的日志级别设置为 WARNING(日志级别等级 CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET),默认的日志格式为日志级别:Logger 名称:用户输出消息。


灵活配置日志级别,日志格式,输出位置
[python]  view plain  copy
  1. import logging  
  2. logging.basicConfig(level=logging.DEBUG,  
  3.                     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',  
  4.                     datefmt='%a, %d %b %Y %H:%M:%S',  
  5.                     filename='/tmp/test.log',  
  6.                     filemode='w')  
  7.   
  8. logging.debug('debug message')  
  9. logging.info('info message')  
  10. logging.warning('warning message')  
  11. logging.error('error message')  
  12. logging.critical('critical message')  
查看输出:
cat /tmp/test.log 
Mon, 05 May 2014 16:29:53 test_logging.py[line:9] DEBUG debug message
Mon, 05 May 2014 16:29:53 test_logging.py[line:10] INFO info message
Mon, 05 May 2014 16:29:53 test_logging.py[line:11] WARNING warning message
Mon, 05 May 2014 16:29:53 test_logging.py[line:12] ERROR error message
Mon, 05 May 2014 16:29:53 test_logging.py[line:13] CRITICAL critical message

可见在 logging.basicConfig() 函数中可通过具体参数来更改 logging 模块默认行为,可用参数有
filename:用指定的文件名创建 FiledHandler(后边会具体讲解 handler 的概念),这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了 filename 时使用这个参数,默认值为 “a” 还可指定为 “w”。
format:指定 handler 使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置 rootlogger(后边会讲解具体概念)的日志级别
stream:用指定的 stream 创建 StreamHandler。可以指定输出到 sys.stderr,sys.stdout 或者文件,默认为 sys.stderr。若同时列出了 filename 和 stream 两个参数,则 stream 参数会被忽略。

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 用户输出的消息


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

先看一个具体的例子
[python]  view plain  copy
  1. #coding:utf-8  
  2. import logging  
  3.   
  4. # 创建一个 logger    
  5. logger = logging.getLogger()  
  6.   
  7. logger1 = logging.getLogger('mylogger')  
  8. logger1.setLevel(logging.DEBUG)  
  9.   
  10. logger2 = logging.getLogger('mylogger')  
  11. logger2.setLevel(logging.INFO)  
  12.   
  13. logger3 = logging.getLogger('mylogger.child1')  
  14. logger3.setLevel(logging.WARNING)  
  15.   
  16. logger4 = logging.getLogger('mylogger.child1.child2')  
  17. logger4.setLevel(logging.DEBUG)  
  18.   
  19. logger5 = logging.getLogger('mylogger.child1.child2.child3')  
  20. logger5.setLevel(logging.DEBUG)  
  21.   
  22. # 创建一个 handler,用于写入日志文件    
  23. fh = logging.FileHandler('/tmp/test.log')  
  24.   
  25. # 再创建一个 handler,用于输出到控制台    
  26. ch = logging.StreamHandler()  
  27.   
  28. # 定义 handler 的输出格式 formatter    
  29. formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')  
  30. fh.setFormatter(formatter)  
  31. ch.setFormatter(formatter)  
  32.   
  33. #定义一个 filter  
  34. #filter = logging.Filter('mylogger.child1.child2')  
  35. #fh.addFilter(filter)    
  36.   
  37. # 给 logger 添加 handler    
  38. #logger.addFilter(filter)  
  39. logger.addHandler(fh)  
  40. logger.addHandler(ch)  
  41.   
  42. #logger1.addFilter(filter)  
  43. logger1.addHandler(fh)  
  44. logger1.addHandler(ch)  
  45.   
  46. logger2.addHandler(fh)  
  47. logger2.addHandler(ch)  
  48.   
  49. #logger3.addFilter(filter)  
  50. logger3.addHandler(fh)  
  51. logger3.addHandler(ch)  
  52.   
  53. #logger4.addFilter(filter)  
  54. logger4.addHandler(fh)  
  55. logger4.addHandler(ch)  
  56.   
  57. logger5.addHandler(fh)  
  58. logger5.addHandler(ch)  
  59.   
  60. # 记录一条日志    
  61. logger.debug('logger debug message')  
  62. logger.info('logger info message')  
  63. logger.warning('logger warning message')  
  64. logger.error('logger error message')  
  65. logger.critical('logger critical message')  
  66.   
  67. logger1.debug('logger1 debug message')  
  68. logger1.info('logger1 info message')  
  69. logger1.warning('logger1 warning message')  
  70. logger1.error('logger1 error message')  
  71. logger1.critical('logger1 critical message')  
  72.   
  73. logger2.debug('logger2 debug message')  
  74. logger2.info('logger2 info message')  
  75. logger2.warning('logger2 warning message')  
  76. logger2.error('logger2 error message')  
  77. logger2.critical('logger2 critical message')  
  78.   
  79. logger3.debug('logger3 debug message')  
  80. logger3.info('logger3 info message')  
  81. logger3.warning('logger3 warning message')  
  82. logger3.error('logger3 error message')  
  83. logger3.critical('logger3 critical message')  
  84.   
  85. logger4.debug('logger4 debug message')  
  86. logger4.info('logger4 info message')  
  87. logger4.warning('logger4 warning message')  
  88. logger4.error('logger4 error message')  
  89. logger4.critical('logger4 critical message')  
  90.   
  91. logger5.debug('logger5 debug message')  
  92. logger5.info('logger5 info message')  
  93. logger5.warning('logger5 warning message')  
  94. logger5.error('logger5 error message')  
  95. logger5.critical('logger5 critical message')  
输出:
2014-05-06 12:54:43,222 - root - WARNING - logger warning message
2014-05-06 12:54:43,223 - root - ERROR - logger error message
2014-05-06 12:54:43,224 - root - CRITICAL - logger critical message
2014-05-06 12:54:43,224 - mylogger - INFO - logger1 info message
2014-05-06 12:54:43,224 - mylogger - INFO - logger1 info message
2014-05-06 12:54:43,225 - mylogger - WARNING - logger1 warning message
2014-05-06 12:54:43,225 - mylogger - WARNING - logger1 warning message
2014-05-06 12:54:43,226 - mylogger - ERROR - logger1 error message
2014-05-06 12:54:43,226 - mylogger - ERROR - logger1 error message
2014-05-06 12:54:43,227 - mylogger - CRITICAL - logger1 critical message
2014-05-06 12:54:43,227 - mylogger - CRITICAL - logger1 critical message
2014-05-06 12:54:43,228 - mylogger - INFO - logger2 info message
2014-05-06 12:54:43,228 - mylogger - INFO - logger2 info message
2014-05-06 12:54:43,229 - mylogger - WARNING - logger2 warning message
2014-05-06 12:54:43,229 - mylogger - WARNING - logger2 warning message
2014-05-06 12:54:43,230 - mylogger - ERROR - logger2 error message
2014-05-06 12:54:43,230 - mylogger - ERROR - logger2 error message
2014-05-06 12:54:43,231 - mylogger - CRITICAL - logger2 critical message
2014-05-06 12:54:43,231 - mylogger - CRITICAL - logger2 critical message
2014-05-06 12:54:43,232 - mylogger.child1 - WARNING - logger3 warning message
2014-05-06 12:54:43,232 - mylogger.child1 - WARNING - logger3 warning message
2014-05-06 12:54:43,232 - mylogger.child1 - WARNING - logger3 warning message
2014-05-06 12:54:43,234 - mylogger.child1 - ERROR - logger3 error message
2014-05-06 12:54:43,234 - mylogger.child1 - ERROR - logger3 error message
2014-05-06 12:54:43,234 - mylogger.child1 - ERROR - logger3 error message
2014-05-06 12:54:43,235 - mylogger.child1 - CRITICAL - logger3 critical message
2014-05-06 12:54:43,235 - mylogger.child1 - CRITICAL - logger3 critical message
2014-05-06 12:54:43,235 - mylogger.child1 - CRITICAL - logger3 critical message
2014-05-06 12:54:43,237 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 12:54:43,237 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 12:54:43,237 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 12:54:43,237 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 12:54:43,239 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 12:54:43,239 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 12:54:43,239 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 12:54:43,239 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 12:54:43,240 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 12:54:43,240 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 12:54:43,240 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 12:54:43,240 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 12:54:43,242 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 12:54:43,242 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 12:54:43,242 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 12:54:43,242 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 12:54:43,243 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 12:54:43,243 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 12:54:43,243 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 12:54:43,243 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message

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

Logger
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() 输出不同级别的日志,只有日志等级大于或等于设置的日志级别的日志才会被输出。

我们看到程序中
[python]  view plain  copy
  1. logger.debug('logger debug message')  
  2. logger.info('logger info message')  
  3. logger.warning('logger warning message')  
  4. logger.error('logger error message')  
  5. logger.critical('logger critical message')  
只输出了
2014-05-06 12:54:43,222 - root - WARNING - logger warning message
2014-05-06 12:54:43,223 - root - ERROR - logger error message
2014-05-06 12:54:43,224 - root - CRITICAL - logger critical message
从这个输出可以看出 logger = logging.getLogger() 返回的 Logger 名为 root。这里没有用 logger.setLevel() 显示的为 logger 设置日志级别,所以使用默认的日志级别 WARNIING,故结果只输出了大于等于 WARNIING 级别的信息。

另外,我们明明通过 logger1.setLevel(logging.DEBUG) 将 logger1 的日志级别设置为了 DEBUG,为何显示的时候没有显示出 DEBUG 级别的日志信息,而是从 INFO 级别的日志开始显示呢?原来 logger1 和 logger2 对应的是同一个 Logger 实例,只要 logging.getLogger(name)中名称参数 name 相同则返回的 Logger 实例就是同一个,且仅有一个,也即 name 与 Logger 实例一一对应。在 logger2 实例中通过 logger2.setLevel(logging.INFO) 设置 mylogger 的日志级别为 logging.INFO,所以最后 logger1 的输出遵从了后来设置的日志级别。
[python]  view plain  copy
  1. logger1 = logging.getLogger('mylogger')  
  2. logger1.setLevel(logging.DEBUG)  
  3. logger2 = logging.getLogger('mylogger')  
  4. logger2.setLevel(logging.INFO)  
为什么 logger1、logger2 对应的每个输出分别显示两次,logger3 对应的输出显示 3 次,logger4 对应的输出显示 4 次...... 呢?
这是因为我们通过 logger = logging.getLogger() 显示的创建了 root Logger,而 logger1 = logging.getLogger('mylogger') 创建了 root Logger 的孩子 (root.)mylogger,logger2 同样。
logger3 = logging.getLogger('mylogger.child1') 创建了 (root.)mylogger.child1
logger4 = logging.getLogger('mylogger.child1.child2') 创建了 (root.)mylogger.child1.child2
logger5 = logging.getLogger('mylogger.child1.child2.child3') 创建了 (root.)mylogger.child1.child2.child3
而孩子, 孙子,重孙…… 既会将消息分发给他的 handler 进行处理也会传递给所有的祖先 Logger 处理。

试着注释掉如下一行程序,观察程序输出
[python]  view plain  copy
  1. #logger.addHandler(fh)    
发现标准输出中每条记录对应两行(因为 root Logger 默认使用 StreamHandler)
2014-05-06 15:10:10,980 - mylogger - INFO - logger1 info message
2014-05-06 15:10:10,980 - mylogger - INFO - logger1 info message
2014-05-06 15:10:10,981 - mylogger - WARNING - logger1 warning message
2014-05-06 15:10:10,981 - mylogger - WARNING - logger1 warning message
2014-05-06 15:10:10,982 - mylogger - ERROR - logger1 error message
2014-05-06 15:10:10,982 - mylogger - ERROR - logger1 error message
2014-05-06 15:10:10,984 - mylogger - CRITICAL - logger1 critical message
2014-05-06 15:10:10,984 - mylogger - CRITICAL - logger1 critical message
……
而在文件输出中每条记录对应一行(因为我们注释掉了 logger.addHandler(fh),没有对 root Logger 启用 FileHandler)
2014-05-06 15:10:10,980 - mylogger - INFO - logger1 info message
2014-05-06 15:10:10,981 - mylogger - WARNING - logger1 warning message
2014-05-06 15:10:10,982 - mylogger - ERROR - logger1 error message
2014-05-06 15:10:10,984 - mylogger - CRITICAL - logger1 critical message

孩子, 孙子,重孙…… 可逐层继承来自祖先的日志级别、Handler、Filter 设置,也可以通过 Logger.setLevel(lel)、Logger.addHandler(hdlr)、Logger.removeHandler(hdlr)、Logger.addFilter(filt)、Logger.removeFilter(filt)。设置自己特别的日志级别、Handler、Filter。若不设置则使用继承来的值。

Handler
上述例子的输出在标准输出和指定的日志文件中均可以看到,这是因为我们定义并使用了两种 Handler。
[python]  view plain  copy
  1. fh = logging.FileHandler('/tmp/test.log')   
  2. ch = logging.StreamHandler()  
Handler 对象负责发送相关的信息到指定目的地,有几个常用的 Handler 方法:
Handler.setLevel(lel): 指定日志级别,低于 lel 级别的日志将被忽略
Handler.setFormatter():给这个 handler 选择一个 Formatter
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个 filter 对象

可以通过 addHandler() 方法为 Logger 添加多个 Handler:
[python]  view plain  copy
  1. logger.addHandler(fh)  
  2. logger.addHandler(ch)  


有多中可用的 Handler:

logging.StreamHandler 可以向类似与 sys.stdout 或者 sys.stderr 的任何文件对象 (file object) 输出信息
logging.FileHandler 用于向一个文件输出日志信息
logging.handlers.RotatingFileHandler 类似于上面的 FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建一个新的同名日志文件继续输出
logging.handlers.TimedRotatingFileHandler 和 RotatingFileHandler 类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就自动创建新的日志文件
logging.handlers.SocketHandler 使用 TCP 协议,将日志信息发送到网络。
logging.handlers.DatagramHandler 使用 UDP 协议,将日志信息发送到网络。
logging.handlers.SysLogHandler 日志输出到 syslog
logging.handlers.NTEventLogHandler 远程输出日志到 Windows NT/2000/XP 的事件日志 
logging.handlers.SMTPHandler 远程输出日志到邮件地址
logging.handlers.MemoryHandler 日志输出到内存中的制定 buffer
logging.handlers.HTTPHandler 通过 "GET" 或 "POST" 远程输出到 HTTP 服务器
各个 Handler 的具体用法可查看参考书册:
https://docs.python.org/2/library/logging.handlers.html#module-logging.handlers


Formatter
Formatter 对象设置日志信息最后的规则、结构和内容,默认的时间格式为 %Y-%m-%d %H:%M:%S。
[python]  view plain  copy
  1. #定义 Formatter  
  2. formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')  
  3. #为 Handler 添加 Formatter  
  4. fh.setFormatter(formatter)  
  5. ch.setFormatter(formatter)  
Formatter 参数中可能用到的格式化串参见上文(logging.basicConfig() 函数 format 参数中可能用到的格式化串:)

Filter
限制只有满足过滤规则的日志才会输出。
比如我们定义了 filter = logging.Filter('a.b.c'), 并将这个 Filter 添加到了一个 Handler 上,则使用该 Handler 的 Logger 中只有名字带 a.b.c 前缀的 Logger 才能输出其日志。

取消下列两行程序的注释
[python]  view plain  copy
  1. #filter = logging.Filter('mylogger.child1.child2')  
  2. #fh.addFilter(filter)    
标准输出中输出结果并没有发生变化,但日志文件输出中只显示了如下内容:
2014-05-06 15:27:36,227 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 15:27:36,227 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 15:27:36,227 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 15:27:36,227 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 15:27:36,228 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 15:27:36,228 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 15:27:36,228 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 15:27:36,228 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 15:27:36,230 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 15:27:36,230 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 15:27:36,230 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 15:27:36,230 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 15:27:36,232 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 15:27:36,232 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 15:27:36,232 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 15:27:36,232 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 15:27:36,233 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 15:27:36,233 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 15:27:36,233 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 15:27:36,233 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message

当然也可以直接给 Logger 加 Filter。若为 Handler 加 Filter 则所有使用了该 Handler 的 Logger 都会受到影响。而为 Logger 添加 Filter 只会影响到自身。
注释掉
[python]  view plain  copy
  1. #fh.addFilter(filter)   
并取消如下几行的注释
[python]  view plain  copy
  1. #logger.addFilter(filter)  
  2. #logger1.addFilter(filter)  
  3. #logger3.addFilter(filter)  
  4. #logger4.addFilter(filter)  
输出结果
2014-05-06 15:32:10,746 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 15:32:10,746 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 15:32:10,746 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 15:32:10,746 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 15:32:10,748 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 15:32:10,748 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 15:32:10,748 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 15:32:10,748 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 15:32:10,751 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 15:32:10,751 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 15:32:10,751 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 15:32:10,751 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 15:32:10,753 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 15:32:10,753 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 15:32:10,753 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 15:32:10,753 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 15:32:10,754 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 15:32:10,754 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 15:32:10,754 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 15:32:10,754 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message

发现 root、mylogger、mylogger.child1 的输出全部被过滤掉了。

除了直接在程序中设置 Logger,Handler,Filter,Formatter 外还可以将这些信息写进配置文件中。

例如典型的 logging.conf

[python]  view plain  copy
  1. [loggers]  
  2. keys=root,simpleExample  
  3.   
  4. [handlers]  
  5. keys=consoleHandler  
  6.   
  7. [formatters]  
  8. keys=simpleFormatter  
  9.   
  10. [logger_root]  
  11. level=DEBUG  
  12. handlers=consoleHandler  
  13.   
  14. [logger_simpleExample]  
  15. level=DEBUG  
  16. handlers=consoleHandler  
  17. qualname=simpleExample  
  18. propagate=0  
  19.   
  20. [handler_consoleHandler]  
  21. class=StreamHandler  
  22. level=DEBUG  
  23. formatter=simpleFormatter  
  24. args=(sys.stdout,)  
  25.   
  26. [formatter_simpleFormatter]  
  27. format=%(asctime)s - %(name)s - %(levelname)s - %(message)s  
  28. datefmt=  

程序可以这么写
[python]  view plain  copy
  1. import logging    
  2. import logging.config    
  3.     
  4. logging.config.fileConfig("logging.conf")    # 采用配置文件     
  5.     
  6. # create logger     
  7. logger = logging.getLogger("simpleExample")    
  8.     
  9. # "application" code     
  10. logger.debug("debug message")    
  11. logger.info("info message")    
  12. logger.warn("warn message")    
  13. logger.error("error message")    
  14. logger.critical("critical message")  

多模块使用 logging
logging 模块保证在同一个 python 解释器内,多次调用 logging.getLogger('log_name') 都会返回同一个 logger 实例,即使是在多个模块的情况下。所以典型的多模块场景下使用 logging 的方式是在 main 模块中配置 logging,这个配置会作用于多个的子模块,然后在其他模块中直接通过 getLogger 获取 Logger 对象即可。

main.py:
[python]  view plain  copy
  1. import logging    
  2. import logging.config    
  3.     
  4. logging.config.fileConfig('logging.conf')    
  5. root_logger = logging.getLogger('root')    
  6. root_logger.debug('test root logger...')    
  7.     
  8. logger = logging.getLogger('main')    
  9. logger.info('test main logger')    
  10. logger.info('start import module \'mod\'...')    
  11. import mod    
  12.     
  13. logger.debug('let\'s test mod.testLogger()')    
  14. mod.testLogger()    
  15.     
  16. root_logger.info('finish test...')   

子模块 mod.py:

[python]  view plain  copy
  1. import logging    
  2. import submod    
  3.     
  4. logger = logging.getLogger('main.mod')    
  5. logger.info('logger of mod say something...')    
  6.     
  7. def testLogger():    
  8.     logger.debug('this is mod.testLogger...')    
  9.     submod.tst()   
子子模块 submod.py:
[python]  view plain  copy
  1. import logging    
  2.     
  3. logger = logging.getLogger('main.mod.submod')    
  4. logger.info('logger of submod say something...')    
  5.     
  6. def tst():    
  7.     logger.info('this is submod.tst()...')    
Python标准模块logging 开发Python, 一直以来都是使用自己编写的logging模块. 比较土...... 今天发现python的标准模块的这个功能做的挺好, 记录一下, 以后使用模块来进行logging. 对于这个模块的介绍网上也很多, 我也不用自己写了, 比较好的如下, http://crazier9527.iteye.com/blog/290018    Python的标准logging模块 http://blog.endlesscode.com/2010/06/03/python-logging-module/   P 阅读详情

相关推荐

Python-logging 模块

通常我们会使用一个配置字典来定义日志。导入 logging 模块。定义两种日志输出格式。# 定义两种日志输出格式定义日志文件路径。# 定义日志文件所在目录# 定义日志文件名# 如果定义的日志文件所在目录不存在就创建一个# 日志文件完整路径配置字典。通常会放在配置文件中,比如项目 conf 目录下 settings 文件中。# 配置字典'version': 1, # 配置字典的版本。

2240

python接口自动化测试输出日志到控制台和文件_自动化接口测试日志

战项目、讲解视频,并且后续会持续更新**

2401_84254196的博客 917

Python常用模块 之 logging:日志模块

Python常用模块 之 logging:日志模块

孤寒者的博客 17万+

三十五、Python--日志logging模块

1.什么是日志? 日志是一种可以追踪某些软甲运行时所发生的事情的方法。 2.日志有什么用? 程序调试 排错 用户行为分析 3.日志的五个级别 日志登记 数值表示 描述 debug 10 最详细的日志信息,用于诊断问题 INFO 20 详细日志信息仅次于DEBUG,记录关键节点的信息 WARNING 30(...

Anthonyyyy的博客 2803

嵌入式开发也玩“全家桶”?手把手教你用CLion+PyOCD调试APM32,比OpenOCD更简单

本文详细介绍了如何使用CLion和PyOCD组合进行APM32嵌入式开发,提供从环境配置到实战调试的完整指南。相比传统工具如Keil和OpenOCD,这套方案更轻量、易用,特别适合现代开发者需求,涵盖CMake配置、PyOCD调试技巧及常见问题解决。

weixin_42543046的博客 464

从零搭建AGV避障系统:我用激光雷达+树莓派视觉模块踩过的那些坑

本文分享了基于树莓派与国产激光雷达从零搭建低成本AGV避障系统的实战经验。针对复杂仓库环境,详细剖析了激光雷达数据噪声、视觉模块算力瓶颈、IMU漂移等核心挑战,并提供了多传感器融合、软件架构设计与避障决策的具体解决方案,为中小型自动化改造项目提供了宝贵参考。

git9versioner的博客 984

详解python的logging模块

使用python文件将输出信息写入到文件中

weixin_46713695的博客 2946

用Python和sklearn预测NBA比赛胜负:从数据清洗到模型优化的完整流程

本文详细介绍了如何使用Python和sklearn构建NBA比赛胜负预测模型,涵盖从数据清洗、特征工程到模型优化与部署的完整流程。通过对比随机森林、XGBoost等主流算法,提供实战技巧和解决方案,帮助数据爱好者掌握体育数据分析的核心技术。

weixin_30823001的博客 134

python 日志 logging模块(详细解析)

1 基本使用 转自:https://www.cnblogs.com/wf-linux/archive/2018/08/01/9400354.html 配置logging基本的设置,然后在控制台输出日志, import logging logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(...

pansaky的博客 15万+

Unity集成阿里Qwen2.5-Omni全模态大模型实战:语音交互与多模态AI开发指南

本文详细介绍了在Unity中集成阿里Qwen2.5-Omni全模态大模型的实战指南。通过C#脚本开发,实现语音交互、图像分析等多模态AI功能,涵盖API调用、音频处理、流式响应解析等核心步骤,为游戏、虚拟人等Unity应用提供沉浸式智能交互解决方案。

weixin_29005499的博客 316

ComfyUI-controlnet控制出图

提供加载预处理器节点。

Bu2n的博客 5497

python logging模块详解

logging库采用模块化方法,并提供了几类组件:记录器,处理程序,过滤器和格式化程序。 以记录器Logger为对象,设置合适的处理器Handler,辅助以筛选器Filter、格式器Formatter,设置日志级别以及常用的方法,最终输出理想的日志记录给到指定目标

weixin_47154909的博客 1万+

在MATLAB和Simulink中设计并仿真一个电动汽车整车动力学模型与控制系统

电动汽车(EV, Electric Vehicle)的动力学建模与控制仿真在车辆开发过程中起着至关重要的作用。通过Simulink进行整车动力学模型的构建和控制策略的验证,可以有效评估车辆性能、优化系统设计并降低开发成本。以下是如何在MATLAB和Simulink中设计并仿真一个电动汽车整车动力学模型与控制系统的详细步骤。通过上述步骤,我们成功设计并实现了基于Simulink的电动汽车整车动力学模型与控制仿真。该系统能够模拟复杂的整车动力学行为,验证控制策略的有效性,并通过优化设计提高车辆的性能和可靠性。

xiaoheshang_123的博客 550

Python logging 模块之 logging.basicConfig 用法和参数详解

Python 函数之 logging.basicConfig 用法和参数详解 先举例个例子: import logging logging.basicConfig(level=logging.INFO, format='%(asctime)s %(filename)s %(levelname)s %(message)s', ...

静堂先生的博客 6万+

RH850从0搭建Autosar开发环境【17】- Davinci Configurator之DCM模块配置详解(下)

RH850从0搭建Autosar开发环境【17】- Davinci Configurator之DCM模块配置详解(下)

weixin_42412049的博客 2379

VLA仿真平台:Isaac sim、MuJoCo

在虚拟仿真领域,VLA(Virtual Learning Agent)仿真器是用于开发和训练虚拟机器人代理的环境,它们为机器人提供了一个平台来进行各种任务的模拟和学习,特别是在强化学习(RL)中。两款广泛应用的仿真器是和。这两者各有其特点和优势,适用于不同类型的机器人研究和开发。

u013250861的博客 864

python之logging模块

python之logging模块

weixin_39926295的博客 1647

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Python的logging模块

DEBUG: 详细信息,通常只在调试问题时使用。INFO: 确认一切按预期运行。WARNING: 指示可能出现的问题,但仍可继续运行。ERROR: 由于更严重的问题,某些功能无法执行。CRITICAL: 严重错误,程序可能无法继续运行。

KIKI3666的博客 2635

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

python之logging模块详解

python之 logging 模块 文章目录python之 logging 模块一、日志关概念日志的作用日志的等级3、日志字段信息与日志格式4、日志功能的实现二、 logging 模块介绍什么是logging模块logging模块的作用logging模块的优点:logging模块日志的级别三、logging 模块的使用方式介绍logging使用方式介绍:示例:直接导入logging模块logging模块定义的模块级别的常用函数第一种使用方式:简单配置默认输出格式为默认日志级别为warning,默认打印到终

淘小欣的博客 1437

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

python的logging模块详解

目录0 前言1 logging简介2 logging模块的使用2.1 基本使用logging.basicConfig()2.2 将日志写到文件中2.3 同时将日志输出到控制台和日志文件2.4 handler的种类2.5 日志回滚 RotatingFilehandler2.6 消息的等级logging.setLevel()2.7 捕获traceback2.8 多模块使用logging3 通过JSON和YAML文件配置logging3.1 通过JSON文件配置3.2 通过YAML文件配置 0 前言   logg

Elenstone的博客 1093

python logging模块 详解

Python 的 logging 模块提供了灵活且强大的日志记录功能,适用于各种规模的应用程序。通过合理配置 Logger、Handler 和 Formatter,可以满足不同的日志记录需求。

stephenbruce的博客 1326

Python logging 模块

Python logging 模块 给大家剖析下Python的logging模块。 logging模块是Python内置的一个强大易用的日志模块。简单到你只需要两行代码就能输出一些东西来:import logging logging.warning('Hi, I print something.')输出:WARNING:root:Hi, I print something.当然,我们可不能满足于

灰蓝 9171

Python中内置的日志模块logging用法详解

logging模块简介 Python的logging模块提供了通用的日志系统,可以方便第三方模块或者是应用使用。这个模块提供不同的日志级别,并可以采用不同的方式记录日志,比如文件,HTTP GET/POST,SMTP,Socket等,甚至可以自己实现具体的日志记录方式。 logging模块与log4j的机制是一样的,只是具体的实现细节不同。模块提供logger,handler,filter,fo...

pansaky的博客 2万+

python logging模块

实际开发一个application,首先可以通过logging配置文件编写好这个application所对应的配置,可以生成一个根logger,如'PythonAPP',然后在主函数中通过fileConfig加载logging配置,接着在application的其他地方、不同的模块中,可以使用根logger的子logger,如'PythonAPP.Core','PythonAPP.Web'来进行log,而不需要反复的定义和配置各个模块的logger。通过YAML文件进行配置,比JSON看起来更加简介明了,

2401_86940371的博客 1821

Python logging模块的基本使用、进阶使用详解

Python logging模块的基本使用、进阶使用详解

小青龍 的博客 3万+
上一篇: python argparse 用法总结
下一篇: MxNet与numpy 的ndarray区别
tealex
博客等级 码龄19年 36粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值