成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么Pycharm輸出的日志全部是紅色!

開發 后端
如果未在記錄器上顯式設置級別,則使用其父記錄器的級別作為其有效級別。如果父記錄器也沒有設置級別,則依此類推,搜索父級的父級,直到找到明確設置了級別的記錄器。

在上一篇文章1萬字詳解 python logging日志模塊 中,深入淺出的講解了日志的基本原理與用法。但還有一些內容并沒有涉及到,所以這篇文章作為上一篇文章的補充。

希望這兩篇文章能幫助你完全理解日志模塊的使用,在項目中對日志的運用游刃有余。上一篇還沒看的建議先閱讀上一篇

1、為什么子記錄器不需要設置日志等級也可以輸出?

如果未在記錄器上顯式設置級別,則使用其父記錄器的級別作為其有效級別。如果父記錄器也沒有設置級別,則依此類推,搜索父級的父級,直到找到明確設置了級別的記錄器。根記錄器默認下為 WARNING 級別

  1. import logging 
  2.  
  3. parent = logging.getLogger("parent"
  4. parent.setLevel(logging.INFO) 
  5. parent.addHandler(logging.StreamHandler()) 
  6.  
  7. child = logging.getLogger("parent.child"
  8. child.info("msg"

輸出

  1. msg 

這里我沒有給child設置日志等級,他會從父記錄器查找日志級別,所以child也可以輸出info級別的日志。關于記錄器的繼承關系可以參考第一篇文章

2、為什么有時候日志會輸出兩次?

看下面例子:

  1. import logging 
  2.  
  3. # 初始化日志,并設置日志級別(為root設置為DEBUG級別,關聯StreamHandler,設置BASIC_FORMAT格式) 
  4. logging.basicConfig(level=logging.DEBUG) 
  5.  
  6. # 定義root記錄器 
  7. root = logging.getLogger() 
  8.  
  9. # 定義child記錄器 
  10. child = logging.getLogger("child"
  11. console_handler = logging.StreamHandler() 
  12. # 給child綁定處理器 
  13. child.addHandler(console_handler) 
  14. # 記錄一條info日志 
  15. child.info("child info"

輸出

  1. child info 
  2. INFO:child:child info 

代碼中明明只記錄了一次日志,卻輸出了兩次,而且兩次的日志格式不一樣。這是因為 child 這個記錄器添加了一個叫console_handler的處理器, 而root根記錄器默認也帶有自己的處理器(也是StreamHandler實例)

  1. print(root.handlers) # [<StreamHandler <stderr> (NOTSET)>] 

根據python中日志模塊的處理機制,子記錄器記錄的消息會自動傳播給父級記錄器的關聯的處理器。所以在這個例子中,child記錄的消息除了會發給自己的handler外,還是傳播給root記錄器的handler,因此最終輸出了兩次,流程圖如下

logging-flow.png

如果不希望子記錄器記錄的消息傳播給父級記錄器,可以設置記錄器的屬性propagate為False,關閉傳播。

  1. child.propagate = False 

如此一來,最終輸出到終端的日志就只有child自己的處理器輸出的記錄

  1. child info 

配置處理器的最佳實踐是給頂級記錄器配置處理器,再根據需要創建子記錄器, 因為記錄最終都會傳播給父記錄器

  1. import logging 
  2.  
  3. parent = logging.getLogger("parent"
  4. parent.setLevel(logging.DEBUG) 
  5. parent.addHandler(logging.StreamHandler()) 
  6.  
  7. # 不需要給子記錄器單獨配置handler 
  8. child = logging.getLogger("parent.child"
  9. child.info("msg"

對于日志的流程處理,python官方文檔畫了一張更為細致的流程圖,可以參考

logging_flow.png

第一次看估計有點暈,但先看我畫的這張圖再來看這張圖,你就能懂了,為了簡化我省去了過濾器以及不斷循環查找父級記錄器的這個流程。

3、 為什么我的pycharm中輸出的日志是紅色?

不知道你的pycharm輸出的日志不管是info信息還是error信息,反正都是紅色,一看以為整屏都是錯誤。

把下面代碼放在Pycharm運行看效果:

  1. import logging 
  2. logging.basicConfig(level=logging.DEBUG) 
  3. logging.info("hello"

這是因為使用root記錄器記錄日志時,默認配置的handler是一個StreamHandler。

我們打開StreamHandler的源碼

  1. class StreamHandler(Handler): 
  2.     ""
  3.     A handler class which writes logging records, appropriately formatted, 
  4.     to a stream. Note that this class does not close the stream, as 
  5.     sys.stdout or sys.stderr may be used. 
  6.     ""
  7.  
  8.     terminator = '\n' 
  9.  
  10.     def __init__(self, stream=None): 
  11.         ""
  12.         Initialize the handler. 
  13.  
  14.         If stream is not specified, sys.stderr is used. 
  15.         ""
  16.         Handler.__init__(self) 
  17.         if stream is None: 
  18.             stream = sys.stderr 
  19.         self.stream = stream 

初始化這個Handler時,會接收一個stream的參數,如果不傳,默認就使用的系統標準錯誤流(sys.stderr)輸出,pycharm對錯誤流輸出的字體樣式做了紅色渲染,如果換成 sys.stdout 輸出的就不再紅色了。

  1. import logging 
  2. import sys 
  3.  
  4. handler = logging.StreamHandler(stream=sys.stdout) 
  5. logging.basicConfig(level=logging.DEBUG, handlers=[handler]) 
  6.  
  7. # 或者指定stream參數 
  8. # logging.basicConfig(level=logging.DEBUG, stream=sys.stdout) 
  9.  
  10. logging.info("hello"

4、怎么生成以日期時間命名的日志?

實際應用中,我們會對日志進行歸檔存儲,每天生成一份日志,如果哪天出了問題,也方便定位,直接找到當天的日志文件就可以分析。我們只需要給logger添加一個TimedRotatingFileHandler處理器就行。

  1. file_handler = TimedRotatingFileHandler(‘'logs/api.log'), 
  2.                                             when="D", interval=1, backupCount=10, 
  3.                                             encoding="UTF-8", delay=False, utc=True
  4. formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'
  5. file_handler.setFormatter(formatter) 
  6. file_handler.setLevel(logging.INFO) 
  7. logger.addHandler(file_handler) 

5、為什么我日志配置后不生效?

可能跟程序的加載順序有關,看個例子

  1. import logging 
  2.  
  3. logger = logging.getLogger() 
  4. handler = logging.StreamHandler() 
  5. logger.addHandler(handler) 
  6. logger.info("hello1"
  7.  
  8. logger.setLevel(logging.INFO) 
  9. logger.info("hello2"

像上面的代碼最后只輸出了hello2,不過實際場景中,代碼沒這么簡單,通常是在a模塊中的某個函數中初始化日志框架配置, 在b模塊外層創建了名字叫 logger_b的記錄器,然后在a中導入b模塊時,這時候日志配置還沒初始化,最后導致logger_b的配置就成了默認配置。所以有可能出現日志不生效的情況。

 

因此最佳實踐是能盡早初始化日志配置就盡早提前。

 

責任編輯:武曉燕 來源: Python之禪
相關推薦

2022-06-02 08:03:19

PyCharmPython代碼

2018-11-30 10:54:29

交換機維護IT維保

2020-07-16 15:17:32

物聯網工業IOT

2021-01-12 10:00:34

流式輸出數據

2022-08-08 08:04:17

Javastatic編程

2024-07-01 10:16:55

搜索向量數據類型

2012-08-01 14:04:46

Surface

2017-09-20 07:57:38

AWG電纜導線

2020-07-29 07:05:00

DevSecOps

2022-03-14 08:33:09

TypeScriptJavaScript前端

2020-03-25 13:58:00

汽車智能物聯網

2020-07-03 14:05:26

Serverless云服務商

2021-11-29 18:27:12

Web Wasmjs

2024-04-24 07:00:00

Redis架構數據持久化

2013-09-11 17:02:40

紅帽OpenStack

2023-11-20 22:26:51

Go開發

2022-03-31 09:00:47

高并發Log4j2java

2018-01-31 14:50:04

LinuxmacOS .bashrc

2021-10-21 05:30:48

Data Fabric數據管理架構邊緣計算

2024-10-18 11:55:47

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美久久视频 | 久久这里只有精品首页 | 精品一二三区视频 | 久久精品日产第一区二区三区 | 日日夜夜精品视频 | 日日操夜夜操天天操 | 久久av一区二区三区 | 午夜精品视频在线观看 | 九七午夜剧场福利写真 | 日本高清中文字幕 | 毛片av免费看 | 日韩欧美专区 | 国产av毛片| 国产成人精品久久久 | 91精品国产一区二区在线观看 | av一区二区三区在线观看 | 亚洲精精品 | 久久成人一区 | 国产精品久久久久久久久久东京 | 一区二区三区日韩精品 | 国产精品久久国产精品 | 青青草一区二区三区 | 黄色成人在线网站 | 亚洲人成在线观看 | 91大神在线看 | 国产精品毛片无码 | 欧美国产免费 | 国产亚洲精品综合一区 | 国精品一区二区 | 亚洲精品一区在线观看 | 欧美极品一区二区 | 国产ts人妖一区二区三区 | 亚洲精品免费在线 | 97免费在线观看视频 | 色射综合 | 色黄视频在线 | 天天综合网永久 | 伊人春色成人 | 国产成人91视频 | 在线免费黄色小视频 | 国产精品久久久久久久久久免费看 |