首頁 >後端開發 >Python教學 >Python中logging日誌模組的解析(程式碼範例)

Python中logging日誌模組的解析(程式碼範例)

不言
不言轉載
2018-11-26 16:29:332507瀏覽

本篇文章帶給大家的內容是關於Python中logging日誌模組的解析(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

一、日誌記錄的等級

  1. #debug:優先權10,記錄調試的詳細信息,只在調試時開啟

  2. info:優先權20,記錄普通的訊息,報告錯誤和警告等待。

  3. warning:優先權30,記錄相關的警告訊息。

  4. error:優先權40,記錄錯誤訊息、程式崩潰

  5. critical:優先權50,記錄錯誤訊息

如果不設置,預設為iwarning

二、logging模組的主要結構

查看logging的源碼,可知主要有四個類別實作功能:

  1. Loggers:提供應該程式直接使用的接口,如相關的組態設定

  2. Handlers:將Loggers產生的日誌傳到指定位置,設定日誌儲存的位置;

  3. Filters:對輸出日誌進行過濾操作;

  4. Formatters:控制日誌的輸出格式

Formatters

Formatters物件定義了日誌的輸出格式,有多種可選參數。

參數 意義
%(name)s #Logger的名字
%(levellno)s #數字形式的日誌等級
%(levelname)s 文字形式的日誌等級
%(pathname)s 呼叫日誌輸出函數的模組的完整路徑名,可能沒有
%(filename)s 呼叫日誌輸出函數的模組的檔案名稱
%(module)s 呼叫日誌輸出函數的模組名稱
%(funcName)s 呼叫日誌輸出函數的函數名稱
%(lineno)d 呼叫日誌輸出函數的語句所在的程式碼行
#%(created)f 目前時間,以unix標表示的時間浮點表示
%(relativeCreated)d #輸出日誌資訊時,自Logger建立以來的毫秒數
%(asctime)s 字串形式的當前時間,預設格式是'2018-11-22 16:49:45,896',逗號後面是毫秒
#%(thread)d 執行緒ID,可能沒有
#%(threadName)s 執行緒名,可能沒有
%(process)d 進程ID,可能沒有
%(message)s 使用者輸出的訊息

實例:

import logging

#fmt:定义输出的日志信息的格式
#datefmt:定义时间信息的格式,默认为:%Y-%m-%d %H:%M:%S
#style:定义格式化输出的占位符,默认是%(name)格式,可选{}或$格式
formatter=logging.Formatter(fmt='%(asctime)s    %(levelname)s:  %(message)s'
                            ,datefmt='%Y-%m-%d %H:%M:%S',style='%')

Handlers日誌處理器

日誌處理器用來處理日誌的具體流向,是輸出到檔案還是標準輸出等,它通過設定Formatter控制輸出格式,新增filters過濾​​日誌。

常用的處理器有兩種

  1. StreamHandler:用來列印日誌

FileHandler:用於列印日誌檔案日誌回滾方式,支援日誌檔案最大數量和日誌檔案回滾#日誌回滾方式,在一定時間區域內回滾日誌檔案遠端輸出日誌到TCP/IP sockets遠端輸出日誌到UDP sockets遠端輸出日誌到郵件地址#日誌輸出到syslog遠端輸出日誌到Windows NT/2000/xp的事件日誌日誌輸出到記憶體中的指定buffer
其它的處理器
名稱 詳細位置 說明
#RotatingHandler logging.handlers.RotatingHandler
TimeRotatingHandler logging.handlers.TimeRotatingHandler
SocketHandler logging.handlers.SocketHandler
#DatagramHandler logging.handlers.DatagramHandler
SMTPHandler #logging.handlers.SMTPHandler
SysLogHandler logging.handlers.SysLogHandler
NTEventLogHandler logging.handlers.NTEventLogHandler
MemoryHandler logging.handlers.MemoryHandler

HTTPHandler

#logging.handlers.HTTPHandler

透過「GET」或「POST」遠端輸出到HTTP伺服器

from logging import Handler

#所有日志处理器的父类
handler=Handler()

print('处理日志的等级:',handler.level)
print('处理日志的名字:',handler.name)
print('处理器的日志过滤器::',handler.filters)
print('日志的格式::',handler.filters)

#一些常用方法:
handler.get_name()
handler.set_name('')
handler.createLock()#创建线程锁
handler.acquire()#获取线程锁
handler.release()#释放线程锁
handler.setLevel('info') #设置日志处理器的记录级别
handler.setFormatter(fmt='')#设置日志的输出格式
handler.addFilter('')#往处理器中添加过滤器
handler.removeFilter('')#往处理器中移除过滤器
handler.emit('')#日志记录的处理逻辑,由子类实现

#Logger日誌物件

Logger管理所有記錄日誌的方法。

from logging import error, debug, warning, info, fatal, critical, getLogger

#返回一个Logger实例
#以'root'为名字的日志对象在Logger对象中只有一个实例
logger=getLogger('root')

print('获取根日志对象',logger.root)
print('获取manager',logger.manager)
print('获取根日志对象的名字',logger.name)
print('获取根日志对象记录水平',logger.level)
print('获取根日志对象过滤器列表',logger.filters)
print('获取根日志对象处理器列表',logger.handlers)
print('获取根日志对象',logger.disabled)

#设置日志记录水平
logger.setLevel('info')

#输出日志信息,格式化输出
logger.info('this is %s','info',exc_info=1)
#记录warning信息
logger.warning('')
#记录error信息
logger.error('')
#等价于logger.error('',exc_info=1)
logger.exception('')
#记录debug信息
logger.debug('')
#记录critical信息
logger.critical('')
#直接指定级别
logger.log('info','')

#添加处理器
logger.addHandler()
#移除处理器
logger.removeHandler()
#判是否有处理器
logger.hasHandlers()

三、logger的基本使用
  1. 實例:

    import logging
    import sys
    
    def my_get_logger(appname):
        #获取logger实例,如果参数为空则返回root logger
        logger=logging.getLogger(appname)
        #创建日志输出格式
        formatter=logging.Formatter('%(asctime)s    %(levelname)s:  %(message)s')
    
        #指定输出的文件路径
        file_handler=logging.FileHandler('test.log')
        # 设置文件处理器,加载处理器格式
        file_handler.setFormatter(formatter)
    
        #控制台日志
        console_handler=logging.StreamHandler(sys.stdout)
        console_handler.formatter=formatter
    
        #为logger添加的日志处理器
        logger.addHandler(file_handler)
        logger.addHandler(console_handler)
    
        #指定日志的最低输出级别,默认为warn级别
        logger.setLevel(logging.INFO)
        return logger
    
    if __name__ == '__main__':
        logger=my_get_logger('test')
        logger.debug('this is debug info')
        logger.info('this is information')
        logger.warning('this is warning message')
        logger.error('this is error message')
        logger.fatal('this is fatal message,it is same ad logger.critical')
        logger.critical('this is critical message')
  2. 結果:
  3. 2018-11-22 16:31:34,023 INFO: this is information
    2018-11-22 16:31:34,023 WARNING: this is warning message
    2018-11-22 16:31:34,023 ERROR: this is error message
    2018-11-22 16:31:34,024 CRITICAL: this is fatal message,it is same ad logger.critical
    2018-11-22 16:31:34,024 CRITICAL: this is critical message

    四、logger日誌記錄的邏輯呼叫過程
  4. 記錄日誌透過呼叫logger.debug等方法;
  5. 首先判斷本筆記錄的日誌等級是否大於設定的級別,如果不是,直接pass,不再執行;
  6. 將日誌資訊當做參數建立一個LogRecord日誌記錄物件
  7. 將LogRecord物件經過logger過濾器過濾,如果被過濾則pass
  8. 日誌記錄物件被Handler處理器的過濾器過濾

判斷本筆記錄的日誌等級是否大於Handler處理器設定的級別,如果不是,直接pass,不再執行;

  1. 最後呼叫處理器的emit方法處理日誌記錄;

  2. 五、配置logger
  3. #透過程式碼進行完整配置,主要是透過getLogger方法實現,但不好修改
  4. 透過basicConfig方法實現,這種方式快速但不夠層次分明

透過logging.config.fileConfig(filepath),檔案配置

透過dictConfig的字典方式配置,這是py3.2版本引入的新的配置方法

使用檔案方式配置

#logging.cong

[loggers]
#定义日志的对象名称是什么,注意必须定义root,否则报错
keys=root,main

[handlers]
#定义处理器的名字是什么,可以有多个,用逗号隔开
keys=consoleHandler

[formatters]
#定义输出格式对象的名字,可以有多个,用逗号隔开
keys=simpleFormatter

[logger_root]
#配置root对象的日志记录级别和使用的处理器
level=INFO
handlers=consoleHandler

[logger_main]
#配置main对象的日志记录级别和使用的处理器,qualname值得就是日志对象的名字
level=INFO
handlers=consoleHandler
qualname=main
#logger对象把日志传递给所有相关的handler的时候,会逐级向上寻找这个logger和它所有的父logger的全部handler,
#propagate=1表示会继续向上搜寻;
#propagate=0表示停止搜寻,这个参数涉及重复打印的坑。
propagate=0

[handler_consoleHandler]
#配置处理器consoleHandler
class=StreamHandler
level=WARNING
formatter=simpleFormatter
args=(sys,)

[formatter_simpleFormatter]
#配置输出格式过滤器simpleFormatter
format=%(asctime)-%(name)s-%(levelname)s-%(message)s
注意:可以看到logger和Handler都可以設定日誌級別,日誌輸出是取最高級別。

使用字典形式配置

###字典形式配置功能更強大,也更有彈性。透過dictConfig函數,我們可以將其他格式的設定檔轉換成字典,如json,YAML等。 ######實例:###
import yaml
from logging.config import dictConfig
import os
filename=os.path.dirname(os.path.abspath(__file__))
with  open(filename+'/logging.yaml','r') as f:
    log=yaml.load(f.read())
    dictConfig(log)
#logging.yaml
#注意:yaml格式严格,:后面一定要带空格
version: 1
formatters:
    simple:
          format: '%(asctime)s-%(name)s-%(levelname)s-%(message)s'
handlers:
    console:
          class: logging.StreamHandler
          level: DEBUG
          formatter: simple
          stream: ext://sys.stdout
    console_err:
          class: logging.StreamHandler
          level: DEBUG
          formatter: simple
          stream: ext://sys.stderr
loggers:
    simpleExample:
          level: DEBUG
          handlers: [console]
          propagate: no
root:
    level: DEBUG
    handlers: [console_err]]
######六、監聽logger設定更改######logging.config.listen(port)函數可以讓英文程式在一個socket上監聽新的配置訊息,達到在運行時改變配置,而不用重啟應用程式的目的。
import logging.config
import logging
logging.config.fileConfig("logging.conf")
logger=logging.getLogger('test.listen')

#监听端口号9999
t=logging.config.listen(9999)
t.setDaemon(True)
t.start()
######

以上是Python中logging日誌模組的解析(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除