Search code examples
pythonpython-3.xpython-multithreadingpython-loggingpython-watchdog

Python Logging from Watchdog Thread


I'm writing a script which downloads some files in the main thread, and spins off a watchdog (using the Watchdog library) thread to watch the downloads folder and move them into a target folder (It must be done this way, I cannot save the files directly into the target folder).

My watchdog looks like so:

class Watcher:

    def __init__(self, directory, handler, logger):
        self.observer = Observer()
        self.handler = handler
        self.directory = directory
        self.logger = logger

    def run(self):
        self.observer.schedule(
            self.handler, self.directory, recursive=True)
        self.observer.start()
        self.logger.log(logging.DEBUG, "\nWatchdog Running in {}/\n".format(self.directory))
        try:
            while True:
                time.sleep(1)
        except:
            self.observer.stop()
        self.observer.join()
        self.logger.log(logging.DEBUG, "\nWatchdog Terminated\n")


class DownloadHandler(FileSystemEventHandler):

    def __init__(self, target_dir, logger):
        super().__init__()
        self.target_dir = target_dir
        self.logger = logger
    
    def on_created(self, event):
        self.logger.log(logging.DEBUG, event.src_path)


def start_watchdog_thread(install_dir, downloads_dir, logger):
    Watcher(downloads_dir, DownloadHandler(install_dir, logger), logger).run()

And is being run as such:

install_dir = sys.argv[1]
downloads_dir = str(Path.home() / "Downloads")
logger = logging.getLogger(LOGGER_NAME)
logger.setLevel(logging.DEBUG)
Thread(target=start_watchdog_thread, args=(install_dir, downloads_dir, logger), daemon=True, name="Watchdog").start()
...
#Start downloading files

However, when I run this, I see no messages from the logger in the console. What have I done wrong?


Solution

  • The problem was that the logger was not configured to write to stdout. I needed to configure it properly by adding a handler like so:

    logger = logging.getLogger(LOGGER_NAME)
    logger.setLevel(logging.DEBUG)
    handler = logging.StreamHandler(sys.stdout)
    handler.setLevel(logging.DEBUG)
    logger.addHandler(handler)
    
    downloads_dir = str(Path.home() / "Downloads")
    Thread(target=start_watchdog_thread, args=(install_dir, downloads_dir, logger), daemon=True, name="Watchdog").start()