Generating multiple observers with Python watchdog
Great question. This thread is older but I found it while looking up the exact thing and I expanded on your work and added the ability to pass in a file with a list of directories to watch. By default I do not look recursively, I leave that to someone else to test. Hopefully this helps anyone looking up the same topic. Great work!
Run using python watcher.py
filename.
Where watcher.py
is what I called my script and filename is the name of the file with my paths.
I list the full paths in the file and these are separated by newlines.
i.e.:
C:\path1
C:\Path2\subpath1
C:\PATH3
watcher.py
import logging
import sys
import time
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler
# Attach a logging event AKA FileSystemEventHandler
event_handler = LoggingEventHandler()
# Create Observer to watch directories
observer = Observer()
# Take in list of paths. If none given, watch CWD
paths = open(sys.argv[1], 'r') if len(sys.argv) > 1 else '.'
# Empty list of observers
observers = []
# Base logging configuration
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
# Iterate through paths and attach observers
for line in paths:
# Convert line into string and strip newline character
targetPath = str(line).rstrip()
# Schedules watching of a given path
observer.schedule(event_handler, targetPath)
# Add observable to list of observers
observers.append(observer)
# Start observer
observer.start()
try:
while True:
# Poll every second
time.sleep(1)
except KeyboardInterrupt:
for o in observers:
o.unschedule_all()
# Stop observer if interrupted
o.stop()
for o in observers:
# Wait until the thread terminates before exit
o.join()
Here's the code I use to watch multiple directories.
import sys
import time
import logging
from watchdog.observers.polling import PollingObserver as Observer
from watchdog.events import LoggingEventHandler
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
event_handler = LoggingEventHandler()
observer = Observer()
if len(sys.argv) > 1:
for i in range(1, len(sys.argv)):
observer.schedule(event_handler, sys.argv[i], recursive=True)
else:
observer.schedule(event_handler, '.', recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
The example code here shows a function called start
, not start_new_thread
. Have you tried that?
https://pypi.python.org/pypi/watchdog
Also, you should probably call start
just once, after the for loop, not inside of it.
Just wanna add some notes:
The threading lib and threads list in the code can be a little bit confusing for people who just start using watchdog (including myself). They are actually not necessary in the solution. A simple way to explain it is just:
- create one observer
- schedule multiple "watching events"
- and start the observer.
That's it.