英文:
Python script stdout is empty while trying to recover logs from remote device
问题
I'm trying to recover logs from a remote LB, the script should:
Connect to the LB -> Execute a command -> Check if the stdout is not none -> If it is, update a web page with ALL_GOO -> If there are persistent sessions it should update the web page with NOT_GOOD and send an email with the script output as attachment -> It should then update the file statusEmail with the date of the sent email (this to avoid sending multiple email per day).
When I execute the script I have an empty return: []
% ./lb-logs.py
SSH connection established successfully.
[]
Command executed.
This is the main script:
#!/usr/bin/env python3
import logging
import os
from src.utils import run_command, get_results
from datetime import datetime
lbUser = "lb_user"
lbIp = "lb_ip"
lbPass = "lb_pass"
attachment = "p-sessions.txt"
date = datetime.now().strftime("%d/%m/%Y")
mailList = "mail_list"
logging.basicConfig(
filename="logs.log",
encoding="utf-8",
level=logging.DEBUG,
format="%(asctime)s:%(levelname)s:%(message)s",
)
result = get_results(lbIp, lbUser, lbPass)
status = 'UNKNOWN'
if result:
run_command(
"sudo sed -i 's/^
./
NOT_GOOD-TEST</h1>/' /var/www/html/index1.html"
)
status = "NOT_GOOD"
logging.info(f"Status: {status}")
else:
run_command(
"sudo sed -i 's/^
.
/
ALL_GOOD-TEST</h1>/' /var/www/html/index1.html"
)
status = "ALL_GOOD"
logging.info(f"Status: {status}")
)
status = "NOT_GOOD"
logging.info(f"Status: {status}")
else:
run_command(
"sudo sed -i 's/^
.
)
status = "ALL_GOOD"
logging.info(f"Status: {status}")
if status == "NOT_GOOD":
if os.path.exists(attachment):
logging.info(f"File {attachment} exists.")
print("File exists.")
else:
# Send email if date in statusEmail is different from today's date
with open("src/statusEmail", "r") as statusEmailFileHandle:
if date == statusEmailFileHandle.read():
logging.info("Email already sent.")
else:
# Create file
for line in result:
print(line)
with open(attachment, "a") as attachmentFileHandle:
attachmentFileHandle.write(line + "\n")
logging.info(f"File {attachment} created.")
result1 = run_command(
f"echo 'Generated from vm: ' | mailx -r 'vm' 'mail_relay' -s 'Persistent sessions found on LB - {date}' -t {mailList} -A {attachment}"
)
print(result1)
with open("src/statusEmail", "w") as f:
f.write(f"NOT_GOOD: {date}")
logging.info("Email sent.")
And this is the utils.py:
import paramiko
import subprocess
import logging
def connect(lb_ip, lb_user, lb_passwd):
try:
_ssh = paramiko.SSHClient()
_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
_ssh.load_system_host_keys()
_ssh.connect(hostname=lb_ip, username=lb_user, password=lb_passwd)
return _ssh
print(_ssh)
except Exception as exceptHandler:
logging.error(f"Failed to connect to {ip}: {exceptHandler}")
raise
def run_command(command):
_process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
_output, _error = _process.communicate()
print(_output.decode())
return _output.decode().strip()
def get_results(lb_ip, lb_user, lb_pass):
conn = connect(lb_ip, lb_user, lb_pass)
if conn is not None:
print("SSH connection established successfully.")
stdin, stderr, stdout = conn.exec_command(
'shell nsconmsg -K /var/nslog/newnslog -g dht_ns_tot_max_limit_exceeds -d current -s disptime=1 | grep dht_ns_tot_max_limit_exceeds'
)
print(stdin, stdout, stderr)
logging.info(f"stdin={stdin}, stdout={stdout}, stderr={stderr}")
conn.close()
return stdout.readlines()
else:
print("Failed to establish SSH connection.")
return None
英文:
I'm trying to recover logs from a remote LB, the script should:
Connect to the LB -> Execute a command -> Check if the stdout is not none -> If it is, update a web page with ALL_GOO -> If there are persistent sessions it should update the web page with NOT_GOOD and send an email with the script output as attachment -> It should then update the file statusEmail with the date of the sent email (this to avoid sending multiple email per day).
When I execute the script I have an empty return: []
% ./lb-logs.py
SSH connection established successfully.
[]
Command executed.
This is the main script:
#! /usr/bin/env python3
import logging
import os
from src.utils import run_command, get_results
from datetime import datetime
lbUser = "lb_user"
lbIp = "lb_ip"
lbPass = "lb_pass"
attachment = "p-sessions.txt"
date = datetime.now().strftime("%d/%m/%Y")
mailList = "mail_list"
logging.basicConfig(
filename="logs.log",
encoding="utf-8",
level=logging.DEBUG,
format="%(asctime)s:%(levelname)s:%(message)s",
)
result = get_results(lbIp, lbUser, lbPass)
status = 'UNKNOWN'
if result:
run_command(
"sudo sed -i 's/^<h1>.*/<h1>NOT_GOOD-TEST<\/h1>/' /var/www/html/index1.html"
)
status = "NOT_GOOD"
logging.info(f"Status: {status}")
else:
run_command(
"sudo sed -i 's/^<h1>.*/<h1>ALL_GOOD-TEST<\/h1>/' /var/www/html/index1.html"
)
status = "ALL_GOOD"
logging.info(f"Status: {status}")
if status == "NOT_GOOD":
if os.path.exists(attachment):
logging.info(f"File {attachment} exists.")
print("File exists.")
else:
# Send email if date in statusEmail is different from today's date
with open("src/statusEmail", "r") as statusEmailFileHandle:
if date == statusEmailFileHandle.read():
logging.info("Email already sent.")
else:
# Create file
for line in result:
print(line)
with open(attachment, "a") as attachmentFileHandle:
attachmentFileHandle.write(line + "\n")
logging.info(f"File {attachment} created.")
result1 = run_command(
f"echo 'Generated from vm: ' | mailx -r 'vm' 'mail_relay' -s 'Persistent sessions found on LB - {date}' -t {mailList} -A {attachment}"
)
print(result1)
with open("src/statusEmail", "w") as f:
f.write(f"NOT_GOOD: {date}")
logging.info("Email sent.")
And this is the utils.py:
import paramiko
import subprocess
import logging
def connect(lb_ip, lb_user, lb_passwd):
try:
_ssh = paramiko.SSHClient()
_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
_ssh.load_system_host_keys()
_ssh.connect(hostname=lb_ip, username=lb_user, password=lb_passwd)
return _ssh
print(_ssh)
except Exception as exceptHandler:
logging.error(f"Failed to connect to {ip}: {exceptHandler}")
raise
def run_command(command):
_process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
_output, _error = _process.communicate()
print(_output.decode())
return _output.decode().strip()
def get_results(lb_ip, lb_user, lb_pass):
conn = connect(lb_ip, lb_user, lb_pass)
if conn is not None:
print("SSH connection established successfully.")
stdin, stderr, stdout = conn.exec_command(
'shell nsconmsg -K /var/nslog/newnslog -g dht_ns_tot_max_limit_exceeds -d current -s disptime=1 | grep dht_ns_tot_max_limit_exceeds'
)
print(stdin, stdout, stderr)
logging.info(f"stdin={stdin}, stdout={stdout}, stderr={stderr}")
conn.close()
return stdout.readlines()
else:
print("Failed to establish SSH connection.")
return None
I've already added checks in all the funtions to make sure that the SSH connections is established, the command executed on the remote LB and yet, the stdout is empty.
I should receive the list of persistent sessions (the output of the command).
答案1
得分: 0
你已经将stdin
、stderr
和stdout
变量以错误的顺序赋值,应该是stdin
、stdout
、stderr
。
这一行:stdin, stderr, stdout = conn.exec_command(
只需将其更改为stdin, stdout, stderr = conn.exec_command(
英文:
You have assigned stdin
, stderr
, and stdout
variables in the wrong order, it should be stdin
, stdout
, stderr
this line: stdin, stderr, stdout = conn.exec_command(
just change it like that stdin, stdout, stderr = conn.exec_command(
答案2
得分: -1
我是您的中文翻译,这是您要翻译的内容:
我是这样解决这个问题的,将标准输出添加到变量result中,这样它就保存为一个变量。
基本上,在此之前,我正在读取它(因此消耗了流),然后再次尝试读取它,当然它是空的。
def get_results(lb_ip, lb_user, lb_pass):
conn = connect(lb_ip, lb_user, lb_pass)
if conn is not None:
logging.info("SSH连接成功建立。")
stdin, stdout, stderr = conn.exec_command(
'shell nsconmsg -K /var/nslog/newnslog -g dht_ns_tot_max_limit_exceeds -d current -s disptime=1 | grep dht_ns_tot_max_limit_exceeds'
)
result = stdout.read().decode('utf-8')
logging.info(f"stdout={result}, stderr={stderr.read()}")
conn.close()
return result
else:
logging.error("无法建立SSH连接。")
return None
英文:
I solved the issued this way, adding the stdout to the variable result, this way it is saved as a variable.
Basically, before I was reading it (so consuming his stream) and then try to read it once again, and of course it was empty.
def get_results(lb_ip, lb_user, lb_pass):
conn = connect(lb_ip, lb_user, lb_pass)
if conn is not None:
logging.info("SSH connection established successfully.")
stdin, stdout, stderr = conn.exec_command(
'shell nsconmsg -K /var/nslog/newnslog -g dht_ns_tot_max_limit_exceeds -d current -s disptime=1 | grep dht_ns_tot_max_limit_exceeds'
)
result = stdout.read().decode('utf-8')
logging.info(f"stdout={result}, stderr={stderr.read()}")
conn.close()
return result
else:
logging.error("Failed to establish SSH connection.")
return None
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论