Django 之 logging

1. logging

1.1 什麼是 logging

logging 模塊是 Python 內置的日誌管理模塊,不須要額外安裝。html

使用:python

import logging

logging.critical('this is critical msg')
logging.error('this is error msg')
logging.warning('this is warning msg')
logging.info('this is info msg')

運行結果以下:web

CRITICAL:root:this is critical msg
ERROR:root:this is error msg
WARNING:root:this is warning msg

默認只輸出 warning 以上級別的日誌,日誌級別:django

CRITICAL(嚴重錯誤) > ERROR > WARNING(默認) > INFO > DEBUG > NOTSET安全

默認日誌格式:服務器

LOGLEVEL:LOGGERNAME:msg

1.2 logging 模塊中的幾個重要概念

logging 中不得不知道的幾個概念:LoggerHandlerFormatterFiltersocket

  • Logger 記錄器:暴露了應用程序代碼能直接使用的接口。
  • Handler 處理器:將(記錄器產生的)日誌記錄發送至合適的目的地。
  • Filter 過濾器:提供了更好的粒度控制,它能夠決定輸出哪些日誌記錄。
  • Formatter 格式化器:指明瞭最終輸出中日誌記錄的佈局。

Logger 記錄器函數

使用接口debug,info,warn,error,critical以前必須建立Logger實例:工具

# 建立 Logger 實例
logger = logging.getLogger(logger_name)

若是沒有建立 Logger 實例,那麼默認建立一個 root logger,且默認日誌級別爲 warning,處理器爲 StreamHandler(即將日誌信息打印輸出在屏幕上),輸出格式爲一個簡單的使用程序輸出格式。佈局

logger 實例其餘操做:

