2017-10-22 22 views
0

概要: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() 
+0

なぜ出力専用ファイルから読み込もうとしていますか? –

+0

こんにちはIgnacioだから、リモートホスト(dmesg、whoamiなど)にコマンドを実行し、その出力がログファイルに保存されている必要があります。 –

+0

代わりに 'stdout'を意味するのではないですか? –

答えて

0

私は答えにthis wonderful postへの感謝を発見し、以下のソリューションを構築しました。うまくいけば、伐採問題に直面している誰かがこの記事を読んでくれるだろ

for command in commands: 
     stdin, stdout, stderr = ssh.exec_command(command, get_pty=True) 
     lines = iter(stdout.readline, "") 
     for line in lines: 
      ddlog.event('[+] '+line,'info') 
     stdin.close() 

私はそれを信じることができません。

A)より多くの人々は、ロギングモジュールを再利用しやすいシンプルなことはありません。私は、開発者が提案するロギングソリューションを見てきました。コードは8つの異なる場所にあります。モジュール、メソッド、INITなどページ全体に嘔吐のように見えます!

B)スタックオーバーフローの人は、OPと同じ問題を抱えている、またはOPと同じ問題を抱えていると言うだけの人がいます。残りの人は人工的に評判を膨らませようとしていますが、上の人のようなコメントセクションに無駄なゴミを掲示しています。

関連する問題