为什么要生成日志
执行脚本时,我们通常希望能够生成相对应的日志,生成日志是为了方便执行完成后我们查看脚本的执行路径,有利于我们调试代码和定位问题。
日志文件就是通常我们理解的配置文件,主要有两种形式,一种是 ini 形式,另一种是 conf 形式。今天分享的是后者,也就是通过 conf 的配置文件来生成日志文件,我们可以把日志信息打印在显示控制台,也可以把日志信息保存在文件里,这样方便我们后期直接打开文件查看相应的日志信息,我们可以把常规的日志文件和有报错信息的日志文件区分开保存,如果有执行过程中有报错的话,我们可以直接通过保存的报错日志直接定位问题。
日志配置文件内容
日志的 conf 配置文件主要由 logger、handlers 日志文件、formatters 日志格式组成,详细配置内容如下,具体解释见下方。
Python
[loggers]
keys=root,infoLogger,errorLogger
[logger_root]
lever=DEBUG
handlers=consoleHandler
[logger_infoLogger]
handlers=fileHandler,consoleHandler
qualname=infoLogger
propagate=0
[logger_errorLogger]
handlers=fileHandler,consoleHandler
qualname=errorLogger
propagate=0
[handlers]
keys=fileHandler,consoleHandler
[handler_consoleHandler]
class=StreamHandler
level=ERROR
fromatter=form01
args=(sys.stderr,)
[handler_fileHandler]
class=FileHandler
level=INFO
formatter=form02
args=('../logs/testlog.log','a')
[formatters]
keys=form01,form02
[formatter_form01]
form01=%(asctime)s - %(levelname)s -%(pathname)s-%(lineno)d - %(message)s
[formatter_form02]
form02=%(asctime)s - %(levelname)s -%(pathname)s
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
[loggers]
keys=root,infoLogger,errorLogger
[logger_root]
lever=DEBUG
handlers=consoleHandler
[logger_infoLogger]
handlers=fileHandler,consoleHandler
qualname=infoLogger
propagate=0
[logger_errorLogger]
handlers=fileHandler,consoleHandler
qualname=errorLogger
propagate=0
[handlers]
keys=fileHandler,consoleHandler
[handler_consoleHandler]
class=StreamHandler
level=ERROR
fromatter=form01
args=(sys.stderr,)
[handler_fileHandler]
class=FileHandler
level=INFO
formatter=form02
args=('../logs/testlog.log','a')
[formatters]
keys=form01,form02
[formatter_form01]
form01=%(asctime)s-%(levelname)s-%(pathname)s-%(lineno)d-%(message)s
[formatter_form02]
form02=%(asctime)s-%(levelname)s-%(pathname)s
日志配置文件详细分析
loggers 部分 : 作用是配置 logger 信息。必须包含父类 root 的 logger,默认情况下,当使用无参函数 logging.getLogger() 时,就会默认返回 root 这个 logger,它的日志等级是 DEBUG,其他自定义 logge r可以通过 logging.getLogger(“infoLogger”) 方式进行调用。
logger_xxx : 对 loggers 中 keys 里面声明的 logger 进行逐个配置,且要一一对应。配置内容一般包括:handlers 日志输出的形式,控制台或者保存日志文件;qualname:指定调用这个日志时用的名字,用 logging.getLogger(qualname) 时的名字;propagate:表示是否继承父类也就是 root 的配置信息,0 表示 否,1 表示是。
handlers:定义声明 handlers 信息。常用的 handlers 包括 StreamHandler(仅将日志输出到控制台)、FileHandler(将日志信息输出保存到文件)。
handler_xxx : 对 handlers 中声明的 handler 进行逐个配置,且要一一对应。配置信息包括:class,表示日志展示形式,有 StreamHandler 展示到控制台,FileHandler 保存为日志文件;level,表示日志输出的等级,一般,控制台输出 ERROR 日志,日志文件输入详细的 INFO 日志;fromatter,定义日志的格式,详细格式见下方;args,元组格式,定义返回信息的路径,sys.stderr 的作用就是返回错误信息到控制台,并以红色字体显示,保存为日志文件时,需要给出日志文件的路径,和文件的写入形式,上面用了 a 表示以追加的形式写入日志文件。
formatter : 设置日志格式。可以按照自己的习惯定义多种格式,应用在不同等级的配置信息。
formatter_xxx : 对声明的formatterjinx进行配置,常见的日志格式见下方。
Python
# %(asctime)s 年-月-日 时-分-秒,毫秒
# %(filename)s 文件名,不含目录
# %(pathname)s 目录名,完整路径
# %(funcName)s 函数名
# %(levelname)s 级别名
# %(lineno)d 行号
# %(module)s 模块名
# %(message)s 日志信息
# %(name)s 日志模块名
# %(process)d 进程id
# %(processName)s 进程名
# %(thread)d 线程id
# %(threadName)s 线程名
1
2
3
4
5
6
7
8
9
10
11
12
13
# %(asctime)s 年-月-日 时-分-秒,毫秒
# %(filename)s 文件名,不含目录
# %(pathname)s 目录名,完整路径
# %(funcName)s 函数名
# %(levelname)s 级别名
# %(lineno)d 行号
# %(module)s 模块名
# %(message)s 日志信息
# %(name)s 日志模块名
# %(process)d 进程id
# %(processName)s 进程名
# %(thread)d 线程id
# %(threadName)s 线程名
调用日志配置文件
日志信息配置文件完成后,接下来,我们讲下怎么调用。
我们首先要打开同级目录下的 logger.conf 文件,并读取配置文件。
Python
config_file = open(r'./logger.conf', encoding='utf-8')
logging.config.fileConfig(config_file)
1
2
config_file=open(r'./logger.conf',encoding='utf-8')
logging.config.fileConfig(config_file)
然后读取配置文件信息来定义 logger。
Python
logger = logging.getLogger('infoLogger')
1
logger=logging.getLogger('infoLogger')
然后直接在相应的位置直接调用 logger 显示你想要的日志即可。
这样,testlog.log 的日志文件也会生成在同级目录下。