欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

2022最新Python日志庫logging總結(jié)

 更新時間:2022年05月07日 16:00:30   作者:Wizey  
這篇文章主要介紹了2022最新Python日志庫logging總結(jié),Python logging 庫設(shè)計的真的非常靈活,如果有特殊的需要還可以在這個基礎(chǔ)的 logging 庫上進(jìn)行改進(jìn),創(chuàng)建新的 Handler 類解決實際開發(fā)中的問題,需要的朋友可以參考下

在部署項目時,不可能直接將所有的信息都輸出到控制臺中,我們可以將這些信息記錄到日志文件中,這樣不僅方便我們查看程序運行時的情況,也可以在項目出現(xiàn)故障時根據(jù)運行時產(chǎn)生的日志快速定位問題出現(xiàn)的位置。

1、日志級別

Python 標(biāo)準(zhǔn)庫 logging 用作記錄日志,默認(rèn)分為六種日志級別(括號為級別對應(yīng)的數(shù)值),NOTSET(0)、DEBUG(10)、INFO(20)、WARNING(30)、ERROR(40)、CRITICAL(50)。我們自定義日志級別時注意不要和默認(rèn)的日志級別數(shù)值相同,logging 執(zhí)行時輸出大于等于設(shè)置的日志級別的日志信息,如設(shè)置日志級別是 INFO,則 INFO、WARNING、ERROR、CRITICAL 級別的日志都會輸出。

2、logging 流程

官方的 logging 模塊工作流程圖如下:

從下圖中我們可以看出看到這幾種 Python 類型,Logger、LogRecordFilter、Handler、Formatter

類型說明:

Logger:日志,暴露函數(shù)給應(yīng)用程序,基于日志記錄器和過濾器級別決定哪些日志有效。

LogRecord :日志記錄器,將日志傳到相應(yīng)的處理器處理。

Handler :處理器, 將(日志記錄器產(chǎn)生的)日志記錄發(fā)送至合適的目的地。

Filter :過濾器, 提供了更好的粒度控制,它可以決定輸出哪些日志記錄。

Formatter:格式化器, 指明了最終輸出中日志記錄的布局。

  1. 判斷 Logger 對象對于設(shè)置的級別是否可用,如果可用,則往下執(zhí)行,否則,流程結(jié)束。
  2. 創(chuàng)建 LogRecord 對象,如果注冊到 Logger 對象中的 Filter 對象過濾后返回 False,則不記錄日志,流程結(jié)束,否則,則向下執(zhí)行。
  3. LogRecord 對象將 Handler 對象傳入當(dāng)前的 Logger 對象,(圖中的子流程)如果 Handler 對象的日志級別大于設(shè)置的日志級別,再判斷注冊到 Handler 對象中的 Filter 對象過濾后是否返回 True 而放行輸出日志信息,否則不放行,流程結(jié)束。
  4. 如果傳入的 Handler 大于 Logger 中設(shè)置的級別,也即 Handler 有效,則往下執(zhí)行,否則,流程結(jié)束。
  5. 判斷這個 Logger 對象是否還有父 Logger 對象,如果沒有(代表當(dāng)前 Logger 對象是最頂層的 Logger 對象 root Logger),流程結(jié)束。否則將 Logger 對象設(shè)置為它的父 Logger 對象,重復(fù)上面的 3、4 兩步,輸出父類 Logger 對象中的日志輸出,直到是 root Logger 為止。

3、日志輸出格式

日志的輸出格式可以認(rèn)為設(shè)置,默認(rèn)格式為下圖所示。

4、基本使用

logging 使用非常簡單,使用 basicConfig() 方法就能滿足基本的使用需要,如果方法沒有傳入?yún)?shù),會根據(jù)默認(rèn)的配置創(chuàng)建Logger 對象,默認(rèn)的日志級別被設(shè)置為 WARNING,默認(rèn)的日志輸出格式如上圖,該函數(shù)可選的參數(shù)如下表所示。

