Watch a directory and tail all files
This commit is contained in:
commit
17c6e87a89
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
class WatchedFile:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.reopen()
|
||||
|
||||
def reopen(self):
|
||||
self.fd = open(self.name, errors='replace')
|
||||
self.fileno = self.fd.fileno()
|
||||
self.last_ts = 0
|
||||
|
||||
def format_ts(ts_ns):
|
||||
return datetime.datetime.fromtimestamp(ts_ns / 1E9).strftime("%H:%M:%S.%f")
|
||||
|
||||
def watch(dir):
|
||||
os.chdir(dir)
|
||||
last_ts = 0
|
||||
watched_files = {}
|
||||
filename_length = 0
|
||||
while True:
|
||||
# are there new files?
|
||||
st = os.stat(".")
|
||||
if st.st_mtime_ns > last_ts:
|
||||
last_ts = st.st_mtime_ns
|
||||
for de in os.scandir("."):
|
||||
if de.is_file():
|
||||
if de.name not in watched_files:
|
||||
watched_files[de.name] = WatchedFile(de.name)
|
||||
if len(de.name) > filename_length:
|
||||
filename_length = len(de.name)
|
||||
|
||||
# has any of the files changed
|
||||
for f in watched_files.values():
|
||||
# XXX - we should also detect replaced files.
|
||||
st = os.stat(f.fileno)
|
||||
try:
|
||||
stf = os.stat(f.name)
|
||||
if stf.st_ino != st.st_ino:
|
||||
f.reopen()
|
||||
except FileNotFoundError:
|
||||
# ignore,
|
||||
# or maybe remove from watched_files?
|
||||
# or just mark as deleted?
|
||||
pass
|
||||
if st.st_mtime_ns > f.last_ts:
|
||||
f.last_ts = st.st_mtime_ns
|
||||
new_content = f.fd.read()
|
||||
lines = new_content.split("\n")
|
||||
if lines[-1] == "":
|
||||
lines.pop()
|
||||
for ln in lines:
|
||||
print(f"{f.name:{filename_length}}", format_ts(f.last_ts), ln)
|
||||
time.sleep(0.1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
dir = sys.argv[1] if len(sys.argv) > 1 else "."
|
||||
|
||||
watch(dir)
|
Loading…
Reference in New Issue