概要:2つのスクリプト、ロギング用(ddlog)、もう1つはssh接続とコマンド実行(ddlogin)用のparamikoを使用します。ロガーは正常に動作し、接続する各ホストのログファイルを作成しますが、標準入力と標準出力のハンドラーはロギングイベントをトリガーしません。現在、以下のioエラーが発生します。私はsys.stdoutでlogging.StreamHandler()を修正しようとしましたが、これはどちらかと思われません。(sys。)stdoutをロギングにリダイレクトする(python3)
エラー:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "ddlogin.py", line 89, in run
main(host)
File "ddlogin.py", line 60, in main
line = sys.stdout.read().splitlines(4096)
io.UnsupportedOperation: not readable
DDLOG:
import logging
fileLogger = logging.getLogger()
fileLogger.setLevel(logging.DEBUG)
switch_log_levels = {
'debug': fileLogger.debug,
'info': fileLogger.info,
'warning': fileLogger.warning,
'error': fileLogger.error,
'critical': fileLogger.critical
}
def setup(logFile):
global fileLogger
logFormatStr = "[%(asctime)s %(threadName)s, %(levelname)s] %(message)s"
consoleFormatStr = "[%(threadName)s, %(levelname)s] %(message)s"
# File Handler for log file
logFormatter = logging.Formatter(logFormatStr)
fileHandler = logging.FileHandler(logFile)
fileHandler.setFormatter(logFormatter)
fileLogger.addHandler(fileHandler)
# Stream Handler for stdout, stderr
consoleFormatter = logging.Formatter(consoleFormatStr)
consoleHandler = logging.StreamHandler()
consoleHandler.setFormatter(consoleFormatter)
consoleHandler.setLevel(logging.INFO)
fileLogger.addHandler(consoleHandler)
def event(string, level='debug',print_screen=False, remove_newlines=False):
if remove_newlines:
string = string.replace('\r', '').replace('\n', ' ')
if print_screen:
switch_log_levels[level](string)
switch_log_levels[level](string)
ddlogin:
import argparse, ddlog, os, paramiko, sys
from threading import Thread
from queue import Queue
def main(hostlist):
global username, password, commands
try:
# Filepath, logger, and console handler
logfile = os.getcwd() + '//logs/' + hostlist + '.log'
ddlog.setup(logfile)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect(hostlist, username=username, password=password)
except paramiko.AuthenticationException:
ddlog.event("[-] Failed to Authenticate.",'error')
pass
except paramiko.SSHException:
ddlog.event("[-] An SSH exception was raised. Check clients ssh settings.",'error') #, exc_info=True)
pass
except TimeoutError:
ddlog.event("[-] host is not reachable.",'error')
pass
host = hostlist.strip('\n')
ddlog.event('[+] successfully connected to ' + host,'info')
for command in commands:
stdin, stdout, stderr = ssh.exec_command(command)
stdin.close()
line = sys.stdout.read().splitlines(4096)
ddlog.event('[+] ' + host + line.strip().decode('ascii'),'info')
except KeyboardInterrupt:
sys.exit('[-] Process aborted by user input')
if __name__ == "__main__":
# system arguments: ddlogin.py -u admin -p password -l 192.168.1.1 -c dmesg 'uname -a'
parser = argparse.ArgumentParser()
parser.add_argument('-u', '--username', action='store', dest='username', help='The ssh username.')
parser.add_argument('-p', '--password', action='store', dest='password', help='The ssh password.')
parser.add_argument('-l', '--hostlist', nargs='+',action='store', dest='hostlist', help='List of devices to interact with.')
parser.add_argument('-c', '--commands', nargs='+',action='store', dest='commands', help='An exact list of commands to run.')
#parser.add_argument('-o', '--output', nargs='+',action='store', dest='commands', help='TBD...')
args = parser.parse_args()
username = args.username
password = args.password
hostlist = args.hostlist
commands = args.commands
class ParallelConnections(Thread):
def __init__(self, queue):
Thread.__init__(self)
self.queue = queue
def run(self):
while True:
host = self.queue.get()
main(host)
self.queue.task_done()
thread_count = 4
queue = Queue()
for i in range(thread_count):
Parallel = ParallelConnections(queue)
Parallel.daemon = True
Parallel.start()
for host in hostlist:
queue.put(host)
queue.join()
なぜ出力専用ファイルから読み込もうとしていますか? –
こんにちはIgnacioだから、リモートホスト(dmesg、whoamiなど)にコマンドを実行し、その出力がログファイルに保存されている必要があります。 –
代わりに 'stdout'を意味するのではないですか? –