1 回答

TA貢獻2012條經驗 獲得超12個贊
正如您已經發(fā)現(xiàn)的那樣,如果進程不干凈地終止,嘗試在進程生命周期結束時執(zhí)行清理可能會失敗。
在開始時執(zhí)行清理的問題是,您顯然在logging.basicConfig嘗試移動舊日志文件之前從導入中調用。當您嘗試重命名和移動它時,
這會導致在現(xiàn)有日志上隱式創(chuàng)建一個打開的文件對象。FileHandler根據(jù)您使用的文件系統(tǒng),這可能不會讓人高興。
如果您想將潛在的舊日志文件的處理完全移至應用程序的開頭,則必須在調用之前執(zhí)行重命名和移動logging.basicConfig,因此您必須將其從導入中刪除并以log_management某種方式添加到。
作為替代方案,您可以通過子類化標準FileHandler類將日志文件的整個處理移動到日志文件處理程序,例如:
import logging
import os
from datetime import datetime
class CustomFileHandler(logging.FileHandler):
? ? def __init__(self, filename, archive_path='archive', archive_name='log_%Y%m%d', **kwargs):
? ? ? ? self._archive = os.path.join(archive_path, archive_name)
? ? ? ? self._archive_log(filename)
? ? ? ? super().__init__(filename, **kwargs)
? ? def _archive_log(self, filepath):
? ? ? ? if os.path.exists(filepath):
? ? ? ? ? ? os.rename(filepath, datetime.now().strftime(self._archive))
? ? def close(self):
? ? ? ? super().close()
? ? ? ? self._archive_log(self.baseFilename)
有了這個,您可以像這樣配置您的日志記錄:
hdler = CustomFileHandler('current.log')
logging.basicConfig(level=logging.INFO, handlers=[hdler],?
? ? ? ? ? ? ? ? ? ?format='%(asctime)s:%(levelname)s:%(message)s')
將CustomFileHandler
在初始化期間檢查并可能存檔舊日志。這將處理無法進行關閉清理的不干凈進程終止后的剩余物。由于在嘗試日志歸檔之后調用了父類初始值設定項,因此日志上還沒有打開的句柄會導致PermissionError
.
覆蓋的close()
方法將在干凈的進程關閉時執(zhí)行歸檔。
這應該消除對專用模塊的需要log_management
,至少就您在代碼中顯示的功能而言。rename_log
,move_log
并且check_log_on_startup
都封裝在CustomFileHandler
.?也無需顯式調用logging.shutdown()
.
一些注意事項:
找不到等效的啟動函數(shù)的原因logging.shutdown()
是在導入logging
模塊時啟動/初始化了日志系統(tǒng)。除其他外,它實例化隱式根記錄器并通過atexit注冊logging.shutdown
為退出處理程序。?后者是無需顯式調用上述解決方案的原因。Python 解釋器將在準備因退出處理程序注冊而關閉解釋器時在完成期間調用它。然后遍歷已注冊處理程序的列表并調用它們的方法,這將在干凈關閉期間執(zhí)行日志歸檔。logging.shutdown()
logging.shutdown()
close()
根據(jù)您選擇的移動(和重命名)舊日志文件的方法,上述解決方案可能需要一些額外的異常保護措施。os.rename
如果目標路徑已經存在,即當您已經在同一天停止并啟動您的進程時,將引發(fā)異常,同時os.replace
會靜默覆蓋現(xiàn)有文件。
因此,我建議不僅按當前日期而且按時間命名歸檔日志。
在上面,將當前日期添加到存檔文件名是通過datetime
's完成的strftime
,因此 'log_?%Y%m%d?' 作為archive_name
自定義文件處理程序參數(shù)的默認值。前面的字符%
是有效的格式代碼,替換為調用它的對象strftime()
的相應部分。datetime
要將當前時間附加到存檔日志文件名,您只需將相應的格式代碼附加到archive_name
,例如:'log_%Y%m%d_?%H%M%S?',這將導致日志名稱,例如log_20200819_123721
.
添加回答
舉報