如果使用進到的日志檔案方法:
logging.FileHandler
,會導緻日志資訊全部存放在一個日志檔案中,不利于後面對日志檔案的使用。
下面分享常見的兩種分檔案存儲日志的方法。
delay = True
參數避免了出現多程序中讀取日志權限的問題
- TimedRotatingFileHandler 根據時間建立日志檔案
TimedRotatingFileHandler(filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None)
Attribute name Description filename 日志檔案名字首 when 日志名變更時間機關 interval 間隔時間,是指等待N個when機關的時間後,自動重建檔案 backupCount 保留日志最大檔案數,超過限制,删除最先建立的檔案;預設值0,表示不限制。 delay 延遲檔案建立,直到第一次調用emit()方法建立日志檔案 atTime 在指定的時間(datetime.time格式)建立日志檔案。 - atTime 與 when參數之間的關系
Value Type of interval If/how atTime is used ‘S’ Seconds Ignored ‘M’ Minutes Ignored ‘H’ Hours Ignored ‘D’ Days Ignored ‘W0’-‘W6’ Weekday (0=Monday) Used to compute initial rollover time ‘midnight’ Roll over at midnight, if atTime not specified, else at time atTime Used to compute initial rollover time
- atTime 與 when參數之間的關系
- RotatingFileHander 根據日志檔案大小建立日志檔案
RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=False)
Attribute name Description filename 指定日志檔案名 filemode 和file函數意義相同,指定日志檔案的打開模式,‘w’或’a’ maxBytes 用于指定日志檔案的最大檔案大小。如果maxBytes為0,意味着日志檔案可以無限大 backupCount 保留日志最大檔案數,超過限制,删除最先建立的檔案;預設值0,表示不限制 delay 延遲檔案建立,直到第一次調用emit()方法建立日志檔案 - 分檔案時,PermissionError異常處理
異常資訊:
--- Logging error ---
Traceback (most recent call last):
'省略部分資訊'
PermissionError: [WinError 32] 另一個程式正在使用此檔案,程序無法通路。
解決方法:
- 設定
delay=True
- 使用第三方庫
concurrent_log_handler.ConcurrentRotatingFileHandler
代碼實作:customer_log.py
import logging
from logging import handlers
from concurrent_log_handler import ConcurrentRotatingFileHandler
def set_basic_logger():
path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
log_path = path + '/Log/'
log_file = log_path + 'mockSystem.log'
err_file = log_path + 'mockSystemErr.log'
# 定制輸出格式
formatter = logging.Formatter(
'[%(asctime)s] %(filename)s -> %(funcName)s line:%(lineno)d [%(levelname)s] : %(message)s')
# # 所有日志在一個檔案中存儲
# handler = logging.FileHandler(log_file, encoding='utf-8', mode='a+')
# 按天分檔案存儲,儲存最近30天的日志
handler = handlers.TimedRotatingFileHandler(log_file, when='d', interval=1, backupCount=30, encoding='utf-8', delay=True)
# 按檔案大小分檔案存儲,每個檔案10位元組,保留10個檔案
# handler = handlers.RotatingFileHandler(log_file, maxBytes=10, backupCount=10,
# encoding='utf-8', delay=True)
# 按檔案大小分檔案存儲,每個檔案10位元組,保留10個檔案
# handler = ConcurrentRotatingFileHandler(log_file, maxBytes=10, backupCount=10)
handler.setLevel(logging.INFO)
handler.setFormatter(formatter)
# err_handler = ConcurrentRotatingFileHandler(err_file, encoding='utf-8', mode='a+') # 輸出到err_log檔案
err_handler = handlers.TimedRotatingFileHandler(err_file, when='d', interval=1, backupCount=30,
encoding='utf-8', delay=True)
# err_handler = handlers.RotatingFileHandler(err_file, maxBytes=10, backupCount=10,
# encoding='utf-8', delay=True)
# err_handler = ConcurrentRotatingFileHandler(err_file, maxBytes=10, backupCount=10)
err_handler.setLevel(logging.WARNING)
err_handler.setFormatter(formatter)
logging.basicConfig(
level=logging.DEBUG,
format='[%(asctime)s] %(filename)s -> %(funcName)s line:%(lineno)d [%(levelname)s] : %(message)s',
handlers=[handler, err_handler]
)
在項目主程式中使用時:main.py
from customer_log imoprt set_basic_logger
import mu
set_basic_logger()
mu.show_cur_info()
在項目其他子產品使用時:mu.py
import logging
def show_cur_info():
msg = 'dddddd'
print(msg)
logging.info(msg