參數(shù)名稱參數(shù)描述
filename日志輸出到文件的文件名
filemode文件模式,r[+]、w[+]、a[+]
format日志輸出的格式
datefat日志附帶日期時間的格式
style格式占位符,默認(rèn)為 "%" 和 “{}”
level設(shè)置日志輸出級別
stream定義輸出流,用來初始化 StreamHandler 對象,不能 filename 參數(shù)一起使用,否則會ValueError 異常
handles定義處理器,用來創(chuàng)建 Handler 對象,不能和 filename 、stream 參數(shù)一起使用,否則也會拋出 ValueError 異常

示例代碼如下:

import logging
logging.basicConfig()
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')

輸出結(jié)果如下:

WARNING:root:This is a warning message
ERROR:root:This is an error message
CRITICAL:root:This is a critical message

傳入常用的參數(shù),示例代碼如下(這里日志格式占位符中的變量放到后面介紹):

import logging
logging.basicConfig(filename="test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%m-%Y %H:%M:%S", level=logging.DEBUG)
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')

生成的日志文件 test.log ,內(nèi)容如下:

13-10-18 21:10:32 root:DEBUG:This is a debug message
13-10-18 21:10:32 root:INFO:This is an info message
13-10-18 21:10:32 root:WARNING:This is a warning message
13-10-18 21:10:32 root:ERROR:This is an error message
13-10-18 21:10:32 root:CRITICAL:This is a critical message

但是當(dāng)發(fā)生異常時,直接使用無參數(shù)的 debug()、info()、warning()、error()、critical() 方法并不能記錄異常信息,需要設(shè)置 exc_info 參數(shù)為 True 才可以,或者使用 exception() 方法,還可以使用 log() 方法,但還要設(shè)置日志級別和 exc_info 參數(shù)。

import logging
logging.basicConfig(filename="test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)
a = 5
b = 0
try:
    c = a / b
except Exception as e:
    # 下面三種方式三選一,推薦使用第一種
    logging.exception("Exception occurred")
    logging.error("Exception occurred", exc_info=True)
    logging.log(level=logging.DEBUG, msg="Exception occurred", exc_info=True)

5、自定義 Logger

上面的基本使用可以讓我們快速上手 logging 模塊,但一般并不能滿足實際使用,我們還需要自定義 Logger。

一個系統(tǒng)只有一個 Logger 對象,并且該對象不能被直接實例化,沒錯,這里用到了單例模式,獲取 Logger 對象的方法為 getLogger。

注意:這里的單例模式并不是說只有一個 Logger 對象,而是指整個系統(tǒng)只有一個根 Logger 對象,Logger 對象在執(zhí)行 info()、error() 等方法時實際上調(diào)用都是根 Logger 對象對應(yīng)的 info()、error() 等方法。

我們可以創(chuàng)造多個 Logger 對象,但是真正輸出日志的是根 Logger 對象。每個 Logger 對象都可以設(shè)置一個名字,如果設(shè)置logger = logging.getLogger(__name__),__name__ 是 Python 中的一個特殊內(nèi)置變量,他代表當(dāng)前模塊的名稱(默認(rèn)為 __main__)。則 Logger 對象的 name 為建議使用使用以點號作為分隔符的命名空間等級制度。

Logger 對象可以設(shè)置多個 Handler 對象和 Filter 對象,Handler 對象又可以設(shè)置 Formatter 對象。Formatter 對象用來設(shè)置具體的輸出格式,常用變量格式如下表所示,所有參數(shù)見 Python(3.7)官方文檔

變量格式變量描述
asctime%(asctime)s將日志的時間構(gòu)造成可讀的形式,默認(rèn)情況下是精確到毫秒,如 2018-10-13 23:24:57,832,可以額外指定 datefmt 參數(shù)來指定該變量的格式
name%(name)日志對象的名稱
filename%(filename)s不包含路徑的文件名
pathname%(pathname)s包含路徑的文件名
funcName%(funcName)s日志記錄所在的函數(shù)名
levelname%(levelname)s日志的級別名稱
message%(message)s具體的日志信息
lineno%(lineno)d日志記錄所在的行號
pathname%(pathname)s完整路徑
process%(process)d當(dāng)前進(jìn)程ID
processName%(processName)s當(dāng)前進(jìn)程名稱
thread%(thread)d當(dāng)前線程ID
threadName%threadName)s當(dāng)前線程名稱

