1

我是 python 日志记录的新手,想为一个项目创建一个可靠的日志记录设置,用于watchdog记录给定目录中 DICOM 文件的创建。我的项目结构是:

planqa\
    src\
        watcher.py
        qa_logger.py
        logs\
            qa_watch.log
    tests\
        test_watchdog.py


到目前为止,我有一个LOGGING_DICTin qa_logger.pyLOGGING_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
4

0 回答 0