1. 程式人生 > >模組之 logging, shelve, sys 模組

模組之 logging, shelve, sys 模組

一. logging模組

  用來記錄日誌,日誌:記錄某個時間點發生了什麼事

  日誌作用:程式除錯

       瞭解軟體程式的執行情況,是否正常

       軟體程式執行故障分析與問題定位

       還可用來做使用者行為分析

  日誌等級:在不改動應用程式程式碼的情況下,實現在不同的環境記錄不同詳細程度的

       1. DEBUG=10   最詳細的日誌,應用場景為問題診斷

       2. INFO=20    通常只記錄關鍵節點資訊,用於確認一切是按照預期那樣進行

       3.WARNING=30    記錄一些不期望發生的事情的資訊,程式可正常執行

       4. ERROR=40    由於一個嚴重的問題導致某些功能不能正常執行時記錄的資訊

       5.CRITICAL=50   當發生嚴重錯誤,導致應用程式不能繼續執行時記錄的資訊

  日誌等級排序: DEBUG<INFO<WARNING<ERROR<CRITICAL

  一條日誌資訊應該包括的內容: 發生時間/ 發生的位置/ 事情的嚴重程度(日誌級別)/ 事件內容

  為某個程式制定日誌級別後,應用程式會記錄所有日誌級別>= 制定日誌級別的日誌資訊,同時,logging模組也可以指定日誌記錄器的日誌級別,只有級別>= 指定日誌級別的日誌記錄才會被輸出,低等級的日誌記錄會別丟棄

  logging 模組提供兩種記錄日誌的方式:

    第一種: 使用logging提供的模組級別的函式

    第二種: 使用logging日誌系統的四大元件

  logging模組定義的模組級別的常用函式:

    logging.debug(msg,*args,**kwargs)  建立一條等級為DEBUG的日誌記錄

    logging.info(msg,*args,**kwargs)   建立一條嚴重級別為INFO的日誌記錄

    logging.warning(msg,*args,**kwargs)  建立一條嚴重級別為warning的日誌記錄

    logging.error(msg,*args,**kwargs)  建立一條嚴重界別為error的日誌記錄

    logging.critical(msg,*args,**kwargs) 建立一條嚴重級別為CRITICAL的日誌記錄

    logging.log(level,*args,**kwargs)  建立一條嚴重級別為level的日誌記錄

    logging.basicConfig(**kwargs)   對root logger 進行一次性配置(用於指定“要記錄的日誌級別”,日誌輸出位置,日誌檔案的開啟模式)

  logging模組的四大元件:

    loggers: 提供應用程式程式碼直接使用的介面

    handlers: 用於將日誌記錄傳送到指定的目的位置

    filters:用於決定哪些日誌記錄將會被輸出

    formatters:用於控制日誌資訊的最終輸出格式

  四大元件之間的關係:

    日誌器: 需要通過處理器(handler)將日誌資訊輸出到目標位置

    不同的處理器可以將日誌輸出到不同的位置

    不同的日誌器可以設定多個處理器 將同一條日誌記錄到不同的位置

    每個處理器都可以設定自己的格式器

    總結: 日誌器是入口, 處理器處理,處理器可以通過過濾器和格式器做過濾和格式化處理

Logger類
Logger物件有3個任務要做:

1)嚮應用程式程式碼暴露幾個方法,使應用程式可以在執行時記錄日誌訊息;
2)基於日誌嚴重等級(預設的過濾設施)或filter物件來決定要對哪些日誌進行後續處理;
3)將日誌訊息傳送給所有感興趣的日誌handlers。
Logger物件最常用的方法分為兩類:配置方法 和 訊息傳送方法

最常用的配置方法如下:

方法    描述
Logger.setLevel()    設定日誌器將會處理的日誌訊息的最低嚴重級別
Logger.addHandler() 和 Logger.removeHandler()    為該logger物件新增 和 移除一個handler物件
Logger.addFilter() 和 Logger.removeFilter()    為該logger物件新增 和 移除一個filter對
Handler類
Handler物件的作用是(基於日誌訊息的level)將訊息分發到handler指定的位置(檔案、網路、郵件等)。Logger物件可以通過addHandler()方法為自己新增0個或者更多個handler物件。比如,一個應用程式可能想要實現以下幾個日誌需求:

1)把所有日誌都發送到一個日誌檔案中;
2)把所有嚴重級別大於等於error的日誌傳送到stdout(標準輸出);
3)把所有嚴重級別為critical的日誌傳送到一個email郵件地址。
這種場景就需要3個不同的handlers,每個handler複雜傳送一個特定嚴重級別的日誌到一個特定的位置。
一個handler中只有非常少數的方法是需要應用開發人員去關心的。對於使用內建handler物件的應用開發人員來說,似乎唯一相關的handler方法就是下面這幾個配置方法:

方法    描述
Handler.setLevel()    設定handler將會處理的日誌訊息的最低嚴重級別
Handler.setFormatter()    為handler設定一個格式器物件
Handler.addFilter() 和 Handler.removeFilter()    為handler新增 和 刪除一個過濾器物件

 

import logging
 