Logger 對象和 Handler 對象都可以設(shè)置級別,而默認(rèn) Logger 對象級別為 30 ,也即 WARNING,默認(rèn) Handler 對象級別為 0,也即 NOTSET。logging 模塊這樣設(shè)計是為了更好的靈活性,比如有時候我們既想在控制臺中輸出DEBUG 級別的日志,又想在文件中輸出WARNING級別的日志??梢灾辉O(shè)置一個最低級別的 Logger 對象,兩個不同級別的 Handler 對象,示例代碼如下:

import logging
import logging.handlers
logger = logging.getLogger("logger")
handler1 = logging.StreamHandler()
handler2 = logging.FileHandler(filename="test.log")
logger.setLevel(logging.DEBUG)
handler1.setLevel(logging.WARNING)
handler2.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
handler1.setFormatter(formatter)
handler2.setFormatter(formatter)
logger.addHandler(handler1)
logger.addHandler(handler2)
# 分別為 10、30、30
# print(handler1.level)
# print(handler2.level)
# print(logger.level)
logger.debug('This is a customer debug message')
logger.info('This is an customer info message')
logger.warning('This is a customer warning message')
logger.error('This is an customer error message')
logger.critical('This is a customer critical message')

控制臺輸出結(jié)果為:

2018-10-13 23:24:57,832 logger WARNING This is a customer warning message
2018-10-13 23:24:57,832 logger ERROR This is an customer error message
2018-10-13 23:24:57,832 logger CRITICAL This is a customer critical message

文件中輸出內(nèi)容為:

2018-10-13 23:44:59,817 logger DEBUG This is a customer debug message
2018-10-13 23:44:59,817 logger INFO This is an customer info message
2018-10-13 23:44:59,817 logger WARNING This is a customer warning message
2018-10-13 23:44:59,817 logger ERROR This is an customer error message
2018-10-13 23:44:59,817 logger CRITICAL This is a customer critical message

創(chuàng)建了自定義的 Logger 對象,就不要在用 logging 中的日志輸出方法了,這些方法使用的是默認(rèn)配置的 Logger 對象,否則會輸出的日志信息會重復(fù)。

import logging
import logging.handlers
logger = logging.getLogger("logger")
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.debug('This is a customer debug message')
logging.info('This is an customer info message')
logger.warning('This is a customer warning message')
logger.error('This is an customer error message')
logger.critical('This is a customer critical message')

輸出結(jié)果如下(可以看到日志信息被輸出了兩遍):

2018-10-13 22:21:35,873 logger WARNING This is a customer warning message
WARNING:logger:This is a customer warning message
2018-10-13 22:21:35,873 logger ERROR This is an customer error message
ERROR:logger:This is an customer error message
2018-10-13 22:21:35,873 logger CRITICAL This is a customer critical message
CRITICAL:logger:This is a customer critical message

說明:在引入有日志輸出的 python 文件時,如 import test.py,在滿足大于當(dāng)前設(shè)置的日志級別后就會輸出導(dǎo)入文件中的日志。

6、Logger 配置

通過上面的例子,我們知道創(chuàng)建一個 Logger 對象所需的配置了,上面直接硬編碼在程序中配置對象,配置還可以從字典類型的對象和配置文件獲取。打開 logging.config Python 文件,可以看到其中的配置解析轉(zhuǎn)換函數(shù)。

從字典中獲取配置信息:

import logging.config
config = {
    'version': 1,
    'formatters': {
        'simple': {
            'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        },
        # 其他的 formatter
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'simple'
        },
        'file': {
            'class': 'logging.FileHandler',
            'filename': 'logging.log',
            'level': 'DEBUG',
            'formatter': 'simple'
        },
        # 其他的 handler
    },
    'loggers':{
        'StreamLogger': {
            'handlers': ['console'],
            'level': 'DEBUG',
        },
        'FileLogger': {
            # 既有 console Handler,還有 file Handler
            'handlers': ['console', 'file'],
            'level': 'DEBUG',
        },
        # 其他的 Logger
    }
}
logging.config.dictConfig(config)
StreamLogger = logging.getLogger("StreamLogger")
FileLogger = logging.getLogger("FileLogger")
# 省略日志輸出

