我是 python 日志记录的新手,想为一个项目创建一个可靠的日志记录设置,用于watchdog
记录给定目录中 DICOM 文件的创建。我的项目结构是:
planqa\
src\
watcher.py
qa_logger.py
logs\
qa_watch.log
tests\
test_watchdog.py
到目前为止,我有一个LOGGING_DICT
in qa_logger.py
。LOGGING_DICT
被导入watcher.py
(并最终导入其他模块),然后在顶部附近watcher.py
,我放了以下几行:
logging.config.dictConfig(LOGGING_DICT)
logger = logging.getLogger()
当我运行时python watcher.py
,所有日志都生成得很好。日志既打印到控制台又写入文件src\logs\qa_watch.log
。
当我运行时出现问题pytest
。根本不生成日志。然而,奇怪的是,如果文件不存在,src\logs\qa_watch.log
则会创建python watcher.py
该文件,但它从未被写入(与我运行时不同)!
我想pytest
用来验证src\logs\qa_watch.log
在监视文件夹中创建有效 DICOM 文件时是否生成了日志。
任何帮助将不胜感激,包括关于如何更好地构建事物的任何评论!我仍然(并且永远会)学习!
编辑:日志级别不是问题。如果我使用logger.warning()
而不是logger.info()
登录,我会遇到同样的问题watcher.py
。
文件:
# qa_logger.py
import logging
from logging.config import dictConfig
import os
from os.path import dirname, join as pjoin
import sys
LOG_DIR = pjoin(dirname(dirname(__file__)), "logs")
LOGGING_DICT = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'f': {
'format': '%(asctime)s %(name)-12s %(levelname)-8s: %(message)s'
}
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'formatter': 'f',
'level': logging.DEBUG
},
'file': {
'class': 'logging.handlers.TimedRotatingFileHandler',
'level': logging.DEBUG,
'formatter': 'f',
'filename': pjoin(LOG_DIR, "qa_watch.log"),
'when': 'midnight',
'interval': 1,
'backupCount': 30
}
},
'root': {
'handlers': ['console', 'file'],
'level': logging.DEBUG,
},
}
# watcher.py
import logging
from time import sleep
from os.path import abspath, dirname, join as pjoin
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
from src.qa_logger import LOGGING_DICT
logging.config.dictConfig(LOGGING_DICT)
logger = logging.getLogger()
class NewFileHandler(PatternMatchingEventHandler):
patterns = ['*.dcm']
ignore_patterns = None
case_sensitive = False
ignore_directories = True
def on_created(self, event):
msg = "Caught creation of {}".format(event.src_path)
logger.info(msg)
def watch_for_dicoms_created_in_folder(folder=None):
if folder is None:
folder = abspath(pjoin(dirname(dirname(__file__)), "tests", "data"))
dcm_handler = NewFileHandler()
observer = Observer()
observer.schedule(dcm_handler, folder, recursive=True)
observer.start()
logger.info("----- Started watcher -----")
try:
while True:
sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
if __name__ == "__main__":
watch_for_dicoms_created_in_folder()
# test_watchdog.py
import logging
import os
from os.path import dirname, join as pjoin, isfile
from multiprocessing import Process
from time import sleep
from src.watcher import watch_for_dicoms_created_in_folder
from src.qa_logger import LOG_DIR
DATA_DIR = pjoin(dirname(__file__), "data")
LOG_PATH = pjoin(LOG_DIR, "qa_watch.log")
def test_watching_for_file_creation():
dcm_test_filepath = pjoin(DATA_DIR, "a_dcm_to_catch.dcm")
nondcm_test_filepath = pjoin(DATA_DIR, "not_a_dcm_to_catch.txt")
# Watcher is run in a separate process or subsequent code will not execute
watch1 = Process(name='watch1', target=watch_for_dicoms_created_in_folder)
watch1.start()
dcm_test_file = open(dcm_test_filepath, 'w')
nondcm_test_file = open(nondcm_test_filepath, 'w')
dcm_test_file.close()
nondcm_test_file.close()
sleep(0.2) # Give watcher time to see files and create logfile
watch1.terminate()
assert isfile(LOG_PATH)
with open(LOG_PATH) as logfile:
assert dcm_test_filepath in logfile
assert not nondcm_test_filepath in logfile
# Cleanup
try:
os.remove(dcm_test_filepath)
os.remove(nondcm_test_filepath)
except OSError:
pass