日志在程序開發中是少不了的,通過日志我們可以分析到錯誤在什么地方,有什么異常。在生產環境下有很大的用途。在Java開發中通常用log4j,logback等第三方組件。那么在django中是怎么處理日志?django利用的就是Python提供的logging模塊,但django中要用logging,還得有一定的配置規則,需要在setting中設置。下面簡單介紹一下logging。
logging是現成安全的,其主要是由4部分組成:
- Logger 用戶使用的直接接口,將日志傳遞給Handler
- Handler 控制日志輸出到哪里,console,file…
一個logger可以有多個Handler
3.Filter
控制哪些日志可以從logger流向Handler
4.Formatter
控制日志的格式
一、logging模塊
logging模塊為應用程序提供了靈活的手段記錄事件、錯誤、警告和調試信息。對這些信息可以進行收集、篩選、寫入文件、發送給系統日志等操作,甚至還可以通過網絡發送給遠程計算機。
1、日志記錄級別
logging模塊的重點在於生成和處理日志消息。每條消息由一些文本和指示其嚴重性的相關級別組成。級別包含符號名稱和數字值。
級別 | 值 | 描述 |
CRITICAL | 50 | 關鍵錯誤/消息 |
ERROR | 40 | 錯誤 |
WARNING | 30 | 警告消息 |
INFO | 20 | 通知消息 |
DEBUG | 10 | 調試 |
NOTSET | 0 | 無級別 |
2、記錄器
記錄器負責管理日志消息的默認行為,包括日志記錄級別、輸出目標位置、消息格式以及其它基本細節。
關鍵字參數 | 描述 |
filename | 將日志消息附加到指定文件名的文件 |
filemode | 指定用於打開文件模式 |
format | 用於生成日志消息的格式字符串 |
datefmt | 用於輸出日期和時間的格式字符串 |
level | 設置記錄器的級別 |
stream | 提供打開的文件,用於把日志消息發送到文件。 |
3、format 日志消息格式
格式 | 描述 |
%(name)s | 記錄器的名稱 |
%(levelno)s | 數字形式的日志記錄級別 |
%(levelname)s | 日志記錄級別的文本名稱 |
%(filename)s | 執行日志記錄調用的源文件的文件名稱 |
%(pathname)s | 執行日志記錄調用的源文件的路徑名稱 |
%(funcName)s | 執行日志記錄調用的函數名稱 |
%(module)s | 執行日志記錄調用的模塊名稱 |
%(lineno)s | 執行日志記錄調用的行號 |
%(created)s | 執行日志記錄的時間 |
%(asctime)s | 日期和時間 |
%(msecs)s | 毫秒部分 |
%(thread)d | 線程ID |
%(threadName)s | 線程名稱 |
%(process)d | 進程ID |
%(message)s | 記錄的消息 |
4、內置處理器
logging模塊提供了一些處理器,可以通過各種方式處理日志消息。使用addHandler()方法將這些處理器添加給Logger對象。另外還可以為每個處理器配置它自己的篩選和級別。
handlers.DatagramHandler(host,port):發送日志消息給位於制定host和port上的UDP服務器。
handlers.FileHandler(filename):將日志消息寫入文件filename。
handlers.HTTPHandler(host, url):使用HTTP的GET或POST方法將日志消息上傳到一台HTTP 服務器。
handlers.RotatingFileHandler(filename):將日志消息寫入文件filename。如果文件的大小超出maxBytes制定的值,那么它將被備份為filename1。
由於內置處理器還有很多,如果想更深入了解。可以查看官方手冊。
二、Django使用logging記錄日志
現在大概了解了logging的使用方法,現在可以結合django使用。
setting.py配置文件
在最后面的加上logging的配置

BASE_LOG_DIR = os.path.join(BASE_DIR, "log") LOGGING = { 'version': 1, # version表示版本,一般不用改 # disable_existing_loggers表示棄用已經存在的日志,True表示棄用,False表示不棄用。 'disable_existing_loggers': False, # 禁用已經存在的logger實例 # 日志文件的格式 'formatters': { # 詳細的日志格式 'verbose': { 'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' '[%(levelname)s][%(message)s]' }, # 標准的日志格式 'standard': { 'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' }, # 簡單的日志格式 'simple': { 'format': '[%(levelname)s][ %(message)s]' }, # 定義一個特殊的日志格式 'collect': { 'format': '%(message)s' } }, # 上面的日志格式可以自己隨便定義幾個 # 過濾器 'filters': { }, # 處理器 'handlers': { # 在終端打印 'console': { 'level': 'DEBUG', # 日志的級別 'class': 'logging.StreamHandler', # 'formatter': 'simple' # 使用哪種日志格式 }, # 默認的 'default': { 'level': 'INFO', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自動切 'filename': os.path.join(BASE_LOG_DIR, "xxx_info.log"), # 日志文件的位置 'maxBytes': 1024 * 1024 * 50, # 日志大小 50M 'backupCount': 3, # 最多備份幾個 'formatter': 'standard', # 使用哪種日志格式 'encoding': 'utf-8', # 保存的格式 }, # 專門用來記錯誤日志 'error': { 'level': 'ERROR', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自動切 'filename': os.path.join(BASE_LOG_DIR, "xxx_err.log"), # 日志文件 'maxBytes': 1024 * 1024 * 50, # 日志大小 50M 'backupCount': 5, 'formatter': 'standard', 'encoding': 'utf-8', }, # 專門定義一個收集特定信息的日志 'collect': { 'level': 'INFO', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自動切 'filename': os.path.join(BASE_LOG_DIR, "xxx_collect.log"), 'maxBytes': 1024 * 1024 * 50, # 日志大小 50M 'backupCount': 5, 'formatter': 'collect', 'encoding': "utf-8" } }, # 上面的處理器可以根據自己的需求來配置 'loggers': { # 默認的logger應用如下配置 '': { 'handlers': ['default', 'console', 'error'], # 上線之后可以把'console'移除 'level': 'DEBUG', 'propagate': True, # 向不向更高級別的logger傳遞 }, # 名為 'collect'的logger還單獨處理 'collect': { 'handlers': ['console', 'collect'], 'level': 'INFO', } }, }
解析:
1.formatters:配置打印日志格式
2.handler:用來定義具體處理日志的方式,可以定義多種,"default"就是默認方式,"console"就是打印到控制台方式。
3.loggers:用來配置用那種handlers來處理日志,比如你同時需要輸出日志到文件、控制台。
在views.py里使用
import logging # 生成一個以當前文件名為名字的logger實例 logger = logging.getLogger(__name__) # 生成一個名為collect的logger實例 collect_logger = logging.getLogger("collect") def index(request): logger.debug("這是一個調試信息1....") logger.info("這是一個信息") logger.debug("這是一個調試信息2....") collect_logger.info("用戶:北京") return HttpResponse("OK")