[Python] 파이썬에서 파일 작성이 중단 된 경우 모니터링


Answers

다음을 수행하여 가능한 해결책으로 파일 크기의 변화를 검사 해 볼 수 있습니다.

import os
from time import sleep
# other imports

while True:
    file1 = os.stat('file.txt') # initial file size
    file1_size = file1.st_size

    # your script here that collects and writes data (increase file size)
    sleep(1)
    file2 = os.stat('file.txt') # updated file size
    file2_size = file2.st_size
    comp = file2_size - file1_size # compares sizes
    if comp == 0:
        restart_program()
    else:
        sleep(5)

sleep() 함수를 조정해야 할 수도 있습니다. 실제 코드를 테스트 할 수 없기 때문에 사용하고있는 추정치 일뿐입니다. 결국 이것은 스크립트가 계속 작성되기를 원하는 한 계속 실행되는 무한 루프입니다.

다른 해결책 은 파일을 다음과 같이 업데이트하는 것입니다.

import os
import sys
from time import sleep
# other imports

while True:
    file1 = os.stat('file.txt') # initial file size
    file1_size = file1.st_size

    # your script here that collects and writes data (increase file size)
    sleep(1)
    file2 = os.stat('file.txt') # updated file size
    file2_size = file2.st_size
    comp = file2_size - file1_size # compares sizes
    if comp == 0:
        sys.exit
    else:
        sleep(5)

그런 다음 보조 프로그램을 사용하여 스크립트를 다음과 같이 실행하십시오.

import os
from time import sleep, strftime

while True:
    print(strftime("%H:%M:%S), "Starting"))
    system('main.py') # this is another infinite loop that will keep your script running
    print(strftime("%H:%M:%S), "Crashed"))
    sleep(5)
Question

매초 파일에 계속 쓰는 프로그램이 있습니다. 파일 쓰기는 UI에 평행 한 스레드에서 일어나고 있습니다. 일부 하드웨어 문제로 인해 때때로 가끔씩 글쓰기가 멈 춥니 다. 파일 쓰기가 중단되었는지 확인하고 싶었는데 업데이트되지 않으면 프로그램을 다시 시작하십시오. 파일의 타임 스탬프를 확인하고 업데이트되지 않는지 확인하고 싶었습니다. (파일이 쓰지 않을 경우 필요했던 워치 독 등을 원치 않았습니다.)

try:
    if time.time()>(os.stat(filename).st_mtime+2):
        raise ValueError("Yikes! Spike")
except ValueError:
    with open('errors.log','a') as log:
        log.write('Spike occured at '+ time.strftime(
        "%H:%M:%S")+' on '+datetime.date.today().strftime('%d/%m/%Y')+'\n')
        log.close()
    restart_program()

이 블록은 1 초마다 실행됩니다. 그러나 이것이 역효과를 냈고 앱 재시작이 끝나면 매 초마다 닫히고 다시 시작하지 않습니다. 매 초마다 예외 메시지가 기록됩니다. 나는 시차를 늘리려고 노력했지만 도움이되지 못했습니다.

다음에 시도했습니다.

ftimestamp = os.stat(filename).st_mtime
try:
    if os.stat(filename).st_mtime>=ftimestamp:
        ftimestamp = time.time()
        print "ftimestamp updated and all is well"
    else:
        ftimestamp = os.stat(filename).st_mtime
        raise ValueError("Yikes! Spike!")
        print "file time is behind"
except ValueError:
    with open('errors.log','a') as log:
        log.write('Spike occured at '+ time.strftime(
        "%H:%M:%S")+' on '+datetime.date.today().strftime('%d/%m/%Y')+'\n')
        log.close()
    restart_program()

다음 번 비교가 1 초 후에 만 ​​일어나고 이전 시간 비교보다 높은 파일 시간을 원하기 때문에 "ftimestamp"변수를 현재 시간 "time.time ()"으로 업데이트하려고했습니다. (블록은 wx.CallLater 함수를 통해 매 초마다 실행됩니다).

내 프로그램이 여전히 실패하고 ... 내가 어디로 잘못 가고 있는지 이해할 수 없다 ... 누군가 도와주세요! 아니면 단순히 파일이 쓰지 않았는지 확인하는 방법이 있습니까?




마지막으로 타임 스탬프 기반 옵션을 사용하여 다음 작업이 나에게 도움이되는 것처럼 보였습니다.

try:
    if time.time()-os.stat(filename).st_mtime>6:
        touch(filename)
        raise ValueError("Yikes! Spike")
except ValueError:
    with open('errors.log','a') as log:
        log.write('Spike/App restarting occured at '+ time.strftime(
                "%H:%M:%S")+' on '+datetime.date.today().strftime('%d/%m/%Y')+'\n')
        log.close()
    restart_program()

앞서 문제는 파일이 주어진 시간 간격으로 쓰기를 멈추었 음을 감지하고 계속해서 같은 것을 만족시키는 것입니다.

time.time()-os.stat(filename).st_mtime>6 

그러나이 조건이 만족되면 파일 타임 스탬프가 업데이트되지 않는 한이 조건을 계속 만족시키고 프로그램을 다시 시작합니다. 이제는 내 솔루션에서 파일을 한 번 터치 했는데 ( 여기서 사용한 터치 ) 조건이 충족되어 이제는 예상대로 작동합니다.

귀하의 의견을 모두 주셔서 감사합니다.




GUI 프로그램에서 파일이 시간에 따라 변경되는지 확인하려면 이벤트 루프에 표준 도구를 사용하여 간격 초마다 함수를 실행할 수 있습니다 (예 : tkinter 에서 수행하는 방법).

#!/usr/bin/env python3
import logging
import os
import sys
import tkinter
from datetime import datetime
from time import monotonic as timer, localtime

path = sys.argv[1]
interval = 120 # check every 2 minutes

def check(last=[None]):
    mtime = os.path.getmtime(path) # or os.path.getsize(path)
    logging.debug("mtime %s", datetime.fromtimestamp(mtime))
    if last[0] == mtime: #NOTE: it is always False on the first run
        logging.error("file metadata hasn't been updated, exiting..")
        root.destroy() # exit GUI
    else: # schedule the next run
        last[0] = mtime
        root.after(round(1000 * (interval - timer() % interval)), check)


logging.basicConfig(level=logging.DEBUG,
                    filename=os.path.splitext(__file__)[0] + ".log",
                    format="%(asctime)-15s %(message)s", datefmt="%F %T")
root = tkinter.Tk()
root.withdraw() # hide GUI
root.after(round(1000 * (interval - timer() % interval)), check) # start on boundary
root.mainloop()

supervisord, systemd 또는 upstart 등을 사용하여 자동으로 스크립트를 다시 생성 할 수 있습니다.

주기적으로 파이썬에서 함수를 실행하는 방법을 보라.