Python to emulate remote tail -f?

前端 未结 6 1614
攒了一身酷
攒了一身酷 2021-01-04 20:28

We have several application servers, and a central monitoring server.

We are currently running ssh with \"tail -f\" from the monitoring server to stream several text

6条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-01-04 20:47

    I wrote a function that do that:

    import paramiko
    import time
    import json
    
    DEFAULT_MACHINE_USERNAME="USERNAME"
    DEFAULT_KEY_PATH="DEFAULT_KEY_PATH"
    
    def ssh_connect(machine, username=DEFAULT_MACHINE_USERNAME,
                    key_filename=DEFAULT_KEY_PATH):
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(hostname=machine, username=username, key_filename=key_filename)
        return ssh
    
    def tail_remote_file(hostname, filepath, key_path=DEFAULT_KEY_PATH,
                         close_env_variable="CLOSE_TAIL_F", env_file='~/.profile'):
        ssh = ssh_connect(hostname, key_filename=key_path)
    
        def set_env_variable(to_value):
            to_value_str = "true" if to_value else "false"
            from_value_str = "false" if to_value else "true"
            ssh.exec_command('sed -i \'s/export %s=%s/export %s=%s/g\' %s' %
                             (close_env_variable, from_value_str,
                              close_env_variable, to_value_str, env_file))
            time.sleep(1)
    
        def get_env_variable():
            command = "source .profile; echo $%s" % close_env_variable
            stdin, stdout_i, stderr = ssh.exec_command(command)
            print(command)
            out = stdout_i.read().replace('\n', '')
            return out
    
        def get_last_line_number(lines_i, line_num):
            return int(lines_i[-1].split('\t')[0]) + 1 if lines_i else line_num
    
        def execute_command(line_num):
            command = "cat -n %s | tail --lines=+%d" % (filepath, line_num)
            stdin, stdout_i, stderr = ssh.exec_command(command)
            stderr = stderr.read()
            if stderr:
                print(stderr)
            return stdout_i.readlines()
    
        stdout = get_env_variable()
        if not stdout:
            ssh.exec_command("echo 'export %s=false' >> %s" %
                             (close_env_variable, env_file))
        else:
            ssh.exec_command(
                'sed -i \'s/export %s=true/export %s=false/g\' %s' %
                (close_env_variable, close_env_variable, env_file))
        set_env_variable(False)
    
        lines = execute_command(0)
        last_line_num = get_last_line_number(lines, 0)
    
        while not json.loads(get_env_variable()):
            for l in lines:
                print('\t'.join(t.replace('\n', '') for t in l.split('\t')[1:]))
            last_line_num = get_last_line_number(lines, last_line_num)
            lines = execute_command(last_line_num)
            time.sleep(1)
    
        ssh.close()
    

提交回复
热议问题