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} ' 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(' ') 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