logging模塊

logging模塊

@(雜庭憶技)[Python, logging]css

018.8.17html

簡單示例

import logging            


logging.debug("debug")                  
logging.info("info")      

logging.warning("warning")                    
logging.error("error")    

# 輸出
>>WARNING:root:warning
>>ERROR:root:error

默認狀況下,logging將日誌打印到屏幕上,按WARNING級別python

日誌等級

CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET服務器

設置日誌等級之後,程序會自動過濾掉低於設置等級的日誌信息。如:當等級爲WARNING的時候,包括INFO及如下的日誌信息會被過濾掉socket

簡單設置

利用logging模塊中的basicConfig()方法對日誌作簡單設置函數

import logging

# 設置日誌的基本信息
logging.basicConfig(
        level=logging.DEBUG, # 設置等級
        filename = "test.log", # 設置輸出文件
        datefmt = "%Y/%m/%d %H:%M:%S", # 設置時間格式
        format = "【%(asctime)s %(levelname)s】 %(lineno)d: %(message)s") # 設置輸出格式

logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")

運行程序以後,當前目錄下會生成一個test.log的文件,內容以下:
這裏寫圖片描述spa

可見輸出格式是按照參數format指定樣子生成的,而asctimelevelnamelineno指定的是須要輸出哪些內容,這裏依次是:時間,日誌等級,出現行號,以及日誌內容;若是不看小括號中的內容,其實%s%d就是格式佔位符線程


