python之追溯函數調用及錯誤日志詳細打印


一、函數調用追溯

1.1 原因

        在打印日志時,為實現日志分層打印,將打印日志的語句封裝到了print_log_info以及print_log_error中。但是如果在上述函數中直接通過logger.*打印日志,日志中的模塊名、行號就會一直打印print_log_info和print_log_error函數中的logger.*中的位置。所以有了追溯函數調用的想法,在打印正常日志時,打印對應模塊名以及打印日志語句的行號。

1.2 使用實例

2.2.1 追溯函數調用推導

        在一個模塊中調用print_log_info函數,在print_log_info函數中調用了trace_caller函數,trace_caller函數定義如下:

import inspectdef trace_caller(laynum):    cur_func_name = inspect.currentframe()    cur_func_name = inspect.getouterframes(cur_func_name, 2)    print(cur_func_name)

打印結果如下:

[(<frame object at 0x04DC2B70>, 'C:\\Users\\Think\\PycharmProjects\\InterfaceFrame\\src\\utils\\utils.py', 19, 'trace_caller', ['    cur_func_name = inspect.currentframe()\n', '    cur_func_name = inspect.getouterframes(cur_func_name, 2)\n'], 1), (<frame object at 0x04DD5380>, 'C:\\Users\\Think\\PycharmProjects\\InterfaceFrame\\src\\utils\\utils.py', 62, 'print_log_info', ['        print(msg) # 在HTMLTestRunner打印測試報告,用例執行成功,不可能觸發斷言,所以需要打印msg\n', '        caller_module, msg_lineno = trace_caller(2)\n'], 1), (<frame object at 0x04B0C6B0>, 'C:/Users/Think/PycharmProjects/InterfaceFrame/src/InterfaceTest.py', 18, '<module>', ['\n', '    utils.print_log_info("最后調用tracecall函數")\n'], 1)]

        可以看到打印結果是一個列表,列表中的元素是三個元組,我們重點從每個元素的第2個元素開始關注,發現分別是調用print(cur_func_name)以及上一級調用語句的模塊所在路徑、代碼行數、函數名、以及打印語句。所以我們根據需要取cur_func_name 對應元素的值就可以達到我們想要的效果了。

1.2.2 代碼示例

def trace_caller(laynum):    '''    根據傳遞的laynum追溯函數調用者所在的模塊、行數。目前只能在打印日志函數中使用    :param laynum:追溯層數,由於在打印日志函數中調用本函數,追溯層數為2,    :return:模塊名, 打印日志所在行號    '''    cur_func_name = inspect.currentframe()    cur_func_name = inspect.getouterframes(cur_func_name, 2)    caller_module = cur_func_name[laynum][1][len(settings.PROJECT_DIR)+1:]    msg_lineno = cur_func_name[laynum][2]    return caller_module, msg_lineno

二、錯誤詳細的日志信息打印

        通過上述方式,可以追溯到函數的調用過程,但最多只能追溯到打印日志的logger.info()等語句。如果想要打印出錯行的代碼,就需要再采用其他方式了。也就是traceback模塊

2.1 traceback模塊介紹

        使用traceback模塊,可以實現對出錯日志的詳細輸出,但是需要結合try except語句來使用,單獨使用會報錯。使用案例如下:

class TestExample(unittest.TestCase):    def test_add(self):        result = Test(2, 2).add()        try:            self.assertEqual(result, 3, "加法錯誤,請重新輸入")            utils.print_log_info("測試成功")        except AssertionError as err:            err_str = traceback.format_exc()            utils.print_log_error(err_str)            raise err

打印日志

2018-04-25 Wednesday 21:48:47 - ERROR -MainThread:42464 - src\test\case\testExample.py : 16     Traceback (most recent call last):  File "C:\Users\Think\PycharmProjects\InterfaceFrame\src\test\case\testExample.py", line 12, in test_add    self.assertEqual(result, 3, "加法錯誤,請重新輸入")  File "C:\Python33\lib\unittest\case.py", line 641, in assertEqual    assertion_func(first, second, msg=msg)  File "C:\Python33\lib\unittest\case.py", line 634, in _baseAssertEqual    raise self.failureException(msg) AssertionError: 4 != 3 : 加法錯誤,請重新輸入

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM