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
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()