更新:原始問題似乎無效,因為即使我設法強制 logger 使用datetime.now(),它仍然沒有解決我的最終目標,即在不重新啟動 python 解釋器的情況下使日志時間戳回應作業系統時區更改。我已經提供了我在下面找到的答案。
如何強制記錄器使用datetime.now()而不是time.asctime()?我需要日志嚴格遵循 Windows 作業系統提供的時間,但time.asctime()如果認為需要,則嘗試轉換時區。如何覆寫此行為?
目前我使用帶有格式字串的自定義 logging.format 子類 '{asctime}: {levelname} - {message}'
這樣做的目的是因為我的 python 腳本在執行程序中更改了作業系統時區。我希望日志在腳本更改后立即遵循更新的時區。我試圖converter在logging.format子類中定義一個函式,但這導致日志中的時區即使在我更改后也沒有更新。
我使用的代碼(來自 doc https://docs.python.org/3.9/library/logging.html#logging.Formatter.formatTime):
class custom(logging.Formatter):
def converter(self, timestamp):
return datetime.now()
從這里嘗試了每個答案:如何更改 Python 日志記錄中的時區?,不作業,因為它們都不會更新到我的腳本在作業系統中設定的新時區。我試過了importlib.reload(tzlocal),也沒有用。
我發現的唯一明智的答案是使用,time.tzset()但它顯然在 Windows 上不可用
uj5u.com熱心網友回復:
經過一些研究,我使用 解決了我自己的問題ctypes,這是受到這個答案的啟發。本質上,我logging.Formatter.formatTime通過添加對 Windows 系統 API 的呼叫來覆寫該函式以獲取當前系統時間。這是一種與所有現有 python 模塊(time, datetime, pytz等)完全不同的方法,因為在啟動 python 解釋器時不緩沖時區資訊。
代碼:
class real_time_formatter(logging.Formatter):
def formatTime(self, record, datefmt=None):
class SYSTEMTIME(ctypes.Structure):
_fields_ = [('wYear', ctypes.c_int16),
('wMonth', ctypes.c_int16),
('wDayOfWeek', ctypes.c_int16),
('wDay', ctypes.c_int16),
('wHour', ctypes.c_int16),
('wMinute', ctypes.c_int16),
('wSecond', ctypes.c_int16),
('wMilliseconds', ctypes.c_int16)]
lpSystemTime = ctypes.pointer(SystemTime)
ctypes.windll.kernel32.GetLocalTime(lpSystemTime)
year = '0' * (4 - len(str(SystemTime.wYear))) str(SystemTime.wYear)
month = '0' * (2 - len(str(SystemTime.wMonth))) str(SystemTime.wMonth)
day = '0' * (2 - len(str(SystemTime.wDay))) str(SystemTime.wDay)
hour = '0' * (2 - len(str(SystemTime.wHour))) str(SystemTime.wHour)
minute = '0' * (2 - len(str(SystemTime.wMinute))) str(SystemTime.wMinute)
second = '0' * (2 - len(str(SystemTime.wSecond))) str(SystemTime.wSecond)
ms = '0' * (3 - len(str(SystemTime.wMilliseconds))) str(SystemTime.wMilliseconds)
return f'{year}-{month}-{day} {hour}:{minute}:{second}:{ms}' # 2003-01-23 00:29:50,411
streamHandler.setFormatter(real_time_formatter())
這模仿了 python{asctime}格式,當然你可以隨意更改它,因為它只是一個 f 字串。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/370538.html
