django 日誌系統
我的程式碼:
1.settings.py檔案中
#django日誌系統 LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'filters': { 'require_debug_true': { '()': 'django.utils.log.RequireDebugTrue', }, # 針對 DEBUG = True 的情況 }, 'formatters': { 'standard': { 'format': '%(levelname)s %(asctime)s %(pathname)s %(filename)s %(module)s %(funcName)s %(lineno)d: %(message)s'}, # 對日誌資訊進行格式化,每個欄位對應了日誌格式中的一個欄位,更多欄位參考官網文件,我認為這些欄位比較合適,輸出類似於下面的內容 # INFO 2016-09-03 16:25:20,067 /home/ubuntu/mysite/views.py views.py views get 29: some info... }, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler', 'formatter':'standard' },'file_handler': { 'level': 'DEBUG', 'class': 'logging.handlers.TimedRotatingFileHandler', 'filename': os.path.join(BASE_DIR, "logging\\test.log"), #網上的報錯,改成相對路徑 'formatter':'standard' }, # 用於檔案輸出 'console':{ 'level': 'INFO', 'filters': ['require_debug_true'], 'class': 'logging.StreamHandler', 'formatter': 'standard' }, }, 'loggers': { 'django': { 'handlers' :['file_handler', 'console'], 'level':'DEBUG', 'propagate': True # 是否繼承父類的log資訊 }, # handlers 來自於上面的 handlers 定義的內容 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': False, }, } }
2.在views.py中呼叫,不知道是不是每個都需要呼叫,暫時都呼叫了
#記錄日誌 import logging logger = logging.getLogger("django") # 為loggers中定義的名稱 logger.info("some info...")
3.得到了報錯日誌,該檔案下有所有的資訊。
4.若想單獨列印bug資訊,則需要根據對應的函式自己寫try except然後打日誌。這步還沒做。
另外一篇簡單的配置博文:
http://blog.csdn.net/novostary/article/details/52424116
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'
}
},