從配置文件中獲取配置信息:

常見的配置文件有 ini 格式、yaml 格式、JSON 格式,或者從網(wǎng)絡(luò)中獲取都是可以的,只要有相應(yīng)的文件解析器解析配置即可,下面只展示了 ini 格式和 yaml 格式的配置。

test.ini 文件

[loggers]
keys=root,sampleLogger
[handlers]
keys=consoleHandler
[formatters]
keys=sampleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_sampleLogger]
level=DEBUG
handlers=consoleHandler
qualname=sampleLogger
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=sampleFormatter
args=(sys.stdout,)
[formatter_sampleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

testinit.py 文件

import logging.config
logging.config.fileConfig(fname='test.ini', disable_existing_loggers=False)
logger = logging.getLogger("sampleLogger")
# 省略日志輸出

test.yaml 文件

version: 1
formatters:
  simple:
    format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
loggers:
  simpleExample:
    handlers: [console]
    propagate: no
root:
  level: DEBUG
  handlers: [console]

testyaml.py 文件

import logging.config
# 需要安裝 pyymal 庫
import yaml
with open('test.yaml', 'r') as f:
    config = yaml.safe_load(f.read())
    logging.config.dictConfig(config)
logger = logging.getLogger("sampleLogger")
# 省略日志輸出

7、實戰(zhàn)中的問題

1、中文亂碼

上面的例子中日志輸出都是英文內(nèi)容,發(fā)現(xiàn)不了將日志輸出到文件中會有中文亂碼的問題,如何解決到這個問題呢?FileHandler 創(chuàng)建對象時可以設(shè)置文件編碼,如果將文件編碼設(shè)置為 “utf-8”(utf-8 和 utf8 等價),就可以解決中文亂碼問題啦。一種方法是自定義 Logger 對象,需要寫很多配置,另一種方法是使用默認(rèn)配置方法 basicConfig(),傳入 handlers 處理器列表對象,在其中的 handler 設(shè)置文件的編碼。網(wǎng)上很多都是無效的方法,關(guān)鍵參考代碼如下:

# 自定義 Logger 配置
handler = logging.FileHandler(filename="test.log", encoding="utf-8")
# 使用默認(rèn)的 Logger 配置
logging.basicConfig(handlers=[logging.FileHandler("test.log", encoding="utf-8")], level=logging.DEBUG)

2、臨時禁用日志輸出

有時候我們又不想讓日志輸出,但在這后又想輸出日志。如果我們打印信息用的是 print() 方法,那么就需要把所有的 print() 方法都注釋掉,而使用了 logging 后,我們就有了一鍵開關(guān)閉日志的 "魔法"。一種方法是在使用默認(rèn)配置時,給 logging.disabled() 方法傳入禁用的日志級別,就可以禁止設(shè)置級別以下的日志輸出了,另一種方法時在自定義 Logger 時,Logger 對象的 disable 屬性設(shè)為 True,默認(rèn)值是 False,也即不禁用。

logging.disable(logging.INFO)
logger.disabled = True

3、日志文件按照時間劃分或者按照大小劃分

如果將日志保存在一個文件中,那么時間一長,或者日志一多,單個日志文件就會很大,既不利于備份,也不利于查看。我們會想到能不能按照時間或者大小對日志文件進(jìn)行劃分呢?答案肯定是可以的,并且還很簡單,logging 考慮到了我們這個需求。logging.handlers 文件中提供了 TimedRotatingFileHandlerRotatingFileHandler 類分別可以實現(xiàn)按時間和大小劃分。打開這個 handles 文件,可以看到還有其他功能的 Handler 類,它們都繼承自基類 BaseRotatingHandler。

# TimedRotatingFileHandler 類構(gòu)造函數(shù)
def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None):
# RotatingFileHandler 類的構(gòu)造函數(shù)
def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=False)

示例代碼如下:

# 每隔 1000 Byte 劃分一個日志文件,備份文件為 3 個
file_handler = logging.handlers.RotatingFileHandler("test.log", mode="w", maxBytes=1000, backupCount=3, encoding="utf-8")
# 每隔 1小時 劃分一個日志文件,interval 是時間間隔,備份文件為 10 個
handler2 = logging.handlers.TimedRotatingFileHandler("test.log", when="H", interval=1, backupCount=10)

