Each client application would send a filepath and search term to the server. The server then takes that file path reads the file and returns any lines that contain the search term, the server then watches the file for any size increase and if the new lines contain wanted information it gets transmitted.
The first for
loop is echoing the initial message to make sure that it is correct it also validates that the file path is a file.
There are some odd bits that are mostly for if a log gets rotated while a connection is active.
My planned upgrades will include better exception handling, I know there are a couple places where if something goes wrong, it'll just throw you into an infinite while loop. There is some other stuff I'll need to fix but you know I'm here for your perspective, not the other way.
import asyncio, socket, os
HOST = "127.0.0.1"
PORT = 65432
async def log_transmit(reader, writer):
try:
print('new connect')
data, datval, fpath = '', '', ''
#ensuring communication of filepath and search term
while 1:
data = (await reader.read(128))
print(f'{fpath} {datval}')
if data.decode('utf-8').strip() == 'recv' and os.path.isfile(fpath):
break
else:
datval = data.decode('utf-8').strip()
l = datval.split()
if len(l) == 2:
fpath, datval = [x for x in l]
writer.write(data)
await writer.drain()
file = open(fpath, 'r')
line = file.readline()
# reading to the end of the file
while line != '':
if datval in line:
line += ' ' * (256 - len(line.encode()))
writer.write(line.encode())
await writer.drain()
line = file.readline()
size = os.path.getsize(fpath)
# looking for new file entries
while 1:
await asyncio.sleep(0.1)
try:
newsize = os.path.getsize(fpath)
# handling log rotation
except FileNotFoundError:
while os.path.isfile(fpath) == False:
pass
file = open(fpath, 'r')
if newsize > size: # new entries need to be examined
file.seek(size)
line = file.readline()
while line != '':
size += len(line)
if datval in line:
line = line.strip()
line += ' ' * (256 - len(line))
writer.write(line.encode())
await writer.drain()
file.seek(size)
line = file.readline()
elif newsize < size:
# more log rotation handling
await asyncio.sleep(2)
file = open(fpath, 'r')
size = newsize
# else file hasn't changed nothing to be done
except ConnectionResetError:
print('client disconnected')
file.close()
writer.close()
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.create_task(asyncio.start_server(log_transmit, HOST, PORT))
loop.run_forever()