Free Style】基于華為CCE微服務改造的技術實踐(二)">【Free Style】基于華為CCE微服務改造的技術實踐(二)
793
2025-03-31
使用 python 的標準日志模塊
那么,怎么樣記錄日志才是正確的呢?其實非常簡單,使用 python 的標準日志模塊。多虧 python 社區將日志做成了一個標準模塊。它非常簡單易用且十分靈活。你可以像這樣使用日志系統:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
logger.info('Start reading database')
# read database here
records = {'john': 55, 'tom': 66}
logger.debug('Records: %s', records)
logger.info('Updating records ...')
# update records here
logger.info('Finish updating records')
運行的時候就可看到:
Python
1
2
3
INFO:__main__:Start reading database
INFO:__main__:Updating records ...
INFO:__main__:Finish updating records
你可能會問這與使用 print 有什么不同呢。它有以下的優勢:
你可以控制消息的級別,過濾掉那些并不重要的消息。
你可決定輸出到什么地方,以及怎么輸出。
有許多的重要性別級可供選擇,debug、info、warning、error 以及 critical。通過賦予 logger 或者 handler 不同的級別,你就可以只輸出錯誤消息到特定的記錄文件中,或者在調試時只記錄調試信息。讓我們把 logger 的級別改成 DEBUG 再看一下輸出結果:
Python
1
logging.basicConfig(level=logging.DEBUG)
輸出變成了:
Python
1
2
3
4
INFO:__main__:Start reading database
DEBUG:__main__:Records: {'john': 55, 'tom': 66}
INFO:__main__:Updating records ...
INFO:__main__:Finish updating records
正如看到的那樣,我們把 logger 的等級改為 DEBUG 后,調試記錄就出現在了輸出當中。你也可以選擇怎么處理這些消息。例如,你可以使用 FileHandler 把記錄寫進文件中:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
# create a file handler
handler = logging.FileHandler('hello.log')
handler.setLevel(logging.INFO)
# create a logging format
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
# add the handlers to the logger
logger.addHandler(handler)
logger.info('Hello baby')
標準庫模塊中提供了許多的 handler ,你可以將記錄發送到郵箱甚至發送到一個遠程的服務器。你也可以實現自己的記錄 handler 。這里將不具體講述實現的細節,你可以參考官方文檔:Basci Turial、Advanced Tutorial?與?Logging Cookbook。
以合適的等級輸出日志記錄
有了靈活的日志記錄模塊后,你可以按適當的等級將日志記錄輸出到任何地方然后配置它們。那么你可能會問,什么是合適的等級呢?在這兒我將分享一些我的經驗。
大多數的情況下,你都不想閱讀日志中的太多細節。因此,只有你在調試過程中才會使用 DEBUG 等級。我只使用 DEBUG 獲取詳細的調試信息,特別是當數據量很大或者頻率很高的時候,比如算法內部每個循環的中間狀態。
Python
1
2
3
4
5
def complex_algorithm(items):
for i, item in enumerate(items):
# do some complex algorithm computation
logger.debug('%s iteration, item=%s', i, item)
在處理請求或者服務器狀態變化等日常事務中,我會使用 INFO 等級。
Python
1
2
3
4
5
6
7
8
9
10
11
def handle_request(request):
logger.info('Handling request %s', request)
# handle request here
result = 'result'
logger.info('Return result: %s', result)
def start_service():
logger.info('Starting service at port %s ...', port)
service.start()
logger.info('Service is started')
當發生很重要的事件,但是并不是錯誤時,我會使用 WARNING 。比如,當用戶登錄密碼錯誤時,或者連接變慢時。
Python
1
2
3
4
5
def authenticate(user_name, password, ip_address):
if user_name != USER_NAME and password != PASSWORD:
logger.warn('Login attempt to %s from IP %s', user_name, ip_address)
return False
# do authentication here
有錯誤發生時肯定會使用 ERROR 等級了。比如拋出異常,IO 操作失敗或者連接問題等。
Python
1
2
3
4
5
6
def get_user_by_id(user_id):
user = db.read_user(user_id)
if user is None:
logger.error('Cannot find user with user_id=%s', user_id)
return user
return user
我很少使用 CRITICAL 。當一些特別糟糕的事情發生時,你可以使用這個級別來記錄。比方說,內存耗盡,磁盤滿了或者核危機(希望永遠別發生 :S)。
華為云
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。