logger.setLevel(logging.ERROR)      # 設置日誌級別
logger.addHandler(handler_name)     # 爲Logger實例增長一個處理器
logger.removeHandler(handler_name) `# 爲Logger實例刪除一個處理器

Handler 處理器

經常使用 Handler 處理器有 :StreamHandlerFileHandlerNullHandler

建立方法:

# StreamHandler
sh = logging.StreamHandler(stream=None)

# FileHandler
fh = logging.FileHandler(filename, mode='a', encoding=None, delay=False)

# NullHandler
# 不作任何的格式化或者輸出的 handler

根據處理器對象,能夠設置日誌級別、格式化日誌增長或刪除過濾器等操做:

sh.setLevel(logging.WARN)           # 指定日誌級別,低於WARN級別的日誌將被忽略
sh.setFormatter(formatter_name)      # 設置一個格式化器formatter
sh.addFilter(filter_name)            # 增長一個過濾器,能夠增長多個
sh.removeFilter(filter_name)        # 刪除一個過濾器

Handler 類型及做用:

類型 說明
logging.StreamHandler 指定向流對象進行
logging.FileHandler 指定文件
logging.handlers.RotaingFileHandler 指定文件,但可管理文件大小,當超過指定值後則從新建立日誌文件
logging.handlers.TimedRotatingFileHandler 指定文件,超過指定週期後從新建立日誌文件
logging.handlers.SocketHandler 指定socket
logging.handlers.SyslogHandler 指定syslog服務器
logging.handlers.HTTPHandler 使用post/get請求提交數據到web服務器

更多關於 Handler 能夠訪問 Python logging.handlers


Formatter 格式化器

Formatter 格式化器能夠用來指定日誌輸出格式,默認的時間格式爲 %Y-%m-%d %H:%M:%S

建立方法:

# fmt:消息的格式化字符串,datefmt:日期字符串,若不指定 fmt,將使用'%(message)s'。若不指定 datefmt,將使用ISO8601日期格式
formatter = logging.Formatter(fmt=None, datefmt=None)

# 示例,指定輸出當前時間、日誌等級名字、線程名、消息
fmt = logging.Formatter('%(asctime)s - %(levelname)s - %(threadName)s - %(message)s')
fh = logging.FileHandler('/tmp/test.log')

格式化參數:

參數 說明
%(name)s Logger的名字
%(levelno)s 數字日誌級別
%(levelname)s 文本日誌級別
%(pathname)s 調用日誌輸出函數的模塊文件路徑
%(filenames)s 調用日誌輸出函數的模塊文件名
%(module)s 調用日誌輸出函數的模塊名
%(funcName)s 調用日誌輸出函數的函數名
%(lineno)d 調用日誌輸出函數語句所在行號
%(created)f 當前時間
%(relativeCreated)d 當前時間
%(asctime)s 當前時間,格式’2015-05-28 20:50:03,345’
%(thread)d 線程id
%(threadName)s 線程名
%(process)d 進程id
%(message)s 消息

Filter 過濾器

進行更爲複雜的日誌過濾,只容許特定 Logger 層次如下的事件經過。

建立方法:

filter = logging.Filter(name='')

Tips

Logger 是一個樹狀結構,它能夠有多個處理器,一個處理器也能夠有多個格式化器或過濾器,且日誌級別可繼承


示例

import logging

logger = logging.getLogger()

# 控制檯 handler 對象,標準輸出
# sh = logging.StreamHandler()
fh = logging.FileHandler(filename='test.log')

# 當前時間、日誌等級名字、線程名、消息
fmt = logging.Formatter('%(asctime)s - %(levelname)s - %(threadName)s - %(message)s')

# 將格式添加到對象中
# sh.setFormatter(fmt)
fh.setFormatter(fmt)

# 添加到 logger 中
# logger.addHandler(sh)
logger.addHandler(fh)
logger.warning('This is a warning log...')

1.3 配置方式

logging 模塊支持自定義配置,配置方式有:

  • basicConfig:簡單配置
  • dictConfig:經過字典進行配置
  • fileConfig:經過一個文件進行配置
  • listen:經過一個端口進行配置

以上配置方式非必須,能夠不使用以上方式配置,而直接調用 Logger 實例。


basicConfig

logging.basicConfig(level=logging.DEBUG, format='', datefmt='',  filemode='', filename='', stream='')

# 示例
logging.basicConfig(filename='logger.log', level=logging.INFO)

參數:

關鍵字 描述
filename 建立一個 FileHandler,使用指定的文件名
filemode 若是指明瞭文件名,指明打開文件的模式(若是沒有指明filemode,默認爲 a)
format 指定日誌輸出格式
datefmt 指定日誌輸出時間/日期格式
level 指定日誌等級
stream 建立 StreamHandler。與 filename 不兼容,若是兩個都有,stream 被忽略

2. 在 Django 中使用 logging

Django 使用 Python 自帶的 logging 模塊做爲日誌打印工具。

日誌級別:infodebugerrorwarningCRITICAL

logging 是線程安全的,其主要由如下四部分組成:

  • Logger(記錄器) :用戶使用的直接接口,將日誌傳遞給 Handler
  • Handler(處理器) :控制日誌輸出到哪裏,consolefile 等(一個logger能夠有多個Handler
  • Filter(過濾器) :控制哪些日誌能夠從logger流向 Handler
  • Formatter(格式化器) :控制日誌的格式

在 Django 中使用 logging

settings.py 最後添加以下代碼:

BASE_LOG_DIR = os.path.join(BASE_DIR, "log")
LOGGING = {
    'version': 1,  # 保留字
    'disable_existing_loggers': False,  # 禁用已經存在的logger實例
    # 日誌文件的格式
    'formatters': {
        # 詳細的日誌格式
        'standard': {
            'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]'
                      '[%(levelname)s][%(message)s]'
        },
        # 簡單的日誌格式
        'simple': {
            'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
        },
        # 定義一個特殊的日誌格式
        'collect': {
            'format': '%(message)s'
        }
    },
    # 過濾器
    'filters': {
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    # 處理器
    'handlers': {
        # 在終端打印
        'console': {
            'level': 'DEBUG',
            'filters': ['require_debug_true'],  # 只有在Django debug爲True時纔在屏幕打印日誌
            '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',
        }
    },
}

在視圖中使用 logging

from django.shortcuts import render, HttpResponse
import logging


# 生成一個以當前文件名爲名字的logger實例
logger = logging.getLogger(__name__)

# 生成一個名爲collect的logger實例
collect_logger = logging.getLogger("collect")

def index(request):
    logger.debug("debug1。。。。")
    logger.info("info1。。。。")
    logger.debug("debug2")

    collect_logger.info("用戶:rose")

    return HttpResponse("OK")

運行流程

相關文章
相關標籤/搜索