我是python日志记录的新手,并且想为项目创建可靠的日志记录设置,以使用watchdog
将DICOM文件的创建记录在给定目录中。我的项目结构是:
planqa\
src\
watcher.py
qa_logger.py
logs\
qa_watch.log
tests\
test_watchdog.py
到目前为止,我在LOGGING_DICT
中有一个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
时不同)!
当在监视的文件夹中创建有效的DICOM文件时,我想使用pytest
来验证src\logs\qa_watch.log
中是否生成了日志。
任何帮助将不胜感激,包括对如何更好地组织事物的任何评论!我仍在(并将永远)学习!
编辑:日志级别不是问题。如果我在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