файл наблюдения за изменениями

Мне нужно посмотреть файл журнала на предмет изменений. После просмотра вопросов о stackoverflow я заметил, что люди рекомендуют watchdog. Итак, я пытаюсь протестировать и не уверен, куда добавить код при изменении файлов:

import time
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler

if __name__ == "__main__":
    event_handler = LoggingEventHandler()
    observer = Observer()
    observer.schedule(event_handler, path='.', recursive=False)
    observer.start()
    try:
        while True:
            time.sleep(1)
        else:
            print "got it"
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

Куда добавить полученное - в цикл while, если файлы были добавлены / изменены?


person Cmag    schedule 03.09.2013    source источник
comment
используйте пример из github   -  person Cmag    schedule 03.09.2013
comment
пример на github все еще не работает.   -  person Deqing    schedule 04.05.2016


Ответы (3)


Вместо LoggingEventHandler определите свой обработчик:

#!/usr/bin/python
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler


class MyHandler(FileSystemEventHandler):
    def on_modified(self, event):
        print(f'event type: {event.event_type}  path : {event.src_path}')


if __name__ == "__main__":
    event_handler = MyHandler()
    observer = Observer()
    observer.schedule(event_handler, path='/data/', recursive=False)
    observer.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

on_modified вызывается при изменении файла или каталога.

person alecxe    schedule 03.09.2013
comment
Отлично, спасибо! Теперь, как мне смотреть только конкретный файл, а теперь и весь каталог? - person Cmag; 03.09.2013
comment
Добро пожаловать. Вы можете посмотреть каталог, в котором находится файл, а затем проверить переменную event.src_path в методах обработчика. - person alecxe; 03.09.2013
comment
И, кроме того, вы можете смотреть конкретное событие. - person alecxe; 03.09.2013
comment
этот код блокирует файл, поэтому он не может использоваться другими программами - person denfromufa; 18.04.2014
comment
У меня проблемы с этим точным кодом, он отправляет 4 Got it!, когда я просто изменяю один файл. - person majidarif; 10.07.2014
comment
@majidarif: определите on_create. on_delete и т. д. и посмотрите, что происходит - person Mr_and_Mrs_D; 16.07.2014
comment
Выяснилось, что возвышенный текст создает дополнительные файлы, которые вызывают это. изменение настроек исправило это. - person majidarif; 16.07.2014
comment
У меня та же проблема, что и у @majidarif, но я не использую Sublime Text. Каталог, который я отслеживаю, является сетевым ресурсом, и когда я копирую в него файл (657 МБ), я вижу несколько Понятно! Сообщения. Мне нужен только последний, так как файл не будет полным, пока не будет последний, и я хочу, чтобы мой код получил доступ к файлу и что-то с ним сделал. Я пробовал играть с очередями и таймаутами, но безуспешно. Любые идеи? Мне бы очень хотелось нового события, которое означает, что я закончил изменять файл !. - person Dan Tenenbaum; 21.10.2014
comment
Разве это не более неэффективно, чем os.stat опрос? поскольку он все еще опрашивает и опрашивает каталог? Затем вам нужно проснуться и посмотреть, является ли событие фактическим изменением файла для целевого файла или нет. - person user3467349; 12.06.2015
comment
@ user3467349 был бы рад, если бы вы действительно предоставили это лучшее решение. Спасибо. - person alecxe; 12.06.2015
comment
@ user3467349 plus, в любом случае, это вопрос специально для сторожевого пса. - person alecxe; 12.06.2015
comment
@DanTenenbaum Вы когда-нибудь узнали, как исправить повторяющиеся сообщения "Понятно"? Я также получаю два последовательных сообщения. - person Helk; 20.09.2017
comment
@alecxe Что дает блок try? - person TheRealFakeNews; 01.02.2019
comment
@AlanH Это позволяет хорошо завершить работу наблюдателя сторожевого пса, когда пользователь завершает программу, нажав Ctrl + C - person Florentin Le Moal; 13.03.2019
comment
что observer.join() делает в коде? также есть ли у наблюдателя свой собственный поток или он выполняется в основном потоке (пытаясь выяснить, почему вызов time.sleep(1) будет работать, поскольку наблюдатель, похоже, использует потоки)? Документы для наблюдателей кажутся немного скудными, поэтому пытаюсь собрать воедино, как использовать эту штуку ... - person bob; 06.12.2019

Вот фрагмент, чтобы предотвратить его запуск дважды, поскольку другие прокомментировали ответ @alecxe:

from datetime import datetime, timedelta

class MyHandler(FileSystemEventHandler):
    def __init__(self):
        self.last_modified = datetime.now()

    def on_modified(self, event):
        if datetime.now() - self.last_modified < timedelta(seconds=1):
            return
        else:
            self.last_modified = datetime.now()
        print(f'Event type: {event.event_type}  path : {event.src_path}')
        print(event.is_directory) # This attribute is also available
person run_the_race    schedule 26.07.2019
comment
Спасибо за это - именно то, что я искал. Если вы все еще активны, не могли бы вы ответить на мой вопрос здесь (на самом деле этот вопрос отвечает на большую часть), и я поставлю зеленую галочку: stackoverflow.com/questions/ 57531818 / - person Umar.H; 17.08.2019
comment
оператор печати print (f'Event type: {event.event_type} path: {event.src_path} ') выдает ошибку? я изменил его на print (event.event_type) print (event.src_path) print (event.is_directory), возможно, кто-то может прояснить, почему? - person Alice; 20.11.2019
comment
@Cat, а вы пользуетесь версией Python ‹3.6? Начиная с python 3.6 они представили f-строки: realpython.com/python-f-strings Они отлично! - person run_the_race; 22.11.2019
comment
Если есть только один файл, это нормально. Но если в каталоге несколько файлов, это может скрыть события от пользователя. - person Javon; 03.01.2021

Вместо datetime вы можете использовать логику проверки src_path, поскольку, если логика после проверки более 1-секундной логики datetime не удастся.

class EventHandler(FileSystemEventHandler):
    def __init__(self):
        self.src_path = ''

    def on_modified(self, event):
        if self.src_path == event.src_path:
            return
        else:
            self.src_path = event.src_path
        logger.info(f"{event.event_type} occured on file {self.src_path}")
        #your long processing logics goes here.
person Basil Jose    schedule 05.02.2021