您好,登錄后才能下訂單哦!
這篇文章主要講解了“python logging日志模塊怎么用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“python logging日志模塊怎么用”吧!
說到日志,無論是寫框架代碼還是業務代碼,都離不開日志的記錄,他能給我們定位問題帶來極大的幫助。
記錄日志最簡單的方法就是在你想要記錄的地方加上一句 print , 我相信無論是新手還是老鳥都經常這么干。在簡單的代碼中或者小型項目中這么干一點問題都沒有。但是在一些稍大一點的項目,有時候定位一個問題,需要查看歷史日志定位問題,用print就不合時宜了。
print
打印出來的日志沒有時間,不知道日志記錄的位置,也沒有可讀的日志格式, 還不能把日志輸出到指定文件。。。。除非這些你都全部自己重復造一遍輪子。
最佳的做法是使用內置的logging模塊, 因為 logging
模塊給開發者提供了非常豐富的功能。
比如上圖就是用標準庫logging
模塊記錄生成的日志,有日志的具體時間、日志發生的模塊、有日志級別和日志的具體內容等等
怎么用呢,來看個例子:
導入logging
模塊,然后直接使用logging提供的日志消息記錄方法就可以。
日志級別分為以下5個級別
日志級別 | 使用場景 |
---|---|
DEBUG | debug級別用來記錄詳細的信息,方便定位問題進行調試,在生產環境我們一般不開啟DEBUG |
INFO | 用來記錄關鍵代碼點的信息,以便代碼是否按照我們預期的執行,生產環境通常會設置INFO級別 |
WARNING | 記錄某些不預期發生的情況,如磁盤不足 |
ERROR | 由于一個更嚴重的問題導致某些功能不能正常運行時記錄的信息 |
CRITICAL | 當發生嚴重錯誤,導致應用程序不能繼續運行時記錄的信息 |
日志級別重要程度逐次提高,python提供了5個對應級別的方法。默認情況下日志的級別是WARGING, 低于WARING
的日志信息都不會輸出。
從上面代碼中可以看到loging.warging以后的日志內容都打印在標準輸出流,也就是命令行窗口,但是logging.debug
和info記錄的日志不會打印出來。
如何讓debug級別的信息也輸出?
當然是修改默認的日志級別,在開始記錄日志前可以使用logging.basicConfig
方法來設定日志級別
import logging logging.basicConfig( level=logging.DEBUG) logging.debug("this is debug") logging.info("this is info") logging.error("this is error")
設置為debug
級別后,所有的日志信息都會輸出
DEBUG:root:this is debug INFO:root:this is info ERROR:root:this is error
前面的日志默認會把日志輸出到標準輸出流,就是只在命令行窗口輸出,程序重啟后歷史日志沒地方找,所以把日志內容永久記錄是一個很常見的需求。同樣通過配置函數logging.basicConfig
可以指定日志輸出到什么地方
import logging logging.basicConfig(filename="test.log", level=logging.INFO) logging.debug("this is debug") logging.info("this is info") logging.error("this is error")
這里我指定日志輸出到文件test.log
中,日志級別指定為了 INFO,最后文件中記錄的內容如下:
INFO:root:this is info ERROR:root:this is error
每次重新運行時,日志會以追加的方式在后面, 如果每次運行前要覆蓋之前的日志,則需指定 filemode='w', 這個和 open 函數寫數據到文件用的參數是一樣的。
默認輸出的格式包含3部分,日志級別,日志記錄器的名字,以及日志內容,中間用“:”連接。如果我們想改變日志格式,例如想加入日期時間、顯示日志器名字,我們是可以指定format
參數來設置日志的格式
import logging logging.basicConfig(format='%(asctime)s %(levelname)s %(name)s %(message)s') logging.error("this is error")
輸出:
2021-12-15 07:44:16,547 ERROR root this is error
日志格式化輸出提供了非常多的參數,除了時間、日志級別、日志消息內容、日志記錄器的名字外,還可以指定線程名,進程名等等
到這里為止,日志模塊的基本用法就這些了,也能滿足大部分應用場景,更高級的方法接著往下看,可以幫助你更好的處理日志
前面介紹的日志記錄,其實都是通過一個叫做日志記錄器(Logger
)的實例對象創建的,每個記錄器都有一個名稱,直接使用logging
來記錄日志時,系統會默認創建 名為 root 的記錄器,這個記錄器是根記錄器。記錄器支持層級結構,子記錄器通常不需要單獨設置日志級別以及Handler
(后面會介紹),如果子記錄器沒有單獨設置,則它的行為會委托給父級。
記錄器名稱可以是任意名稱,不過最佳實踐是直接用模塊的名稱當作記錄器的名字。
命名如下:
logger = logging.getLogger(__name__)
默認情況下,記錄器采用層級結構,上句點作為分隔符排列在命名空間的層次結構中。層次結構列表中位于下方的記錄器是列表中較高位置的記錄器的子級。例如,有個名叫 foo 的記錄器,而名字是 foo.bar
,foo.bar.baz
,和foo.bam
的記錄器都是 foo 的子級。
├─foo
│ │ main.py
│ │ __init__.py
│ │
│ ├─bam
│ │ │ __init__.py
│ │ │
│ │
│ ├─bar
│ │ │ __init__.py
│ │ │
│ │ ├─baz
│ │ │ │ __init__.py
│ │ │ │
main.py:
import foo from foo import bar from foo import bam from foo.bar import baz if __name__ == '__main__': pass
foo.py
import logging logging.basicConfig() logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) logger.info("this is foo")
這里我只設置foo這個記錄器的級別為INFO
bar.py
import logging logger = logging.getLogger(__name__) logger.info("this is bar")
其它子模塊都是像bar.py一樣類似的代碼,都沒有設置日志級別,最后的輸出結果是
INFO:foo:this is foo INFO:foo.bar:this is bar INFO:foo.bam:this is bam INFO:foo.bar.baz:this is baz
這是因為 foo.bar 這個記錄器沒有設置日志級別,就會向上找到已經設置了日日志級別的祖先,這里剛好找到父記錄器foo的級別為INFO,如果foo也沒設置的話,就會找到根記錄器root,root默認的級別為WARGING。
記錄器負責日志的記錄,但是日志最終記錄在哪里記錄器并不關心,而是交給了另一個家伙--處理器(Handler)去處理。
例如一個Flask項目,你可能會將INFO級別的日志記錄到文件,將ERROR級別的日志記錄到標準輸出,將某些關鍵日志(例如有訂單或者嚴重錯誤)發送到某個郵件地址通知老板。這時候你的記錄器添加多個不同的處理器來處理不同的消息日志,以此根據消息的重要性發送的特定的位置。
Python內置了很多實用的處理器,常用的有:
1、StreamHandler 標準流處理器,將消息發送到標準輸出流、錯誤流
2、FileHandler 文件處理器,將消息發送到文件
3、RotatingFileHandler 文件處理器,文件達到指定大小后,啟用新文件存儲日志
4、TimedRotatingFileHandler 文件處理器,日志以特定的時間間隔輪換日志文件
Handler
提供了4個方法給開發者使用,細心的你可以發現了,logger可以設置level,Handler也可以設置Level。通過setLevel可以將記錄器記錄的不同級別的消息發送到不同的地方去。
import logging from logging import StreamHandler from logging import FileHandler logger = logging.getLogger(__name__) # 設置為DEBUG級別 logger.setLevel(logging.DEBUG) # 標準流處理器,設置的級別為WARAING stream_handler = StreamHandler() stream_handler.setLevel(logging.WARNING) logger.addHandler(stream_handler) # 文件處理器,設置的級別為INFO file_handler = FileHandler(filename="test.log") file_handler.setLevel(logging.INFO) logger.addHandler(file_handler) logger.debug("this is debug") logger.info("this is info") logger.error("this is error") logger.warning("this is warning")
運行后,在命令行窗口輸出的日志內容是:
this is error this is warning
輸出在文件的日志內容是:
this is info this is error this is warning
盡管我們將logger的級別設置為了DEBUG,但是debug記錄的消息并沒有輸出,因為我給兩個Handler設置的級別都比DEBUG要高,所以這條消息被過濾掉了。
格式器在文章的前面部分其實已經有所介紹,不過那是通過logging.basicConfig來指定的,其實格式器還可以以對象的形式來設置在Handler上。格式器可以指定日志的輸出格式,要不要展示時間,時間格式什么,要不要展示日志的級別,要不要展示記錄器的名字等等,都可以通過一個格式器對消息進行格式化輸出。
import logging from logging import StreamHandler logger = logging.getLogger(__name__) # 標準流處理器 stream_handler = StreamHandler() stream_handler.setLevel(logging.WARNING) # 創建一個格式器 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 作用在handler上 stream_handler.setFormatter(formatter) # 添加處理器 logger.addHandler(stream_handler) logger.info("this is info") logger.error("this is error") logger.warning("this is warning")
注意:格式器只能作用在處理器上,通過處理器的setFromatter方法設置格式器。而且一個Handler只能設置一個格式器。是一對一的關系。而 logger 與 handler 是一對多的關系,一個logger可以添加多個handler。handler 和 logger 都可以設置日志的等級。
回到最開始的地方,logging.basicConfig()
方法為我們干了啥?現在你大概能猜出來了。來看python源碼中是怎么說的
Do basic configuration for the logging system.
This function does nothing if the root logger already has handlers configured. It is a convenience method intended for use by simple scripts to do one-shot configuration of the logging package.
The default behaviour is to create a StreamHandler which writes to sys.stderr, set a formatter using the BASIC_FORMAT format string, and add the handler to the root logger.
A number of optional keyword arguments may be specified, which can alter the default behaviour.
1、創建一個root記錄器
2、設置root的日志級別為warning
3、為root記錄器添加StreamHandler處理器
4、為處理器設置一個簡單格式器
logging.basicConfig() logging.warning("hello")
這兩行代碼其實就等價于:
import sys import logging from logging import StreamHandler from logging import Formatter logger = logging.getLogger("root") logger.setLevel(logging.WARNING) handler = StreamHandler(sys.stderr) logger.addHandler(handler) formatter = Formatter(" %(levelname)s:%(name)s:%(message)s") handler.setFormatter(formatter) logger.warning("hello")
logging.basicConfig 方法做的事情是相當于給日志系統做一個最基本的配置,方便開發者快速接入使用。它必須在開始記錄日志前調用。不過如果 root 記錄器已經指定有其它處理器,這時候你再調用basciConfig,則該方式將失效,它什么都不做。
日志的配置除了前面介紹的將配置直接寫在代碼中,還可以將配置信息單獨放在配置文件中,實現配置與代碼分離。
日志配置文件 logging.conf
[loggers] keys=root [handlers] keys=consoleHandler [formatters] keys=simpleFormatter [logger_root] level=DEBUG handlers=consoleHandler [handler_consoleHandler] class=StreamHandler level=DEBUG formatter=simpleFormatter args=(sys.stdout,) [formatter_simpleFormatter] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
加載配置文件
import logging import logging.config # 加載配置 logging.config.fileConfig('logging.conf') # 創建 logger logger = logging.getLogger() # 應用代碼 logger.debug("debug message") logger.info("info message") logger.warning("warning message") logger.error("error message")
輸出:
2021-12-23 00:02:07,019 - root - DEBUG - debug message
2021-12-23 00:02:07,019 - root - INFO - info message
2021-12-23 00:02:07,019 - root - WARNING - warning message
2021-12-23 00:02:07,019 - root - ERROR - error message
感謝各位的閱讀,以上就是“python logging日志模塊怎么用”的內容了,經過本文的學習后,相信大家對python logging日志模塊怎么用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。