一、logging的基礎使用
1、logging的級別
import logging logging.debug('debug message') # 計算或者工作的細節 logging.info('info message') # 記錄一些用戶的增刪改查的操作 logging.warning('warning operation') # 警告操作 logging.error('error message') # 錯誤操作 logging.critical('critical message') # 致命的錯誤 直接導致程序出錯退出的 結果: WARNING:root:warning operation ERROR:root:error message CRITICAL:root:critical message 從上面可以看出: 默認情況下Python的logging模塊將日志打印到了標准輸出中,且只顯示了大於等於warning級別的日志, 這說明默認的日志級別設置為WARNING(日志級別等級critical > error > warning > info > debug), 默認的日志格式為日志級別:level級別:用戶:輸出消息。
2、簡單配置
logging.basicConfig()函數中可通過具體參數來更改logging模塊默認行為 import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%Y-%m-%d %H:%M', # 把asctime的時間格式改為:年-月-日 時:分 filename='test.log', filemode='w') logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message') (簡單配置中文顯示的是亂碼) 參數說明: level:設置logger的日志級別(大於等於這個參數的級別都會顯示) format:指定handler使用的日志顯示格式。 datefmt:指定日期時間格式。 filename:用指定的文件名創建FiledHandler,這樣日志會被存儲在指定的文件中。 filemode:文件打開方式,在指定了filename時使用這個參數,默認值為“a”還可指定為“w”。 stream:用指定的stream創建StreamHandler。可以指定輸出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)), 默認為sys.stderr。若同時列出了filename和stream兩個參數,則stream參數會被忽略。 format參數中可能用到的格式化串: %(asctime)s 字符串形式的當前時間。默認格式是 “2003-07-08 16:49:45,896”。逗號后面的是毫秒(可用datefmt修改默認日期時間格式。) %(filename)s 調用日志輸出函數的模塊的文件名 %(lineno)d 調用日志輸出函數的語句所在的代碼行 %(levelname)s 日志級別 %(message)s用戶輸出的消息 %(name)s 用戶的名字 %(levelno)s 數字形式的日志級別 %(pathname)s 調用日志輸出函數的模塊的完整路徑名,可能沒有 %(module)s 調用日志輸出函數的模塊名 %(funcName)s 調用日志輸出函數的函數名 %(created)f 當前時間,用UNIX標准的表示時間的浮 點數表示 %(relativeCreated)d 輸出日志信息時的,自Logger創建以 來的毫秒數 %(thread)d 線程ID。可能沒有 %(threadName)s 線程名。可能沒有 %(process)d 進程ID。可能沒有
3、對象的配置
import logging logger = logging.getLogger() # 創建一個log對象 logger.setLevel(logging.DEBUG) # 設置顯示級別 # 還要創建一個控制文件輸出的文件操作符 fh = logging.FileHandler('mylog.log', encoding='utf-8') # 指定編碼可以解決中文亂碼問題 # 還要創建一個控制屏幕輸出的屏幕操作符 sh = logging.StreamHandler() # 要創建一個格式(多個格式也可以) fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s [line:%(lineno)d]') # 文件操作符綁定一個格式 fh.setFormatter(fmt) # fh.setLevel(logging.WARNING) # 可以設置寫入文件的級別,不設置的話就默認用log對象設置的級別(一般全部級別的信息都寫進去) # 屏幕操作符綁定一個格式 sh.setFormatter(fmt) sh.setLevel(logging.WARNING) # 可以設置屏幕打印的級別,不設置的話就默認用log對象設置的級別 # 但是不能設置比log對象設置的級別低,否則只會執行log對象的級別,比如:log對象設置的級別是WARNING,你這里設置INFO,級別 # 沒有WARNING高,不會顯示 # logger對象來綁定:文件操作符, 屏幕操作符 logger.addHandler(sh) logger.addHandler(fh) logger.debug('debug message') # 計算或者工作的細節 logger.info('info message') # 記錄一些用戶的增刪改查的操作 logger.warning('warning message') # 警告操作 logger.error('error message') # 錯誤操作 logger.critical('critical message') # 批判的 直接導致程序出錯退出的
4、工作中的使用案例
import logging def init_log(data): log_id = data.get("log_id", None) # 從參數中獲取日志id logger = logging.getLogger(str(log_id)) # 根據log_id創建一個log對象 logger.setLevel(logging.INFO) # 設置顯示級別 # 避免重復生成新的logger,日志多次寫入的問題 # 避免這種情況:第一條記錄寫一次,第二條記錄寫兩次,第三條記錄寫三次 if not logger.handlers: fh = logging.FileHandler('mylog.log', encoding='utf-8') # 創建一個控制文件輸出的文件操作符 # 創建一個日志輸出格式 fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s [line:%(lineno)d]') # 文件操作符綁定一個格式 fh.setFormatter(fmt) # fh.setLevel(logging.WARNING) # 可以設置寫入文件的級別,不設置的話就默認用log對象設置的級別 # logger對象來綁定:文件操作符 logger.addHandler(fh) def write_log(data): log_id = data.get("log_id", None) # 從參數中獲取日志id logger = logging.getLogger(str(log_id)) # 根據log_id創建一個log對象 # 在需要打印日志的地方,直接打印日志即可,上面的init_log已經實例化完畢 logger.error("錯啦!")
二、自動刪除功能
1、通過時間設置備份並刪除
通過TimedRotatingFileHandler可以把輸出重定向到文件,它會對比文件最后修改時間和當前時間,如果比設置的時候大,則會把當前文件加時間后綴備份,然后,新建一個進行Log。
import logging from logging.handlers import TimedRotatingFileHandler def init_log(data): log_id = data.get("log_id", None) logger = logging.getLogger(str(log_id)) logger.setLevel(logging.INFO) if not logger.handlers: # 這里設置成TimedRotatingFileHandler # 創建一個由時間控制的文件操作符:每天生成一個文件 tfh = TimedRotatingFileHandler(filename='mylog.log', when="D", interval=1, backupCount=3) fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s [line:%(lineno)d]') tfh.setFormatter(fmt) logger.addHandler(tfh) def write_log(data): log_id = data.get("log_id", None) logger = logging.getLogger(str(log_id)) # 在需要打印日志的地方,直接打印日志即可,上面的init_log已經實例化完畢 logger.error("錯啦!")
- filename:日志文件名的prefix;
- when:是一個字符串,用於描述滾動周期的基本單位,字符串的值及意義如下:
“S”: Seconds
“M”: Minutes
“H”: Hours
“D”: Days
“W”: Week day (0=Monday)
“midnight”: Roll over at midnight - interval: 滾動周期,單位有when指定,比如:when=’D’,interval=1,表示每天產生一個日志文件;
- backupCount: 表示日志文件的保留個數;
例如上面的結果會這樣:
如果到22號,那么19號的會自動刪除,生成22號的日志
2、通過文件大小設置備份並刪除
使用RotatingFileHander對log的文件大小進行限制
import logging from logging.handlers import RotatingFileHandler def init_log(data): log_id = data.get("log_id", None) logger = logging.getLogger(str(log_id)) logger.setLevel(logging.INFO) if not logger.handlers: # 創建一個由文件大小控制的文件操作符 # 文件大小最大為1MB,超過時自動備份,最多備份3個,超過三個刪除最早的記錄 tfh = RotatingFileHandler(filename='mylog.log', maxBytes=1024 * 1024, backupCount=3) fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s [line:%(lineno)d]') tfh.setFormatter(fmt) logger.addHandler(tfh) def write_log(data): log_id = data.get("log_id", None) logger = logging.getLogger(str(log_id)) # 在需要打印日志的地方,直接打印日志即可,上面的init_log已經實例化完畢 logger.error("錯啦!")
結果如下:
最多產生3個備份文件,每個文件最大為1MB,3個文件都超過1MB時,自動清理最早的日志。