удаленный файл следует с использованием Python

Я создал класс по запросу, который можно запустить для сбора любых новых данных, записанных в файл из start_recording звони, пока stop_recording которые закрывают соединение и извлекают собранные данные.

Он используется в тестовых примерах для получения соответствующих журналов во время выполнения определенной операции, чтобы проверить ее успешность.

В настоящее время я использую этот класс для тестов на удаленной машине, но был бы рад услышать любые идеи по улучшению, правильности и т. Д.

import time

import paramiko
import select

from virtual_machine import utils
from multiprocessing import Queue
import multiprocess

class background():
    def __init__(self, config_file):
        self.q = Queue(1000)
        #this methods implemented elsewhere and read a config file into dictionary
        self.config = utils.get_params(config_file)

    @staticmethod
    def linesplit(socket):
        buffer_string = socket.recv(4048).decode('utf-8')
        done = False
        while not done:
            if 'n' in buffer_string:
                (line, buffer_string) = buffer_string.split('n', 1)
                yield line + "n"
            else:
                more = socket.recv(4048)
                if not more:
                    done = True
                else:
                    buffer_string = buffer_string + more.decode('utf-8')
        if buffer_string:
            yield buffer_string

    def do_tail(self, log_file):
        data = ""
        client = paramiko.SSHClient()
        client.load_system_host_keys()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        from os.path import expanduser
        home = expanduser("~")
        client.connect(self.config["ip"],self.config["username"],self.config["password"])

        grep_pattern = "grep_filter"
        remote_command = 'tail -0 -f {} '.format(log_file)
        print(remote_command)
        transport = client.get_transport()
        channel = transport.open_session()
        channel.exec_command(remote_command)

        while 1:
            try:
                rl, _, _ = select.select([channel], [], [], 0.0)
                if len(rl) > 0:
                    print("ready to read")
                    for line in background.linesplit(channel):
                        self.q.put_nowait(line)


            except (KeyboardInterrupt, SystemExit):
                print('got ctrl+c')
                break

        client.close()

        return data

    def start_recording(self, log_file):
        q = Queue(100)
        self.p = multiprocess.Process(target=self.do_tail, args=(log_file,), daemon=True)
        self.p.start()

    def stop_recording(self):
        self.p.terminate()

        data = ""
        while not self.q.empty():
            data += self.q.get()

        return data


#example 
if __name__ == '__main__':
    x = background("config.conf")
    x.start_recording("/tmp/logfile.log")
    # doing some operation 
    data = x.stop_recording()
    print(data)

1 ответ
1

Ваш linesplit немного повторяет код; Вы могли бы сформулировать это как

while True:
    buffer_bytes = socket.recv(4096)
    if len(buffer_bytes) == 0:
        break
    buffer_string = buffer_bytes.decode('utf-8')
    *lines, buffer_string = buffer_string.split('n')
    yield from lines

'tail -0 -f {} '.format(log_file) может быть просто 'tail -0 -f ' + log_file.

background должно быть Background.

Подумайте о добавлении подсказок типа PEP484.

rl, _, _ = select ...

возможно

rl, *_ = select ...

Код между paramiko.SSHClient() и client.close() не имеет закрытой гарантийной защиты. Есть разные варианты, в том числе try/finallyили сделать ваш текущий класс (или выделенный класс, специфичный для хвоста) диспетчером контекста.

  • Спасибо за ваши комментарии. Кстати, я столкнулся с тем, что запись журнала отставала, а где это произошло, интересная часть уже закончилась. Интересно, есть ли какая-то системная блокировка, которая может заблокировать start_recording от возврата, пока подпроцесс не достигнет ready to read линия. Вы можете что-нибудь порекомендовать? Благодарность !

    — Зохар81

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *