Python有自带的logging模块,用于日志记录,功能很强大,但不好用,使用挺麻烦的,而且发现了几个bug,调用了一个logger.warning()一次,结果日志文件中出现了n行记录,且逐渐变成n+1,n+2,...越来越多。也不想去查原因,索性自己写一个日志功能。
我想要的日志的核心功能就只有两点:
1. 保存触发时间、异常堆栈信息。
2. 用文件形式保存。
上面第1点可以用Python自带的traceback模块实现,文件读写就很简单了。
MyLogger.py
1 import os
2 import time
3 import traceback
4
5 class MyLogger:
6 def __init__(self,filename='./log/myapp.log'):#默认的日志文件为当前目录的子目录下的myapp.log文件
7 self.logfile=filename
8 path = filename[0:filename.rfind("/")]
9 if not os.path.isdir(path): # 无文件夹时创建
10 os.makedirs(path)
11 if not os.path.isfile(filename):
12 f=open(self.logfile,'w',encoding='utf-8')
13 f.close()
14 self.default_formator='{0},File {1},{2}():{3}\n'
15
16 def get_invoker_info(self):
17 invoker_file=traceback.extract_stack()[-3].filename#调用本logger的代码的所在文件
18 invoker_func=traceback.extract_stack()[-3].name#调用本logger的代码(其实就是下面的log方法和error方法)所在的函数
19 return invoker_file,invoker_func
20 '''普通日志,保存任意信息,且也有堆栈信息'''
21 def log(self,msg=''):
22 t=time.strftime('%Y-%m-%d %H:%M:%S')
23 print('Log at:',t)
24 formator='Log at '+self.default_formator
25 #获取调用者信息
26 invoker_file,invoker_func=self.get_invoker_info()
27 content=formator.format(t,os.path.basename(invoker_file),invoker_func,msg)
28 self.append_log(content)
29 ''''错误日志,报错的时候可以使用,加上了堆栈的形式'''
30 def error(self,msg=''):
31 t=time.strftime('%Y-%m-%d %H:%M:%S')
32 print('Error at:',t)
33 trace=traceback.format_exc()
34 #获取调用者信息
35 invoker_file,invoker_func=self.get_invoker_info()
36 formator='Error at '+self.default_formator+'{4}'
37 content=formator.format(t,os.path.basename(invoker_file),invoker_func,msg,trace)
38 self.append_log(content)
39
40 def append_log(self,content):
41 f=open(self.logfile,'a',encoding='utf-8')
42 f.write(content)
43 #f.write('\n')
44 f.close()
45
46 logger=MyLogger()
用法示例
logger_test.py
1 from MyLogger import logger
2
3 def test():
4 try:
5 b=0
6 a=1/b
7 except Exception as e:
8 #logger.error('UU',exc_info=True)
9 logger.error(e)
10 logger.log('calling exception')
11
12 if __name__=='__main__':
13 test()
14 logger.log('info')
打印的日志在log/myapp.log中的内容如下:
Error at 2019-12-31 19:18:48,File logger_test.py,test():division by zero
Traceback (most recent call last):
File "/Users/admin/Desktop/code/spyder_workspace/logger_test.py", line 13, in test
a=1/b
ZeroDivisionError: division by zero
Log at 2019-12-31 19:18:48,File logger_test.py,test():calling exception
Log at 2019-12-31 19:18:48,File logger_test.py,<module>():info