固然basicConfig()的用法並無完,完整參數以下
- filename:輸出文件路徑
- filemode:按什麼方式寫入,w表示清空內容以後寫入,a表示追加(默認追加模式)
- datefmt:設置時間格式
- style:當format傳入了參數的時候,用style參數來指定佔位符,能夠是:%,{,$debug

import logging

# 不指定style時,默認%
logging.basicConfig(
        level=logging.DEBUG,
        datefmt = "%Y/%m/%d",
        filename = "test.log",
        format = "%(asctime)s %(message)s")

# 指定用符號 {
logging.basicConfig(
        level=logging.DEBUG,
        style = "{",
        datefmt = "%Y/%m/%d",
        filename = "test.log",
        format = "{asctime} {message}")

# 指定用符號 $
logging.basicConfig(
        level=logging.DEBUG,
        style = "{",
        datefmt = "%Y/%m/%d",
        filename = "test.log",
        format = "$asctime $message")

logging.debug("debug")

須要區分%、{、$佔位時的不一樣用法
- level:指定日誌輸出等級,只有大於等於這個等級的日誌纔會被輸出
- stream:輸出流,能夠理解爲輸出到終端,當沒有設置filename參數的時候,默認用StreamHandler;若是同時設置了streamfilename參數,stream的效果將被忽略
- handlers:指定日誌處理時使用的Handler
- format:指定日誌輸出格式。經常使用參數以下:
1. asctime:時間,默認按照2003-07-08 16:49:45,896格式
2. created:也是時間,但以時間戳形式輸出
3. filename:當前執行文件的名字
4. funcName:當前執行函數的名字
5. levelname:日誌級別的名稱(WARNING、ERROR…)
6. lineno:當前行號
7. message:日誌內容
8. module:模塊名
9. process:進程號
10. processName:進程名字
11. thread:線程號
12. threadName:線程名字
13. (更多相關參數可查看官方文檔3d

Handler

FileHandler

前面都是利用logging的basicConfig()方法配置全局信息,咱們也能夠經過getLogger()方法返回一個logging.Logger類型的對象進行動態配置

import logging                                  

# 實例一個logger對象,並對其添加文件名
logger = logging.getLogger(__name__)
# 設置日誌級別
logger.setLevel(logging.WARNING)

# 構建日誌格式
formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
# 構建一個handler對象,並設置日誌存放路徑
handler = logging.FileHandler("test.log")
# 添加格式
handler.setFormatter(formatter)

# 添加handler
logger.addHandler(handler)

# 輸出日誌
logger.error("error")

咱們也能夠構建多個handler來處理問題,好比將日誌輸出到文件的同時,也在終端輸出

import logging


logger = logging.getLogger(__name__)

formatter = logging.Formatter("【%(asctime)s %(levelname)s】 %(message)s")

# 構建一個StreamHandler,用於輸出到終端
strHandler = logging.StreamHandler()
strHandler.setLevel(logging.WARN) # 設置等級高於WARN以及WARN以上的(WARNING的簡寫)
strHandler.setFormatter(formatter)

logger.addHandler(strHandler)


# 構建一個FileHandler,用於輸出到文件
fileHandler = logging.FileHandler("a-simmple.log")
fileHandler.setLevel(logging.INFO)# 設置等級高於INFO以及INFO以上的(WARNING的簡寫)
fileHandler.setFormatter(formatter)

logger.addHandler(fileHandler)


logger.debug("debug")
logger.info("info")
logger.warning("warning")
logger.error("error")

終端輸出結果以下:
這裏寫圖片描述
日誌文件內容以下:
這裏寫圖片描述

須要注意一點,在使用Handler(FileHandler,StreamHandler)對象的setLevel()方法的時候,若是須要設置的日誌級別低於WARNING,則必須對logger對象使用setLevel(),根據具體狀況選擇logging.DEBUG或logging.INFO參數;固然也可使用logging.basicConfig()方法配置全局信息,也能起到一樣的效果,以下:

import logging


logging.basicConfig(level = logging.DEBUG)
logger = logging.getLogger(__name__)

formatter = logging.Formatter("【%(asctime)s %(levelname)s】 %(message)s")

# 構建一個StreamHandler,用於輸出到終端
...(省略)

其餘Handler

除FileHandler,StreamHandler外,logging模塊還提供了其餘的Handler(如下都包含在logging.handlers模塊中
- BaseRotatingHandler:基本的日誌回滾方式
- RotatingHandler:日誌回滾方式,支持日誌文件最大數量和日誌文件回滾
- TimeRotatingHandler:日誌回滾方式,在必定時間區域內回滾日誌文件
- SocketHandler:遠程輸出日誌到TCP/IP sockets
- DatagramHandler:遠程輸出日誌到UDP sockets
- SMTPHandler:遠程輸出日誌到郵件地址
- SysLogHandler:日誌輸出到syslog
- NTEventLogHandler:遠程輸出日誌到Windows NT/2000/XP的事件日誌
- MemoryHandler:日誌輸出到內存中的指定buffer
- HTTPHandler:經過GET或POST遠程輸出到HTTP服務器

捕獲Traceback

利用logging模塊,也能夠詳細記錄Traceback,方便咱們查找問題

import logging


logger = logging.getLogger(__name__)

formatter = logging.Formatter(
        "【%(asctime)s %(levelname)s】 %(message)s")
handler = logging.FileHandler("traceback.log")
handler.setFormatter(formatter)
logger.addHandler(handler)


try:
    print(name)
except:
    logger.error("error", exc_info=True)

運行結果以下:
這裏寫圖片描述

配置共享

能夠經過配置父模塊的方法,讓子模塊也受益

""" 父模塊:mainLog.py """
import logging
import dupLog


logger = logging.getLogger("father") # 生成一個logger,併爲其命名「father」
logger.setLevel(logging.DEBUG)

handler = logging.FileHandler("my-log.txt")
formatter = logging.Formatter(
        "【%(asctime)s %(levelname)s】 %(name)s: %(message)s ")
handler.setFormatter(formatter)
logger.addHandler(handler)


logger.debug("debug")
logger.info("info")
logger.warning("warning")

dupLog.record_log() # 調用子模塊的日誌記錄功能
""" 子模塊:dupLog.py """
import logging


logger = logging.getLogger("father.son") # 生成一個logger,併爲其命名「father.son」

# 記錄日誌函數
def record_log():
    logger.info("info")
    logger.error("error")

輸出結果:

"""
日誌文件:my-log.txt
"""
【2018-08-18 07:47:21,775 DEBUGfather: debug 
【2018-08-18 07:47:21,776 INFOfather: info 
【2018-08-18 07:47:21,776 WARNINGfather: warning 
【2018-08-18 07:47:21,776 INFOfather.son: info 
【2018-08-18 07:47:21,776 ERRORfather.son: error

這裏須要注意的是,子模塊的logger名稱必須以父模塊的logger名稱開頭,如上所示的父father,子father.son

文件配置

儘管設置配置信息的時候有logging.basciConfig()logging.getLogger().setLevel()logging.Formatter().setFormatter()等方法,但語句始終鑲嵌在代碼裏,不利於修改,也不利於閱讀。所以logging模塊提供了以加載配置文件的方式對日誌功能進行配置

配置文件: log.conf

[loggers]
keys=root,log02

[handlers]
keys=hand01,hand02

[formatters]
keys=form01,form02

#################################################
[logger_root]
level=NOTSET
handlers=hand01

[logger_log02]
level=WARNING
handlers=hand02
propagate=1
qualname=log02

#################################################
[handler_hand01]
class=FileHandler
level=NOTSET
formatter=form01
args=("mine.log", "w")

[handler_hand02]
class=StreamHandler
level=WARNING
formatter=form02
args=(sys.stdout,)

#################################################
[formatter_form01]
format=[%(asctime)s %(levelname)s]-%(name)s-: %(message)s
datefmt=%Y/%m/%d %H:%M:%S
class=logging.Formatter

[formatter_form02]
format=%(asctime)s %(levelname)s: %(message)s
class=logging.Formatter

執行文件:test_log.py

import logging
import logging.config


logging.config.fileConfig("log.conf") # 加載配置文件

loggerRoot = logging.getLogger("root") # 獲取root的配置
loggerLog02 = logging.getLogger("log02") # 獲取log2的配置

loggerRoot.debug("debug")
loggerRoot.info("info")
loggerRoot.warning("warning")
loggerRoot.error("error")

loggerLog02.warning("warning")
loggerLog02.error("error")

運行結果以下:
- 終端
這裏寫圖片描述
- mine.log
這裏寫圖片描述

須要注意如下幾點:
- 配置文件中,必須含有[loggers] [handlers] [formatters] 字段
- [loggers]keys中,必須含有root,並對其配置
- root會執行全部logger應該執行的debug(),info()...等方法(因此上示mine.log文件中,有log02的日誌信息)
- 更多詳情可查看官方logging.config信息


文件配置還有另外一種方法,利用logging.config.dictConfig()方法加載配置信息,配置文件格式以下:
這裏寫圖片描述

具體使用方法可參看官方文檔說明,也能夠看崔慶才的一篇關於使用logging的文章

相關文章
相關標籤/搜索