Python 官網(wǎng)雖然說 logging 庫是線程安全的,但在多進(jìn)程、多線程、多進(jìn)程多線程環(huán)境中仍然還有值得考慮的問題,比如,如何將日志按照進(jìn)程(或線程)劃分為不同的日志文件,也即一個進(jìn)程(或線程)對應(yīng)一個文件。

總結(jié):Python logging 庫設(shè)計的真的非常靈活,如果有特殊的需要還可以在這個基礎(chǔ)的 logging 庫上進(jìn)行改進(jìn),創(chuàng)建新的 Handler 類解決實際開發(fā)中的問題。

到此這篇關(guān)于2022最新Python日志庫logging總結(jié)的文章就介紹到這了,更多相關(guān)Python日志庫logging內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于數(shù)據(jù)分析之滾動窗口pandas.DataFrame.rolling方法

    關(guān)于數(shù)據(jù)分析之滾動窗口pandas.DataFrame.rolling方法

    Pandas庫中的rolling方法是數(shù)據(jù)處理中常用的功能,它允許用戶對數(shù)據(jù)進(jìn)行滾動窗口(滑動窗口)操作,通過指定窗口大小,可以使用不同的聚合函數(shù)對窗口內(nèi)的數(shù)據(jù)進(jìn)行計算,例如最大值、最小值、平均值、中位數(shù)等,此外,rolling方法還可以計算方差、標(biāo)準(zhǔn)差、偏度、峰度
    2024-09-09
  • Python面向?qū)ο笾K詳解

    Python面向?qū)ο笾K詳解

    這篇文章主要為大家介紹了Python面向?qū)ο笾K,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • Python docx庫用法示例分析

    Python docx庫用法示例分析

    這篇文章主要介紹了Python docx庫用法,結(jié)合實例形式分析了docx庫相關(guān)的docx文件讀取、文本添加、格式操作,需要的朋友可以參考下
    2019-02-02
  • Python從入門到精通之條件語句和循環(huán)結(jié)構(gòu)詳解

    Python從入門到精通之條件語句和循環(huán)結(jié)構(gòu)詳解

    Python中提供了強大而靈活的條件語句和循環(huán)結(jié)構(gòu),本文將從入門到精通地介紹它們的使用方法,并通過相關(guān)代碼進(jìn)行講解,希望對大家深入了解Python有一定的幫助
    2023-07-07
  • 對于Python中線程問題的簡單講解

    對于Python中線程問題的簡單講解

    這篇文章主要介紹了對于Python中線程問題的簡單講解,線程一直是Python編程當(dāng)中的熱點問題,而本文沒有涉及GIL線程鎖方面的內(nèi)容,需要的朋友可以參考下
    2015-04-04
  • 3種Python 實現(xiàn)酷炫進(jìn)度條的實用方法

    3種Python 實現(xiàn)酷炫進(jìn)度條的實用方法

    這篇文章主要介紹了3種Python 實現(xiàn)酷炫進(jìn)度條的實用方法,文章圍繞Python的相關(guān)資料展開對實現(xiàn)進(jìn)度條的介紹,需要的小伙伴可以參考一下
    2022-04-04
  • python 通過文件夾導(dǎo)入包的操作

    python 通過文件夾導(dǎo)入包的操作

    這篇文章主要介紹了python 通過文件夾導(dǎo)入包的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • python-3.5.3安裝及一些庫安裝教程詳解

    python-3.5.3安裝及一些庫安裝教程詳解

    這篇文章主要介紹了python-3.5.3安裝及一些庫安裝教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Django數(shù)據(jù)庫表反向生成實例解析

    Django數(shù)據(jù)庫表反向生成實例解析

    這篇文章主要介紹了Django數(shù)據(jù)庫表反向生成實例解析,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • 10個示例帶你掌握python中的元組

    10個示例帶你掌握python中的元組

    這篇文章主要介紹了python中的元組的相關(guān)資料,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2020-11-11

最新評論