如果直接运行,Python模块会生成日志,但由`pytest`运行时,Python模块不会生成日志

时间:2019-02-07 03:24:55

标签: python logging python-watchdog

我是python日志记录的新手,并且想为项目创建可靠的日志记录设置,以使用watchdog将DICOM文件的创建记录在给定目录中。我的项目结构是:

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


到目前为止,我在LOGGING_DICT中有一个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时不同)!

当在监视的文件夹中创建有效的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

0 个答案:

没有答案