2
\$\begingroup\$

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()
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.