- 1. logging 简介
- 2. Basic logging Tutorial
- 2.1 使用logging 屏幕打印
- 2.2 使用logging 保存文件
- 2.3 多个模块logging
- 2.3 格式化输出,变量输出
- 3. Advanced Logging Tutorial
- Reference
logging是一种跟踪某些软件运行时发生的事件的方法。 软件开发人员可以将logging添加到他们的代码中,以表明某些事件已经发生。 这个事件可以由打印信息描述,该信息中可以包含变量。 开发者也可以赋予事件的一定的重要性; 重要性也可以称为级别或严重性。
logging函数以其用于跟踪的事件的级别或严重性命名(按严重程度递增的顺序):
| level | when it’s used |
|---|---|
| DEBUG | Detailed information, typically of interest only when diagnosing problems. |
| INFO | Confirmation that things are working as expected. |
| WARNING | An indication that something unexpected happened, or indicative of some problem in the near future. The software is still working as expected. |
| ERROR | Due to a more serious problem, the software has not been able to perform some function. |
| CRITICAL | A serious error, indicating that the program itself may be unable to continue running. |
import logging
logging..basicConfig(level=logging.DEBUG)
logging.debug('this is a debug message')
logging.info('this is an info message')
logging.warning('this is a warning message')
logging.error('this is a error message')
logging.critical('this is a critical mesage')
2.2 使用logging 保存文件
import logging
logging..basicConfig(filename='example.log', encoding='utf-8', level=logging.DEBUG)
logging.debug('this is a debug message')
logging.info('this is an info message')
logging.warning('this is a warning message')
logging.error('this is a error message')
logging.critical('this is a critical mesage')
2.3 多个模块logging
# main.py
# main module
import logging
import submodule
# write into demo.log
logging.basicConfig(filename='demo.log', level=logging.DEBUG)
# stream to screen
#logging.basicConfig(level=logging.DEBUG)
def main():
logging.info('main started')
submodule.do_logger()
logging.debug('main, this is a debug message')
logging.info('main, this is an info message')
logging.warning('main, this is a warning message')
logging.error('main, this is a error message')
logging.critical('main, this is a critical mesage')
logging.info('main end')
if __name__=='__main__':
main()
# submodule.py
import logging
def do_logger():
logging.debug('main, this is a debug message')
logging.info('main, this is an info message')
logging.warning('main, this is a warning message')
logging.error('main, this is a error message')
logging.critical('main, this is a critical mesage')
写入demo.log的内容如下:
INFO:root:main started DEBUG:root:main, this is a debug message INFO:root:main, this is an info message WARNING:root:main, this is a warning message ERROR:root:main, this is a error message CRITICAL:root:main, this is a critical mesage DEBUG:root:main, this is a debug message INFO:root:main, this is an info message WARNING:root:main, this is a warning message ERROR:root:main, this is a error message CRITICAL:root:main, this is a critical mesage INFO:root:main end2.3 格式化输出,变量输出
basicConfig支持以下关键字变量:
| Format | Description |
|---|---|
| filename | 使用指定的文件名创建FileHandler,而不是StreamHandler |
| filemode | 如指定文件名,设置打开文件的方式,默认是’a’ |
| format | 常用参数,设置输出字符串的格式,默认使用冒号分隔属性levelname,name和message |
| style | If format is specified, use this style for the format string. One of ‘%’, ‘{’ or ‘$’ for printf-style, str.format() or string.Template respectively. Defaults to ‘%’. |
| level | Set the root logger level to the specified level. |
| stream | Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with filename - if both are present, a ValueError is raised. |
| handlers | If specified, this should be an iterable of already created handlers to add to the root logger. Any handlers which don’t already have a formatter set will be assigned the default formatter created in this function. Note that this argument is incompatible with filename or stream - if both are present, a ValueError is raised. |
| force | If this keyword argument is specified as true, any existing handlers attached to the root logger are removed and closed, before carrying out the configuration as specified by the other arguments. |
| encoding | If this keyword argument is specified along with filename, its value is used when the FileHandler is created, and thus used when opening the output file. |
| errors | If this keyword argument is specified along with filename, its value is used when the FileHandler is created, and thus used when opening the output file. If not specified, the value ‘backslashreplace’ is used. Note that if None is specified, it will be passed as such to open(), which means that it will be treated the same as passing ‘errors’. |
import logging
str_format = '%(asctime)s -- %(filename)s line:%(lineno)d -- %(levelname)s -- %(message)s'
time_format = '%Y-%m-%d %H:%M:%S'
logging.basicConfig(format=str_format, datefmt=time_format, level=logging.DEBUG)
name = 'Julian'
age = 50
logging.warning('%s is %d years old.', name,age)
logging.warning(f'{name} is {age} years old.')
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too')
输出结果
2022-04-30 09:38:00 -- main.py line:29 -- WARNING -- Julian is 50 years old. 2022-04-30 09:38:00 -- main.py line:32 -- DEBUG -- This message should appear on the console 2022-04-30 09:38:00 -- main.py line:33 -- INFO -- So should this 2022-04-30 09:38:00 -- main.py line:34 -- WARNING -- And this, too3. Advanced Logging Tutorial
在一些简单的代码设计中,使用logging基本上就可以满足调试的基本需求。对于一些特殊的需求,比如要将不能级别的信息写入不同的文件,将输出信息在屏幕显示的同时写入文件等,使用Logging基本方法目前还无法实现。这时候可以考虑logging的高级用法:
logging的高级用法,简单来说就是使用logger,handler,filter,formatter.
- logger: 记录器,程序代码直接使用的接口,类似于marker,
- Handler: 处理器,顾名思义,就是处理由logger创建的日志记录,发送到适当的位置
- filter: 过滤器,提供了更细粒度的工具确定需要输出那些日志
- formatter: 格式化,设置最终输出日志的格式,以及信息
import logging
# 1. Create a logger
logger = logging.getLogger(__name__)
# Step 2. Craete Handler
# craete file handler which logs even debug messages
f_handler = logging.FileHandler('debug.log')
f_handler.setLevel(logging.DEBUG)
# create console handler with a higher log level
c_handler = logging.StreamHandler()
c_handler.setLevel(logging.ERROR)
# 3. Create Formatter and add it to the handler
s_format = '%(asctime)s -- %(filename)s line:%(lineno)d -- %(levelname)s -- %(message)s'
t_format = '%Y-%m-%d %H:%M:%S'
formatter = logging.Formatter(fmt=s_format,datefmt=t_format)
f_handler.setFormatter(formatter)
c_handler.setFormatter(formatter)
# 4. add handler to the logger
logger.addHandler(f_handler)
logger.addHandler(c_handler)
logger.debug('advance, this is a debug message')
logger.info('advance, this is an info message')
logger.warning('advance, this is a warning message')
logger.error('advance, this is a error message')
logger.critical('advance, this is a critical mesage')
Reference
[1]. https://docs.python.org/3/howto/logging.html
[2].https://zhuanlan.zhihu.com/p/360306588
[3].https://www.cnblogs.com/yizhipanghu/p/15566983.html



