導入 logging 模塊
import logging
日志級別
DEBUG- 詳細信息,典型地調試問題時會感興趣
INFO- 證明事情按預期工作
WARNING- 表明發生了一些意外
- 或者不久的將來會發生問題(如‘磁盤滿了’)
- 但是軟件還是在正常工作
ERROR- 由於更嚴重的問題,軟件已不能執行一些功能了
CRITICAL- 嚴重錯誤,表明軟件已不能繼續運行了
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
配置
# 通過下面的方式進行簡單配置輸出方式與日志級別 logging.basicConfig(filename='logger.log', level=logging.INFO)
幾個重要的概念
- Logger,記錄器,暴露了應用程序代碼能直接使用的接口。
- Handler,處理器,將(記錄器產生的)日志記錄發送至合適的目的地。
- Filter,過濾器,提供了更好的粒度控制,它可以決定輸出哪些日志記錄。
- Formatter,格式化器,指明了最終輸出中日志記錄的布局。
Logger 記錄器
- Logger 是一個樹形層級結構
- 在使用接口 debug,info,warning,error,critical 之前必須創建 Logger 實例
- 即創建一個記錄器
- 如果沒有顯式的進行創建,則默認創建一個 root logger
- 並應用默認的日志級別(WARNING)
- 處理器 Handler(StreamHandler,即將日志信息打印輸出在標准輸出上)
- 格式化器 Formatter(默認的格式即為第一個簡單使用程序中輸出的格式)
logger = logging.getLogger(logger_name) # 設置日志級別為ERROR,即只有日志級別大於等於ERROR的日志才會輸出 logger.setLevel(logging.ERROR) # 為Logger實例增加一個處理器 logger.addHandler(handler_name) # 為Logger實例刪除一個處理器 logger.removeHandler(handler_name)
Handler 處理器
Handler 處理器類型有很多種,比較常用的有三個
StreamHandlerFileHandlerNullHandler
sh = logging.StreamHandler(stream=None) fh = logging.FileHandler(filename, mode='a', encoding=None, delay=False) # NullHandler類位於核心logging包,不做任何的格式化或者輸出 # 本質上它是個“什么都不做”的handler,由庫開發者使用 nf = logging.NullHandler()
創建 StreamHandler 之后
- 可以通過使用以下方法設置日志級別
- 設置格式化器 Formatter
- 增加或刪除過濾器 Filter
# 指定日志級別,低於 WARNING 級別的日志將被忽略 handler.setLevel(logging.WARNING) # 設置一個格式化器 formatter handler.setFormatter(formatter_name) # 增加一個過濾器,可以增加多個 handler.addFilter(filter_name) # 刪除一個過濾器 handler.removeFilter(filter_name)
Formatter 格式化器
- 使用 Formatter 對象設置日志信息最后的規則、結構和內容
- 默認的時間格式為
%Y-%m-%d %H:%M:%S
# fmt是消息的格式化字符串,如果不指明fmt,將使用'%(message)s' # datefmt是日期字符串,如果不指明datefmt,將使用ISO8601日期格式。 formatter = logging.Formatter(fmt=None, datefmt=None)
Filter 過濾器
- Handlers 和 Loggers 可以使用 Filters 來完成比級別更復雜的過濾
- Filter 基類只允許特定 Logger 層次以下的事件
filter = logging.Filter(name='')
import logging
# create logger
logger_name = "example"
logger = logging.getLogger(logger_name)
logger.setLevel(logging.DEBUG)
# create file handler
log_path = "demo03.log"
fh = logging.FileHandler(log_path)
fh.setLevel(logging.WARNING)
# create formatter
fmt = "%(asctime)-15s %(levelname)s %(filename)s %(lineno)d %(process)d %(message)s"
datefmt = "%a %d %b %Y %H:%M:%S"
formatter = logging.Formatter(fmt, datefmt)
# add handler and formatter to logger
fh.setFormatter(formatter)
logger.addHandler(fh)
# print log info
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')
配置方式
- 顯式創建記錄器 Logger、處理器 Handler 和格式化器 Formatter,並進行相關設置
- 通過簡單方式進行配置,使用
basicConfig()函數直接進行配置 - 通過配置文件進行配置,使用
fileConfig()函數讀取配置文件 - 通過配置字典進行配置,使用
dictConfig()函數讀取配置信息 - 通過網絡進行配置,使用
listen()函數進行網絡配置
basicConfig 關鍵字參數
filename- 創建一個 FileHandler,使用指定的文件名,而不是使用 StreamHandler
filemode- 如果指明了文件名,指明打開文件的模式(如果沒有指明 filemode,默認為
a)
- 如果指明了文件名,指明打開文件的模式(如果沒有指明 filemode,默認為
format- handler 使用指明的格式化字符串
datefmt- 使用指明的日期/時間格式
level- 指明根 logger 的級別
stream- 使用指明的流來初始化 StreamHandler,該參數與
filename不兼容, - 如果兩個都有,
stream被忽略
- 使用指明的流來初始化 StreamHandler,該參數與
format 格式
%(levelno)s,打印日志級別的數值%(levelname)s,打印日志級別名稱%(pathname)s,打印當前執行程序的路徑%(filename)s,打印當前執行程序名稱%(funcName)s,打印日志的當前函數%(lineno)d,打印日志的當前行號%(asctime)s,打印日志的時間%(thread)d,打印線程 ID%(threadName)s,打印線程名稱%(process)d,打印進程 ID%(message)s,打印日志信息
datefmt 格式
%a,本地的縮寫工作日名稱%A,本地的完整工作日名稱%b,本地的縮寫月份名稱%B,本地的全月名稱%c,本地的適當日期和時間表示%d,每月的一天作為小數 [01,31]%H,小時(24 小時時鍾)作為小數 [00,23]%I,小時(12 小時時鍾)作為小數目 [01,12]%j,一年中的一天作為小數 [001,366]%m,月作為小數 [01,12]%M,分鍾作為小數 [00,59]%p,本地相當於上午或下午%S,第二為小數 [00,61]%U,年度周數(星期日為一周的第一天)為小數 [00,53]- 第一個星期天前的新年中的所有日子都被認為是在第 0 周
%w,平日作為小數 [0 (星期日), 6]%W,年度周數(星期一為一周的第一天)為小數 [00,53]- 第一個星期一之前的新年的所有日子都被認為是在第 0 周
%x,本地的適當日期表示%X,本地的適當時間表示%y,沒有世紀的年份作為小數 [00,99]%Y,以世紀為小數的年份%Z,時區名稱(如果沒有時區,則不存在字符)%%,字面意思%
[loggers]
keys=root,example01
[logger_root]
level=DEBUG
handlers=hand01,hand02
[logger_example01]
handlers=hand01,hand02
qualname=example01
propagate=0
[handlers]
keys=hand01,hand02
[handler_hand01]
class=StreamHandler
level=INFO
formatter=form01
args=(sys.stderr,)
[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form02
args=('demo04.log', 'a')
[formatters]
keys=form01,form02
[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
[formatter_form02]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
log.py文件
import logging
import logging.config
logging.config.fileConfig("logging.conf")
# create logger
logger_name = 'example01'
logger = logging.getLogger(logger_name)
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')
