天天看點

python logging子產品的分檔案存放

如果使用進到的日志檔案方法:

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
  • 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] 另一個程式正在使用此檔案,程序無法通路。
           

解決方法:

  1. 設定

    delay=True

  2. 使用第三方庫

    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
           

繼續閱讀