zoukankan      html  css  js  c++  java
  • 【Python】自己写日志功能

    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
  • 相关阅读:
    BAT都来参加的 DevOps Master 培训
    如何快速复制BAT级的DevOps工具链
    DevOps开源工具的三种分类整理
    Devops成功的八大炫酷工具
    阿里CI/CD、DevOps、分层自动化技术
    Android爬坑之旅:软键盘挡住输入框问题的终极解决方式
    Android应用程序窗体View的创建过程
    LeetCode Convert Sorted List to Binary Search Tree
    Spark Streaming性能优化系列-怎样获得和持续使用足够的集群计算资源?
    android nfc中Ndef格式的读写
  • 原文地址:https://www.cnblogs.com/aaronhoo/p/12126585.html
Copyright © 2011-2022 走看看