点击上方“
程序员共读
”,选择“置顶公众号”
关键时刻,第一时间送达!
虽说 logging 模块都用了好久了,不过由于文档不够详细,每次都忍不住去搜索别人的文章,于是就干脆记录下来吧。
懒得分段了,想到哪写到哪吧。
1.为什么 logging.info() 默认不输出任何东西?
因为默认生成的 root logger 的 level 是 logging.WARNING,低于该级别的就不输出了。可以进行如下设置来输出:
>>>
import
logging
>>>
logging
.
info
(
'test'
)
>>>
root_logger
=
logging
.
getLogger
()
# 或使用未公开的 logging.root
>>>
root_logger
.
level
30
>>>
logging
.
getLevelName
(
30
)
'WARNING'
>>>
root_logger
.
level
=
logging
.
NOTSET
>>>
logging
.
info
(
'test'
)
INFO
:
root
:
test
如果还没配置 handler 的话,可以用 logging.basicConfig() 来配置:
>>>
root_logger
.
handlers
[]
>>>
logging
.
basicConfig
(
level
=
logging
.
NOTSET
)
>>>
root_logger
.
handlers
[
<
logging
.
StreamHandler object
at
0x108becd10
>
]
>>>
logging
.
info
(
'test'
)
INFO
:
root
:
test
2.如何定制输出的格式?
给 logger 的 handler 设置一个 logging.Formatter 对象:
>>>
root_logger
.
handlers
[
0
].
formatter
.
format
<
bound method Formatter
.
format
of
<
logging
.
Formatter
object
at
0x10c062d90
>>
>>>
root_logger
.
handlers
[
0
].
formatter
.
datefmt
>>>
root_logger
.
handlers
[
0
].
formatter
.
_fmt
'%(levelname)s:%(name)s:%(message)s'
>>>
LOGGING_FORMAT
=
'[%(levelname)1.1s %(asctime)s %(module)s:%(lineno)d] %(message)s'
>>>
DATE_FORMAT
=
'%y%m%d %H:%M:%S'
>>>
formatter
=
logging
.
Formatter
(
LOGGING_FORMAT
,
DATE_FORMAT
)
>>>
root_logger
.
handlers
[
0
].
formatter
=
formatter
>>>
logging
.
info
(
'test'
)
[
I
130221
01
:
58
:
28
<
stdin
>:
1
]
test
如果还没配置 handler 的话,可以用 logging.basicConfig() 来配置:
logging
.
basicConfig
(
level
=
logging
.
NOTSET
,
format
=
LOGGING_FORMAT
,
datefmt
=
DATE
_
FORMAT
)
详细的格式介绍就查看文档吧。
3.为什么我重定向了 stdout,但是却看不到输出?
因为默认生成的 root logger 的 handler 的 stream 是 stderr,不是 stdout:
>>>
root_logger
.
handlers
[
0
].
stream
<
open
file
'
'
,
mode
'w'
at
0x1089cb270
>
可以如下分别配置:
stdout_handler
=
logging
.
StreamHandler
(
sys
.
__stdout__
)
stdout_handler
.
level
=
logging
.
DEBUG
stdout_handler
.
formatter
=
formatter
root_logger
.
addHandler
(
stdout_handler
)
stderr_handler
=
logging
.
StreamHandler
(
sys
.
__stderr__
)
stderr_handler
.
level
=
logging
.
WARNING
stderr_handler
.
formatter
=
formatter
root_logger
.
addHandler
(
stderr_handler
)
|
4.
如何将日志输出到文件?
使用 logging.FileHandler():
handler
=
logging
.
FileHandler
(
'log/test.log'
)
root_logger
.
addHandler
(
handler
)
其中文件名可以使用相对路径,但要保证文件夹存在。默认的文件打开方式是 append。
如果还没配置 handler 的话,可以用 logging.basicConfig() 来配置:
logging
.
basicConfig
(
level
=
logging
.
NOTSET
,
format
=
LOGGING_FORMAT
,
datefmt
=
DATE_FORMAT
,
filename
=
'log/test.log'
,
filemode
=
'a'
)
5.
捕捉了一个异常,如何输出执行堆栈?
使用 logging.exception(),或在调用 logging.debug() 等方法时加上 exc_info=True 参数。
>>>
try
:
...
0
/
0
...
except
:
...
logging
.
exception
(
'Catch an exception.'
)
...
print
'-'
*
10
...
logging
.
warning
(
'Catch an exception.'
,
exc_info
=
True
)
...
ERROR
:
root
:
Catch an exception
.
Traceback
(
most recent call
last
)
:
File
"
"
,
line
2
,
in
<
module
>
ZeroDivisionError
:
integer division
or
modulo by
zero
----------
WARNING
:
root
:
Catch an exception
.
Traceback
(
most recent call
last
)
:
File
"
"
,
line
2
,
in
<
module
>
ZeroDivisionError
:
integer division
or
modulo by
zero
6.
能不能针对不同的用途或模块,指定不同的日志?
可以创建多个 logger:
console_handler
=
logging
.
StreamHandler
(
sys
.
__stdout__
)
console_handler
.
level
=
logging
.
DEBUG
console_logger
=
logging
.
getLogger
(
'test'
)
console_logger
.
addHandler
(
console_handler
)
file_handler
=
logging
.
FileHandler
(
'log/test.log'
)
file_handler
.
level
=
logging
.
WARNING
file_logger
=
logging
.
getLogger
(
'test.file'
)
file_logger
.
addHandler
(
file_handler
)
console_logger
.
error
(
'test'
)
file_logger
.
error
(
'test'
)
console_logger
.
|