Python Logging原來真的遠比我想象的要復雜很多很多,學習路線堪比git。但是又繞不過去,alternatives又少,所以必須要予以重視,踏踏實實認認真真的來好好學學才行。
學習Logging的目的:
簡單腳本還好,print足夠。
但是稍微復雜點,哪怕是三四個文件加起來兩三百行代碼,調試也開始變復雜起來了。
再加上如果是后臺長期運行的那種腳本,運行信息的調查更是復雜起來。
一開始我還在各種查crontab的日志查看,或者是python后臺運行查看,或者是python stdout的獲取等等,全都找錯了方向。
真正的解決方案在于正確的logging。
記錄好了的話,我不需要去找python的控制臺輸出stdout,也不需要找crontab的日志,只需要查看log文件即可。
下面是python的logging學習記錄。
import logging logging.error("出現了錯誤") logging.info("打印信息") logging.warning("警告信息")首先,忘掉logging.info()! 忘掉logging.basicConfig()!
網上各種關于python logging的文章實在是太不體諒新手了,logging這么復雜的東西竟然想表現得很簡單,還用各種簡單的東西做假象。
實際上我們真正要用起來的日志,絕對是不會直接用logging.info()和logging.basicConfig()這樣的,這是此模塊的官方推出來迷惑人的——看似讓你一鍵上手,快速看到結果,但是跟實際真的不搭!
所以為了后面解釋起來輕松,必須先警告這點:忘記它們倆!
記住,唯一要用到logging.什么的,就只有logging.getLogger()這一次。
不想上流程圖一類的東西,那樣反而更迷糊。
簡單說吧:
logging模塊是會自動將你自定制的logger對象全局化的,
也就是說,
你在自己的模塊里只要定義了一次某個logger,比如叫log,那么只要是在同一個模塊中運行的其他文件都能讀取到它。
比如說,你在主文件main.py中自定義了一個logger,可能設置了什么輸出文件、輸出格式什么的,然后你在main.py中會引用一些別的文件或模塊,比如sub.py,那么在這個sub.py中你什么都不用設置,只要用一句logger = logging.getLogger("之前在main.py定義的日志名")即可獲得之前的一切自定義設置。
當然,被調用的文件(先稱為子模塊)中,用logging.getLogger("日志名")時,最好在日志名后加一個.子名稱這樣的,比如main.sub。這樣輸出的時候就會顯示出來某條日志記錄是來自于這個文件里了。當然,.前面的父級logger必須名字一致,是會被識別出來的!
然后,子日志還可以再子日志,甚至一個子模塊可以再讓所有函數各又一個子子日志,比如main.sub.func1這樣的。logging都會根據.識別出來上下級關系的。
這樣一說,實際上也就是class類繼承的那種機制了。你按照父級名稱繼承,然后還可以改寫自己的新設置等。
了解了這些概念以后,才能來談代碼。實際上也就好理解多了。
設置logger的方法看來看去,這篇文章說得比較全面也最清楚,以下很多都參考到它的內容:Python 101: An Intro to logging
一般想要自定義一個logger,比如讓它輸出信息時按照什么格式顯示,輸出到哪個文件,要不要輸出到屏幕一類,有三種方法可以達到設置:
直接在python代碼里設置
用外部的config.ini文件配置
用python的dict字典配置
三種達到的目的都是一樣的,字典用的人很少也不方便,配置文件比較好用只是.ini的語法不是很方便讀,且不容易做到變量的動態設置,所以一般直接在python代碼里寫就好。
常用設置語句以下是程序主入口文件的通用寫法,注意,一定要在主入口定義好logger,這樣其他所有的子模塊才能夠繼承到。
# main.py import logging import otherMod2 # 等下會調用到的子模塊 def main(): """ 這個文件是程序的主入口 """ define_logger() log = logging.getLogger("exampleApp") # 輸出信息測試 logger.info("Program started") result = otherMod2.add(7, 8) # 這個是來自別的模塊的方法 logger.info("Done!") def define_logger(): logger = logging.getLogger("exampleApp") logger.setLevel(logging.INFO) # 設置輸出格式 formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") # 設置日志文件處理器 fh = logging.FileHandler("new_snake.log") fh.setFormatter(formatter) # 為這個處理器添加格式 # 設置屏幕stdout輸出處理器 sh = logging.StreamHandler(stream=None) sh.setFormatter(formatter) # 把處理器加到logger上 logger.addHandler(fh) logger.addHandler(sh) if __name__ == "__main__": main()
下面是子模塊中的調用方法(很簡單):
# otherMod2.py import logging module_logger = logging.getLogger("exampleApp.otherMod2") def add(x, y): # 這里一句`getLogger`就繼承到父級的logger了 logger = logging.getLogger("exampleApp.otherMod2.add") # 輸出測試 logger.info("added %s and %s to get %s" % (x, y, x+y)) return x+y
注意,主文件中,在什么地方定義logger都可以,可以在main()里也可以在任何多帶帶的函數或類里,無所謂。只要在調用子模塊之前定義好了就可以了。一旦定義過,日志名就會被記下來,然后子模塊就可以輕松繼承到。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/41813.html
摘要:每一條日志記錄也包含級別,代表對應消息的嚴重程度。即格式化器,主要功能是確定最終輸出的形式和內容。最好是日志能夠按自然天進行記錄和分割。 上一章學習了自動化測試,很好,現在我們可以絞盡腦汁寫出一份全面的測試,來保證代碼永遠健康了。 話雖如此,但是作為一個獨立開發者很難寫出真正全面的測試代碼。這是因為用戶在使用你的網站時可不會循規蹈矩,而是會以各種怪異的姿勢瀏覽網頁、上傳數據。但這也不是...
摘要:例如,控制臺使用調用類型,因此當您使用控制臺調用函數時,控制臺將顯示返回的值。如果別名用于調用函數,將為別名指向的版本。 場景:現在需要開發一個前后端分離的應用,后端采用 RESTful API 最為方便,但是如果這個后端服務會在一天中的某些時候有高并發的情況,使用什么樣的架構最為簡單呢? 剛思考這個問題的時候我想到的解決方案可能有以下幾種: 使用CDN內容分發網絡,減少主服務器的...
摘要:用于便捷記錄日志且線程安全的模塊日志級別日志一共分成個等級,從低到高分別是。詳細的信息通常只出現在診斷問題上確認一切按預期運行一個跡象表明一些意想不到的事情發生了或表明一些問題在不久的將來例如。這個等級,也分別對應種打日志的方法。 用于便捷記錄日志且線程安全的模塊 1、日志級別 日志一共分成5個等級,從低到高分別是:DEBUG INFO WARNING ERROR CRITICAL。D...
摘要:上一篇文章模塊分析第節模塊一日志記錄的級別優先級,記錄調試的詳細信息,只在調試時開啟優先級,記錄普通的消息,報告錯誤和警告等待。監聽端口號上一篇文章模塊分析第節模塊 上一篇文章:Python模塊分析:第3節-typing模塊 一、日志記錄的級別 debug:優先級10,記錄調試的詳細信息,只在調試時開啟 info:優先級20,記錄普通的消息,報告錯誤和警告等待。 warning:優...
摘要:模塊簡介的模塊提供了靈活的日志處理相關功能可以用來追蹤程序運行的情況。模塊設置的默認等級時這意味著默認情況下,日志級別為的日志會被記錄,而的日志會被忽略。線程安全模塊是通過線程鎖保證線程安全的。 Logging 模塊 簡介 Python的 logging 模塊提供了靈活的日志處理相關功能, 可以用來追蹤程序運行的情況。 logging 模塊提供了一系列標準的日志等級: DEBUG,...
閱讀 3118·2021-11-23 09:51
閱讀 1982·2021-09-09 09:32
閱讀 1092·2019-08-30 15:53
閱讀 2964·2019-08-30 11:19
閱讀 2473·2019-08-29 14:15
閱讀 1441·2019-08-29 13:52
閱讀 559·2019-08-29 12:46
閱讀 2826·2019-08-26 12:18