Python有自带的logging模块,用于日志记录,功能很强大,但不好用,使用挺麻烦的,而且发现了几个bug,调用了一个logger.warning()一次,结果日志文件中出现了n行记录,且逐渐变成n+1,n+2,…越来越多。也不想去查原因,索性自己写一个日志功能。
我想要的日志的核心功能就只有两点:
1. 保存触发时间、异常堆栈信息。
2. 用文件形式保存。
上面第1点可以用Python自带的traceback模块实现,文件读写就很简单了。
MyLogger.py
import os
import time
import traceback class MyLogger:
def __init__(self,filename='./log/myapp.log'):#默认的日志文件为当前目录的子目录下的myapp.log文件
self.logfile=filename
path = filename[0:filename.rfind("/")]
if not os.path.isdir(path): # 无文件夹时创建
os.makedirs(path)
if not os.path.isfile(filename):
f=open(self.logfile,'w',encoding='utf-8')
f.close()
self.default_formator='{0},File {1},{2}():{3}\n' def get_invoker_info(self):
invoker_file=traceback.extract_stack()[-3].filename#调用本logger的代码的所在文件
invoker_func=traceback.extract_stack()[-3].name#调用本logger的代码(其实就是下面的log方法和error方法)所在的函数
return invoker_file,invoker_func
'''普通日志,保存任意信息,且也有堆栈信息'''
def log(self,msg=''):
t=time.strftime('%Y-%m-%d %H:%M:%S')
print('Log at:',t)
formator='Log at '+self.default_formator
#获取调用者信息
invoker_file,invoker_func=self.get_invoker_info()
content=formator.format(t,os.path.basename(invoker_file),invoker_func,msg)
self.append_log(content)
''''错误日志,报错的时候可以使用,加上了堆栈的形式'''
def error(self,msg=''):
t=time.strftime('%Y-%m-%d %H:%M:%S')
print('Error at:',t)
trace=traceback.format_exc()
#获取调用者信息
invoker_file,invoker_func=self.get_invoker_info()
formator='Error at '+self.default_formator+'{4}'
content=formator.format(t,os.path.basename(invoker_file),invoker_func,msg,trace)
self.append_log(content) def append_log(self,content):
f=open(self.logfile,'a',encoding='utf-8')
f.write(content)
#f.write('\n')
f.close() logger=MyLogger()
用法示例
logger_test.py
from MyLogger import logger def test():
try:
b=0
a=1/b
except Exception as e:
#logger.error('UU',exc_info=True)
logger.error(e)
logger.log('calling exception') if __name__=='__main__':
test()
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