Python Logging模块的简单使用
前言
日志是非常重要的,最近有接触到这个,所以系统的看一下Python这个模块的用法。本文即为Logging模块的用法简介,主要参考文章为Python官方文档,链接见参考列表。
另外,Python的HOWTOs文档很详细,连日志该怎么用都写了,所以有英文阅读能力的同学建议去阅读一下。
Logging模块构成
组成
主要分为四个部分:
- Loggers:提供应用程序直接使用的接口
- Handlers:将Loggers产生的日志传到指定位置
- Filters:对输出日志进行过滤
- Formatters:控制输出格式
日志级别
Level | Numeric value | When it’s used |
---|---|---|
DEBUG | 10 | Detailed information, typically of interest only when diagnosing problems. |
INFO | 20 | Confirmation that things are working as expected. |
WARNING | 30 | An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected. |
ERROR | 40 | Due to a more serious problem, the software has not been able to perform some function. |
CRITICAL | 50 | A serious error, indicating that the program itself may be unable to continue running. |
NOSET | 0 | getattr(logging, loglevel.upper()) |
默认级别是WARNING,可以使用打印到屏幕上的方式记录,也可以记录到文件中。
模块使用示例
简单例子
打印输出
In [5]: import logging
In [6]: logging.warning("FBI warning")
WARNING:root:FBI warning
In [7]: logging.info("information")
# 没有打印是因为默认级别是warning
输出到文件中
In [4]: import logging
In [5]: logging.basicConfig(filename='example.log', level=logging.DEBUG)
In [6]: logging.debug("debug")
In [7]: logging.warning('warning')
In [8]: logging.info('info')
In [9]: ls
C++ STL/ a.py example.log parser/ test.sh*
In [10]: cat example.log
DEBUG:root:debug
WARNING:root:warning
INFO:root:info
In [14]: logging.warning('new warning')
# 注意这种是直接往后面添加,也就是add的,若是想覆盖内容可以更改文件写入方式
In [15]: cat example.log
DEBUG:root:debug
WARNING:root:warning
INFO:root:info
WARNING:root:new warning
# 覆盖的方式写入例子
(test) ➜ test ipython
WARNING: Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
Python 2.7.11 (default, Jun 17 2016, 20:01:51)
Type "copyright", "credits" or "license" for more information.
IPython 4.2.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: import logging
In [2]: logging.basicConfig(filename='example.log', filemode='w', level=logging.DEBUG)
In [3]: logging.warning('FBI warning')
In [4]: ls
C++ STL/ a.py example.log parser/ test.sh*
In [5]: cat example.log
WARNING:root:FBI warning
In [6]: quit
(test) ➜ test ipython
WARNING: Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
Python 2.7.11 (default, Jun 17 2016, 20:01:51)
Type "copyright", "credits" or "license" for more information.
IPython 4.2.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: import logging
In [2]: logging.basicConfig(filename='example.log', filemode='w', level=logging.DEBUG)
In [3]: logging.warning('warning')
In [4]: cat example.log
WARNING:root:warning
变量的使用
和print
语句中使用变量一样,如:
In [5]: logging.warning('%s before you %s', 'Look', 'leap!')
In [6]: cat example.log
WARNING:root:warning
WARNING:root:Look before you leap!
输出格式
可以在basicConfig
中设置,参数名称可以参见链接,可以设置时间什么的,如:
In [2]: import logging
In [3]: logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s', level=logging.DEBUG)
In [4]: logging.warning('And this, too')
2016-12-06 15:40:43,577:WARNING:And this, too
进阶使用
当想项目中使用logging模块的时候肯定不能在这样一句句的写了,一般可能会抽象出一个模块来,这样比较有效一些。logging模块提供了四个类(Loggers,Formatters,Filtters,Handlers)来实现不同的功能,与此对应的我们如果想封装一个函数,也就要针对这几个功能来自定义一下。
想自定义的话思路也很简单,首先实例化一个相应的对象,然后进行一些设置,可以简单看一下下面的例子:
import logging
# create logger
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)
# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# add formatter to ch
ch.setFormatter(formatter)
# add ch to logger
logger.addHandler(ch)
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
# 输出是:
$ python simple_logging_module.py
2005-03-19 15:10:26,618 - simple_example - DEBUG - debug message
2005-03-19 15:10:26,620 - simple_example - INFO - info message
2005-03-19 15:10:26,695 - simple_example - WARNING - warn message
2005-03-19 15:10:26,697 - simple_example - ERROR - error message
2005-03-19 15:10:26,773 - simple_example - CRITICAL - critical message
从配置文件导入配置
模块内容:
import logging
import logging.config
logging.config.fileConfig('logging.conf')
# create logger
logger = logging.getLogger('simpleExample')
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
# 输出
$ python simple_logging_config.py
2005-03-19 15:38:55,977 - simpleExample - DEBUG - debug message
2005-03-19 15:38:55,979 - simpleExample - INFO - info message
2005-03-19 15:38:56,054 - simpleExample - WARNING - warn message
2005-03-19 15:38:56,055 - simpleExample - ERROR - error message
2005-03-19 15:38:56,130 - simpleExample - CRITICAL - critical message
配置文件内容:
[loggers]
keys=root,simpleExample
[handlers]
keys=consoleHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_simpleExample]
level=DEBUG
handlers=consoleHandler
qualname=simpleExample
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
同时也可以使用YAML格式的配置文件,如:
version: 1
formatters:
simple:
format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: simple
stream: ext://sys.stdout
loggers:
simpleExample:
level: DEBUG
handlers: [console]
propagate: no
root:
level: DEBUG
handlers: [console]
PS
Logging模块使用也会有很多坑,常见的是日志重复打印的问题,大家可以搜一下,这里提供一些链接供参考:
- http://www.jianshu.com/p/25f70905ae9d
- https://yinzo.github.io/14610807170718.html
- http://python.jobbole.com/86887/