本文由Scarb发表于金甲虫的博客,转载请注明出处

Python logging 笔记

整理一下Python自带的logging模块的使用。

1. 基本概念

Logger对象

Logger不会直接实例化,使用模块级别的函数logging.getLogger(name)可以获取logger对象。获取同名logger会返回相同logger对象的引用。
name可以是一个用点分割的包含层级关系的值,如foo.bar.baz。较低的层级是高层级logger的子项,较高层级的logger会包含低层logger的日志。

logger可以设置很多属性,这里不赘述。
logger对象可以打印日志,用logger.log(level, message)方法。

日志级别

级别 重要性数值
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTSET 0

Handler

handler不会直接实例化,而是用来充当子类。
handler决定日志如何输出和输出到哪(控制台、文件、email等)。
有多种handler,将输出到不同地方。

  • StreamHandler
  • FileHandler
  • BaseRotatingHandler
  • RotatingFileHandler
  • SocketHandler
  • ……

Formatter

formatter负责将一个log record格式化,转换为人可以看懂的格式。
在formatter中可以指定日志输出的格式。
格式用这种形式来指定'%(message)s%'
比较完整的一种格式:
%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s] %(message)s

Filter

filter被handler和logger使用,用来做复杂的过滤。

LogRecord

包含与记录日志相关的所有信息

2. 基本使用

简单的例子

1
2
3
import logging
logging.warning('Watch out!') # will print a message to the console
logging.info('I told you so') # will not print anything
1
WARNING:root:Watch out!

这里没有指定打印日志的级别,warning级别的日志被打印,info级别的没有被打印。

打印到文件

1
2
3
4
5
import logging
logging.basicConfig(filename='example.log',level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')

这里通过logging.basicConfig指定了打印的文件名和打印的日志级别,DEBUG和以上级别的日志都会被打印到文件里。

1
2
3
DEBUG:root:This message should go to the log file
INFO:root:So should this
WARNING:root:And this, too

格式化输出

1
2
3
4
5
import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too')
1
2
3
DEBUG:This message should appear on the console
INFO:So should this
WARNING:And this, too

3. 高级使用

配置logging

配置logging有三种方式

  1. 用Python代码创建logger、handler、formatter并调用配置方法。
  2. 创建配置文件,并用fileConfig()函数配置
  3. 用dict编写配置,并传给dictConfig()

Python代码显式配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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.warning('warn message')
logger.error('error message')
logger.critical('critical message')
1
2
3
4
5
6
$ 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

fileConfig 用文件配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.warning('warn message')
logger.error('error message')
logger.critical('critical message')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[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
datefmt=
1
2
3
4
5
6
$ 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

dictConfig

贴一段django文档的日志配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
'style': '{',
},
'simple': {
'format': '{levelname} {message}',
'style': '{',
},
},
'filters': {
'special': {
'()': 'project.logging.SpecialFilter',
'foo': 'bar',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'filters': ['special']
}
},
'loggers': {
'django': {
'handlers': ['console'],
'propagate': True,
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'myproject.custom': {
'handlers': ['console', 'mail_admins'],
'level': 'INFO',
'filters': ['special']
}
}
}
1
2
logging.config.dictConfig(LOGGING)
logger = logging.getLogger('django')

4. 参考资料

  1. Logging HOWTO
  2. logging — Logging facility for Python
  3. django-logging