logging.debug('This is a debug log.')
logging.warning('this is a warning log.')

# 相當於

logging.log(logging.DEBUGE, 'this is a debug log.')
logging.log(logging.WARNING,'this is a warnging log.')

# 輸出結果

WARNING:root:This is a warning log.

# 重點: 當沒有提供任何配置資訊的時候,這些函式都會去調logging.basicConfig(**kwargs) 且不會向該方法傳遞任何引數

 

Formater類
Formater物件用於配置日誌資訊的最終順序、結構和內容。與logging.Handler基類不同的是,應用程式碼可以直接例項化Formatter類。另外,如果你的應用程式需要一些特殊的處理行為,也可以實現一個Formatter的子類來完成。

Formatter類的構造方法定義如下:

logging.Formatter.__init__(fmt=None, datefmt=None, style='%')
可見,該構造方法接收3個可選引數:

fmt:指定訊息格式化字串,如果不指定該引數則預設使用message的原始值
datefmt:指定日期格式字串,如果不指定該引數則預設使用"%Y-%m-%d %H:%M:%S"
style:Python 3.2新增的引數,可取值為 '%', '{''$',如果不指定該引數則預設使用'%'

  logging.basicConfig() 函式引數說明:

    filename: 指定日誌輸出目標檔案的檔名,指定該設定項後日志信心就不會被輸出到控制檯了

    filemode: 指定日誌檔案的開啟模式,預設為'a'。需要注意的是,該選項要在filename指定時才有效

    format: 指定日誌格式字串,即指定日誌輸出時所包含的欄位資訊以及它們的順序

    datefmt: 指定日期/時間格式。需要注意的是,該選項要在format中包含時間欄位%(asctime)s時才有效

    level: 指定日誌器的日誌級別

    stream: 指定日誌輸出目標stream,如sys.stdout、sys.stderr以及網路stream。stream和filename不能同時提供,否則會引發 ValueError異常

    style:指定format格式字串的風格,可取值為'%'、'{'和'$',預設為'%'

    handlers: 它應該是一個建立了多個Handler的可迭代物件,這些handler將會被新增到root logger。注意:filename、stream和handlers這三個配置項只能有一個存在

  format 格式:

    

欄位/屬性名稱 使用格式 描述
asctime %(asctime)s 日誌事件發生的時間--人類可讀時間,如:2003-07-08 16:49:45,896
created %(created)f 日誌事件發生的時間--時間戳,就是當時呼叫time.time()函式返回的值
relativeCreated %(relativeCreated)d 日誌事件發生的時間相對於logging模組載入時間的相對毫秒數(目前還不知道幹嘛用的)
msecs %(msecs)d 日誌事件發生事件的毫秒部分
levelname %(levelname)s 該日誌記錄的文字形式的日誌級別('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
levelno %(levelno)s 該日誌記錄的數字形式的日誌級別(10, 20, 30, 40, 50)
name %(name)s 所使用的日誌器名稱,預設是'root',因為預設使用的是 rootLogger
message %(message)s 日誌記錄的文字內容,通過 msg % args計算得到的
pathname %(pathname)s 呼叫日誌記錄函式的原始碼檔案的全路徑
filename %(filename)s pathname的檔名部分,包含檔案字尾
module %(module)s filename的名稱部分,不包含字尾
lineno %(lineno)d 呼叫日誌記錄函式的原始碼所在的行號
funcName %(funcName)s 呼叫日誌記錄函式的函式名
process %(process)d 程序ID
processName %(processName)s 程序名稱,Python 3.1新增
thread %(thread)d 執行緒ID
threadName %(thread)s 執行緒名稱
#配置日誌輸出
import logging
logging.basicConfig(level=logging.DEBUG

LGO_FORMAT='%(asctime)s-%(levelname)s-%(message)s'
DATE_FORMAT='%m/%d/%Y %H:%M:%S %p'
logging.basicConfig(filename='mylog', level=logging.DEBUG,format=LOG_FORMAT, datefmt=DATE_FORMA

 

二. shelve 模組

  用來序列化模組,只有一個open函式,用open開啟一個檔案當做字典來使用,自動完成序列化

  支援python的所有基礎資料型別,只能被python使用

  無法跨平臺使用,當程式是單機程式時可用

s=shelve.open('test.she')
s['name']='egon' # 開啟檔案,預設為一個字典,為字典增加鍵值對,自動將寫入的內容序列化

s=shelve.open('test.she')
print(s['name']) # 開啟檔案,直接取檔案中內容

 

三. sys 模組

  system: 表示直譯器                   os(operation system) 表示作業系統

  sys.argv  ===>  接收的是作業系統呼叫直譯器時傳入的引數(開發一款不帶介面的程式,只能在終端(cmd)應用

  print(sys.srgv)  ===> 預設為檔案的路徑

  sys.argv 

# 需求: 開發一個基於cmd的複製檔案的工具
# sys.argv 接收引數
# 引數1:被執行的py檔案
# 引數2: 原始檔路徑
# 引數3: 目標檔案路徑

  sys.exit(0)   0 表示正常退出

  sys.version  表示直譯器版本

  sys.platform  表示系統