次の 2 つの問題に対処します。
tail
ファイルに実装する方法、
pyinotify
そしてモジュールの使い方。
ファイルのテール
コードでは、次のことを行う必要があります。
read
またはreadlines
を使用して、できるだけ多くの行全体を読んでみてください。
- を使用して印刷できるようになるまで、ファイルを最後の不完全な行の先頭まで巻き戻します
seek
。
これは、たとえば次のように変換されます。
f = open(PATH)
for line in f.readlines():
print line[:-1]
while True:
time.sleep(5)
try:
line_start = f.tell()
new_lines = f.read()
last_n = new_lines.rfind('\n')
if last_n >= 0:
# We got at least one full line
line_start += last_n + 1
print new_lines[:last_n]
else:
# No complete line yet
print 'no line'
f.seek(line_start)
except KeyboardInterrupt:
notifier.stop()
break
ここでさらに例を見つけることができますが、改行で終わらないファイルへの追加に対応していないものもあります。
そして、ここにいくつかの選択肢があります Python でログファイルを追跡するにはどうすればよいですか?
Pyinotify ループ
pyinotify
また、ドキュメントで説明されているように、 のイベント ハンドラ内にコードを移動する必要があります。
check_events
処理するイベントがある場合は戻りますTrue
が、実際にはイベントを処理しないため、イベントTrue
が処理されるまで常に戻ります。
また、while
/sleep
ループを避けるようにしてください。Inotify は、リソースを犠牲にすることなく、イベントを受信するとすぐに処理する機能を追加します。/ループは反応性が低くなりますwhile
。sleep
以下は、 のショート チュートリアルの最初の 2 つの方法pyinotify
です。
1. 終わりのない監視
他のイベント ループがない場合は、これが最も反応性が高いため、この方法をお勧めします。
PATH = os.path.join(os.path.expanduser('~/'), 'experiments', 'testfile')
class EventHandler(pyinotify.ProcessEvent):
def __init__(self, *args, **kwargs):
super(EventHandler, self).__init__(*args, **kwargs)
self.file = open(PATH)
self.position = 0
self.print_lines()
def process_IN_MODIFY(self, event):
print 'event received'
self.print_lines()
def print_lines(self):
new_lines = self.file.read()
last_n = new_lines.rfind('\n')
if last_n >= 0:
self.position += last_n + 1
print new_lines[:last_n]
else:
print 'no line'
self.file.seek(self.position)
wm = pyinotify.WatchManager()
handler = EventHandler()
notifier = pyinotify.Notifier(wm, handler)
wm.add_watch(PATH, pyinotify.IN_MODIFY, rec=True)
notifier.loop()
2. 定期的なモニタリング
すでに処理ループがある場合は、process_events
定期的に呼び出すだけです。EventHandler
クラスは方法 1 と同じですが、呼び出しの代わりに通知notifier.loop()
機能に小さなタイムアウトを追加し、独自のイベント ループを実装します。
...
wm = pyinotify.WatchManager()
handler = EventHandler()
notifier = pyinotify.Notifier(wm, handler, timeout=10)
wm.add_watch(PATH, pyinotify.IN_MODIFY, rec=True)
while True:
# Do something unrelated to pyinotify
time.sleep(5)
notifier.process_events()
#loop in case more events appear while we are processing
while notifier.check_events():
notifier.read_events()
notifier.process_events()