日志记录是一种跟踪软件在运行时所发生的任何事件的方法。也就是说,在日常开发过程中,我们可以将程序所产生的事件用日志的形式记录下来,以此来查看程序逻辑执行得是否合理。这对于开发人员来说十分的重要。本篇文章使用Python中的logging来对日志的一些操作展开说明。
logging为我们提供了许多记录日志的方法,如 debug()
、info()
、warning()
、error()
、critical()
。根据处理事件的情况不同,又可以分为不同的等级,如 DEBUG
、INFO
、WARNING
、ERROR
、CRITICAL
。如下表格:
等级 |
啥时候用? |
DEBUG |
输出详细信息,通常仅在诊断问题的时候使用。 |
INFO |
按照预期正在进行的并且是确认的事情。 |
WARNING |
预示着发生了意想不到的事情,或者在不久的将来预示着一些问题(例如“磁盘空间低”)。软件仍在按预期运行。 |
ERROR |
由于更严重的问题,该软件无法执行某些功能。 |
CRITICAL |
表明程序本身可能无法继续运行的严重的错误。 |
下表给出了日志记录的等级:
等级 |
数值 |
CRITICAL |
50 |
ERROT |
40 |
WARNING |
30 |
INFO |
20 |
DEBUG |
10 |
NOTSET |
0 |
然而,默认情况下是 WARNING
,这种情况下它会追踪此级别及以上级别的事件。
可以以不同方式处理被跟踪的事件。处理跟踪事件的最简单方法是将它们打印到控制台,另一种常见方法是将它们写入磁盘文件。
先来看一个简单的例子,首先导入 logging
模块,通过模块的 basicConfig
方法设置了日志文件的名称以及将跟踪阈值的日志记录级别设置为 DEBUG
,最后输出三条日志信息,如下所示:
1
2
3
4
5
6
|
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.')
|
执行程序后会生成一个日志文件example.log
,打开它就会看到日志信息,如下图:
你可以看到,单单是输出了日志信息,而没有时间,不方便查看。接下来通过另一个例子将日志时间、日志等级等信息一起记录下来。
下面的例子用于计算一元二次方程的根,计算完成后将日志记录下来,如下所示:
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
|
import logging
import math
# 规定打印日志的格式
LOG_FORMAT = '%(levelname)s %(asctime)s - %(name)s - %(message)s'
# 增加以及初始化logger
logging.basicConfig(filename='f:\\Python_test\\BasicKnowledge\\test.log',
level=logging.DEBUG,
format=LOG_FORMAT,
filemode='w')
# getLogger(name)用于获取logger对象,如果不指定记录器的名称name,则返回root对象
logger = logging.getLogger('Carol')
def quadratic_formula(a, b, c):
"""
返回方程 ax^2 + bx + c = 0 的根
"""
logger.info('quadratic_formula({0}, {1}, {2})'.format(a, b, c))
# 计算判别式
logger.debug('# Compute the discriminant')
disc = b ** 2 - 4 * a * c
# 计算两个根
logger.debug('# compute the two roots')
root1 = (-b + math.sqrt(disc)) / (2 * a)
root2 = (-b - math.sqrt(disc)) / (2 * a)
# 返回根
logger.debug('# return the roots')
return root1, root2
roots = quadratic_formula(1, 0, -4)
print(roots)
|
输出结果如下:
同时,执行程序后会生成一个日志文件 test.log
,打开它就会看到日志信息,如下图:
你可以看到,在有解的情况下不仅返回了方程的根,而且也将计算顺序以日志的形式保存了下来。
下面我们给它一个无解的参数,看看它的日志文件会保存什么东西。修改下列语句:
1
|
roots = quadratic_formula(1, 0, 1)
|
你可以看到控制台报错,同时日志文件如下图:
这是因为它在执行完 logger.debug('# compute the two roots')
这条语句之后就不再执行了,也就是我们修改的参数不满足方程根的求解。
再最后一个例子,我们结合 try-except-else-finally
来说明 logging
的使用方法。
对于不熟悉 try-except-else-finally
的同学,你可以看下面的图片:
该例子用于统计打开一个文件所需要的时间,并将其记录在日志文件中,如下所示:
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
import time
logging.basicConfig(filename="F:\\Python_test\\BasicKnowledge\\problems.log",
level=logging.DEBUG)
logger = logging.getLogger()
def read_file_timed(path):
"""Return the contents of the file at 'path' and measure time required"""
start_time = time.time()
try:
f = open(path, mode='rb')
data = f.read()
return data
except FileNotFoundError as err:
logger.error(err)
raise
else:
f.close()
finally:
stop_time = time.time()
dt = stop_time - start_time
logger.info('Time required for {file} = {time}'.format(file=path, time=dt))
path = read_file_timed('F:\\Python_test\\BasicKnowledge\\google_stock_data.csv')
|
如果 google_stock_data.csv
文件存在的话,你可以看到日志文件中有如下内容:
如果打开一个不存在的文件,执行程序后,会出现如下的内容:
好了,介绍完了。
对于一个比较有意思的谷歌股票数据文件,你可以在 这里 下载。