18:django 日志系統


django使用python內建的logging模塊去建造自己的系統日志的,如果你想詳細了解這個模塊的話,請自己去看python的說明文檔,這里僅僅介紹django中的日志系統

日志配置包括四個部分:記錄器,處理器,過濾器和格式器,下面我們來一一講解

記錄器

一個記錄器是日志系統的一個實體,每一個記錄器是一個已經命名好的可以將消息為進程寫入的“桶”。

每一個記錄器都會有一個日志等級,每個等級描述了記錄器即將處理的信息的嚴重性,python定義了以下五個等級:

debug:出於調試目的的低層次系統信息

  • info:普通的系統信息
  • warning:描述已經發生的小問題
  • error:描述已經發生的主要問題
  • critical:描述已經發生的嚴重問題

每一條被寫入記錄器的信息成為一條日志記錄,每條日志記錄都有一個表明該記錄嚴重性的日志等級,每條日志信息也會包含一些有用的元信息表明已經被記錄的事件,比如棧追溯和錯誤代碼。

當一條信息被發往記錄器的時候,消息的記錄等級會和記錄器的等級相比較,如果符合甚至超越當前等級,則被發往處理器處理,否則會被忽略掉。

處理器

處理器是決定日志記錄器中對應的實體消息發生了什么的引擎,描述了一個具體的日志行為,比如輸出到屏幕,或者一個文件,抑或一個網絡socket。

和記錄器一樣,沒有到達相應等級的消息會被忽略。

一個記錄器可以有多個處理器,一個處理器可以有不同的日志等級,因此你可以根據消息的重要性而提供不同的提示。

過濾器

過濾器是用來提供額外的控制,控制哪些日志記錄可以被傳給處理器處理。

默認情況下,只要日志消息符合相應的等級要求就會傳給對應的處理器處理,然而,通過安裝過濾器,你可以在日志記錄過程中設置額外的內容,例如,你可以安裝一個過濾器使得某個源只有error級別的消息才會被發送。你也可以使用過濾器修改之前會被發送的消息,例如,你可以寫一個過濾器使得符合某些條件的error等級的消息降級為warning等級。

過濾器可以給處理器和記錄器使用,多個過濾器可以級聯使用。

格式器

控制日志輸出的格式,格式使用python的字符串控制格式

使用日志

一旦配置好你的記錄器,處理器,過濾器和格式器,你需要在你的代碼中調用日志功能,下面是一個簡單的例子:

復制代碼
# import the logging library import logging # Get an instance of a logger logger = logging.getLogger(__name__) def my_view(request, arg1, arg): ... if bad_mojo: # Log an error message logger.error('Something went wrong!')
復制代碼

 

命名你的記錄器

logging.getLogger()的調用獲得一個記錄器的實體,記錄器實體通過名字來辨別。

像上面的那個例子,一般是使用__name__,包含記錄器的python模塊的名字,這使得基於每個模塊的記錄成為可能

或者你可以是用點號相連的名字,這意味着記錄器的層次,點號之前的是點號之后的父模塊,例如

# Get an instance of a specific named logger logger = logging.getLogger('project.interesting.stuff')

 

這種方式也很重要,因為通過層次,子層次的消息可以把消息發送給自己的父層次,如果你不想把消息發給你的父層次,記得把發送開關關閉掉。(下面會有介紹到)

日志調用

對應日志的五個等級,日志調用有五個對應的方法:

  • logger.critical()
  • logger.error()
  • logger.warning()
  • logger.info()
  • logger.debug()

還有兩個可用的日志方法可以調用:

  • logger.log():手工發送一個具體等級的日志消息
  • logger.exception():創建一個error等級的封裝着異常堆棧幀內容的日志消息

配置日志系統

在代碼中調用日志的前提是已經配置好了日志系統的記錄器,處理器,過濾器和格式器,我們通過一個復雜的例子來詳細講解吧:

復制代碼
LOGGING = {
    'version': 1,#指明dictConnfig的版本,目前就只有一個版本,哈哈 'disable_existing_loggers': True,#禁用所有的已經存在的日志配置 'formatters': {#格式器 'verbose': {#詳細 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' }, 'simple': {#簡單 'format': '%(levelname)s %(message)s' }, }, 'filters': {#過濾器 'special': {#使用project.logging.SpecialFilter,別名special,可以接受其他的參數 '()': 'project.logging.SpecialFilter', 'foo': 'bar',#參數,名為foo,值為bar  } }, 'handlers': {#處理器,在這里定義了三個處理器 'null': {#Null處理器,所有高於(包括)debug的消息會被傳到/dev/null 'level':'DEBUG', 'class':'django.utils.log.NullHandler', }, 'console':{#流處理器,所有的高於(包括)debug的消息會被傳到stderr,使用的是simple格式器 'level':'DEBUG', 'class':'logging.StreamHandler', 'formatter': 'simple' }, 'mail_admins': {#AdminEmail處理器,所有高於(包括)而error的消息會被發送給站點管理員,使用的是special格式器 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler', 'filters': ['special'] } }, 'loggers': {#定義了三個記錄器 'django': {#使用null處理器,所有高於(包括)info的消息會被發往null處理器,向父層次傳遞信息 'handlers':['null'], 'propagate': True, 'level':'INFO', }, 'django.request': {#所有高於(包括)error的消息會被發往mail_admins處理器,消息不向父層次發送 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': False, }, 'myproject.custom': {#所有高於(包括)info的消息同時會被發往console和mail_admins處理器,使用special過濾器 'handlers': ['console', 'mail_admins'], 'level': 'INFO', 'filters': ['special'] } } }
復制代碼

 

相信看完這個例子,對日志系統的配置大家基本了解了吧

循環導入問題

如果你自定義了一個處理器,然后再settings.py文件有配置,如果這是你在類實現文件里面導入settings模塊的時候,就會出現循環導入的問題,建議只在settings.py配置文件里面配置

自定義日志配置和禁用日志配置

使用LOGGING_CONFIG屬性自定義和禁用日志配置,LOGGING_CONFIG=None禁用

django日志拓展

django提供三個自帶的記錄器:

django

django記錄器是捕捉所有消息的記錄器,沒有消息是直接發往django記錄器的

django.request

5XX會引發一個error消息,4XX會引發一個warning消息,這個記錄器還附帶有額外的上下文:

  • status_code:HTTP響應嗎
  • request:生成這個消息的request對象

django.db.backens

所有的由請求運行的sql語句都會記錄一條debug的消息,每個記錄器還附帶有額外的上下文:

  • duration:sql語句運行的時間
  • sql:運行的sql語句
  • params:sql語句調用的參數

處於網站運行的表現原因,僅當settings.DEBUG=True的時候,這個處理器才生效,否則即使配置了也無效

除了python模塊自帶的,django自定義了一個處理器

class AdminEmailHandler(include_html=False)

這個處理器每收到一條消息就會發往站點管理員,如果日志信息包含request屬性,那么整個request的詳細信息也會被包包含在Email中發往站點管理員;如果日志信息包含堆棧跟蹤信息,堆棧跟蹤信息也會被發送。

include_html屬性控制當DEBUG為真的時候是否發送那些回溯信息,因為這些都是很敏感的系統系統,如果被人截獲,可能會發生危險,所以要謹慎。配置這個屬性示例如下:

復制代碼
'handlers': { 'mail_admins': { 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler', 'include_html': True, } },
復制代碼

 

除了python自帶的,django提供了兩個自帶的過濾器:

class CallBackFilter(callback)

這個過濾器接受一個回調函數(這個函數接受一個參數,被記錄的信息),每個記錄通過過濾器的時候都會調用這個回調函數,當回調函數返回False的時候,不處理這個記錄。下面是一個示例:

復制代碼
from django.http import UnreadablePostError def skip_unreadable_post(record): if record.exc_info: exc_type, exc_value = record.exc_info[:2] if isinstance(exc_value, UnreadablePostError): return False return True
復制代碼
復制代碼
'filters': { 'skip_unreadable_posts': { '()': 'django.utils.log.CallbackFilter', 'callback': skip_unreadable_post, } }, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'filters': ['skip_unreadable_posts'], 'class': 'django.utils.log.AdminEmailHandler' } },
復制代碼

 

class RequireDebugFalse

這個過濾器僅當settings.DEBUG為False的時候會生效,默認是啟用的,僅當settings.DEBUG=False的時候,AdminEmailHandler才生效

復制代碼
'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse', } }, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler' } },
復制代碼

 


免責聲明!

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



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