Browse Source

Add files via upload

dufsh 5 years ago
parent
commit
906ea521e5
10 changed files with 708 additions and 0 deletions
  1. 1 0
      __init__.py
  2. 37 0
      autocheck_day.py
  3. 37 0
      autocheck_hour.py
  4. 46 0
      call_test.py
  5. 56 0
      databaseconn.py
  6. 56 0
      decodepasswd.py
  7. 65 0
      hostinfo.py
  8. 216 0
      snmpclient.py
  9. 194 0
      sshclient.py
  10. BIN
      testP.jar

+ 1 - 0
__init__.py

@@ -0,0 +1 @@
+#

+ 37 - 0
autocheck_day.py

@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Dec  3 23:30:49 2018
+
+@author: dufs
+"""
+
+import logging.config
+import hostinfo as hf
+import sshclient as sshcl
+
+if __name__ == '__main__':
+
+    logging.config.fileConfig("conf/logging.conf")
+    #create logger
+    logger = logging.getLogger("autocheck")
+    
+    hostList=hf.get_hostinfo()
+    if hostList[0]!=0:
+        logger.error('get hostinfo error')
+        raise
+    
+    hostSet=set()
+    for host in hostList[1]:
+        if host[3] is None or len(host[3])==0 or host[4] is None or len(host[4])==0:
+            continue
+        hostSet.add((host[1], int(host[2]), host[3], host[4], host[0]))
+    
+    logger.info('get host number %d', len(hostSet))
+    if len(hostSet)>0:
+        cmdSet=set()
+        cmdSet.add(('userinfo', '''cat /etc/passwd |awk -F":" '{print $1}' '''))
+        cmdSet.add(('mkmfsinfo', "sudo -u root mkmfsinfo -querydisk |awk '{print $1,$8}'"))
+
+        sshcl.ssh_batch_cmd(hostSet, cmdSet)
+    logger.info('exec autocheck_day finished')

+ 37 - 0
autocheck_hour.py

@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Dec  3 17:40:17 2018
+
+@author: dufs
+"""
+
+import sys
+import logging.config
+import hostinfo as hf
+import snmpclient as scl
+
+if __name__ == '__main__':
+
+    logging.config.fileConfig("conf/logging.conf")
+    #create logger
+    logger = logging.getLogger("autocheck")
+    
+    hostList=hf.get_hostinfo(False)
+    if hostList[0]!=0:
+        logger.error('get hostinfo error')
+        raise
+    
+    hostSet=set()
+    for host in hostList[1]:
+        hostSet.add((host[1], 'SNMP_COMMUNITY', host[0]))
+    
+    logger.info('get host number %d', len(hostSet))
+    if len(hostSet)>0:
+        oidSet=set()
+        oidSet.add(('disk', 'snmpdf'))
+        oidSet.add(('mem', 'memTotalReal'))
+        oidSet.add(('mem', 'memAvailReal'))
+        oidSet.add(('cpu', 'ssCpuIdle'))
+        scl.snmp_batch_cmd(hostSet, oidSet)
+    logger.info('exec autocheck_hour finished')

+ 46 - 0
call_test.py

@@ -0,0 +1,46 @@
+#!/usr/bin/env python2
+# -*- coding: utf-8 -*-
+"""
+Created on Sat Dec  1 16:55:52 2018
+
+@author: dufs
+"""
+
+import sshclient as sshClt
+import decodepasswd as decp
+import hostinfo
+
+
+if __name__ == "__main__":
+    
+    hostSet=set()
+    hostSet.add(('10.102.52.8', 22444, 'iss', 'Iss@52.8!', 100))
+    hostSet.add(('10.102.52.9', 22444, 'iss', 'Iss@52.8!', 101))
+    hostSet.add(('10.102.52.10', 22444, 'iss', 'Iss@52.8!', 102))
+    hostSet.add(('10.102.52.11', 22444, 'iss', 'Iss@52.8!', 103))
+    hostSet.add(('10.102.52.12', 22444, 'iss', 'Iss@52.8!', 104))
+    hostSet.add(('10.102.52.13', 22444, 'iss', 'Iss@52.8!', 105))
+    hostSet.add(('10.102.52.16', 22444, 'iss', 'Iss@52.8!', 106))
+    hostSet.add(('10.102.52.18', 22444, 'iss', 'Iss@52.8!', 107))
+    hostSet.add(('10.102.52.19', 22444, 'iss', 'Iss@52.8!', 108))
+    hostSet.add(('10.102.52.20', 22444, 'iss', 'Iss@52.8!', 109))
+    hostSet.add(('10.102.52.21', 22444, 'iss', 'Iss@52.8!', 110))
+
+    cmdSet=set()
+    cmdSet.add(('disk', 'df -k'))
+    cmdSet.add(('mem', 'free -m'))
+    cmdSet.add(('vmstat', 'vmstat 1 5'))
+    cmdSet.add(('ps', 'ps -fu iss'))  
+    
+    #result=sshClt.ssh_batch_cmd(hostSet, cmdSet)
+    #for res in result:
+    #    print res
+    
+    #decpass=decp.DecodePassword()
+    #res=decpass.getdecodePassword('GaE+arhkPtNsGdsQOej3hw==', 'dWx0cmEtc3RhY2s=')
+    #decpass.shutdownJVM()
+    #print res
+    
+    res=hostinfo.get_hostinfo()
+    print res
+    

+ 56 - 0
databaseconn.py

@@ -0,0 +1,56 @@
+#!/usr/bin/python2.7
+# -*- coding: utf-8 -*-
+"""
+Created on Sat Jul 28 12:34:00 2018
+
+@author: dufs
+"""
+
+import os
+import cx_Oracle
+import logging
+import logging.config
+
+
+logging.config.fileConfig('conf/logging.conf')
+logger = logging.getLogger(__name__)
+
+
+class DataBaseConn():
+    '''
+    '''
+
+    def __init__(self, url, nls_lang='SIMPLIFIED CHINESE_CHINA.UTF8'):
+        self.url=url
+
+        try:
+            os.environ['NLS_LANG'] = nls_lang
+            self.conn=cx_Oracle.connect(self.url)
+        except Exception as e:
+            logger.error('get connect faild : ' + str(e) , exc_info=True)
+            raise
+
+    def close_connect(self):
+        self.conn.close()
+
+    def exec_sql(self, sql, *argList):
+        # sql
+        
+        try:
+            if not isinstance(sql,basestring):
+                logger.error('sql is not a string ', exc_info=True)
+                raise
+            else:
+                #logger.info('get exec sql =  %s ' , sql)
+                self.curs=self.conn.cursor()
+                if argList:
+                    logger.debug('get exec sql argList : %s', str(argList))
+                    result=self.curs.execute(sql, argList[0])
+                else:
+                    result=self.curs.execute(sql)
+                self.conn.commit()
+                #logger.info('exec sql success')
+                return result
+        except Exception:
+            logger.error('execInsertSql faild : ' , exc_info=True)
+            raise

+ 56 - 0
decodepasswd.py

@@ -0,0 +1,56 @@
+#!/usr/bin/python2.7
+# -*- coding: utf-8 -*-
+"""
+Created on Fri Nov 30 15:28:17 2018
+
+@author: dufs
+ decode password  by key
+"""
+
+import os
+import logging
+import logging.config
+import jpype
+import os.path
+
+
+#logging.config.fileConfig('conf/logging.conf')
+#logger = logging.getLogger(__name__)
+logger = logging.getLogger('autocheck.decodepasswd')
+
+
+class DecodePassword():
+    '''
+    '''
+    def __init__(self):
+        jarpath =os.path.join(os.path.abspath('.'),'./')
+        jvmpath=jpype.getDefaultJVMPath()
+        #jvmpath='/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/server/libjvm.dylib'
+        if jpype.isJVMStarted()>0:
+            jpype.shutdownJVM()
+        else:
+            jpype.startJVM(jvmpath, "-ea", "-Djava.class.path=%s" % (jarpath + "testP.jar"))
+        self.Jcls = jpype.JPackage("com.zznode.utils").DESDecryptCoder()
+    
+    def getdecodePassword(self, passwd, key):
+        '''
+        '''
+        if passwd is None or key is None:
+            desPass=''
+        else:
+            desPass=self.Jcls.decrypt(passwd, key)
+        logger.debug("enPass = %s , desPass = %s" % (passwd, desPass))
+        return desPass
+    
+    def shutdownJVM(self):
+        jpype.shutdownJVM()
+
+
+if ( __name__ == "__main__"):
+    
+    logging.config.fileConfig("conf/logging.conf")
+    #create logger
+    logger = logging.getLogger("decodepassword")
+    decpass=DecodePassword()
+    decpass.getdecodePassword('GaE+arhkPtNsGdsQOej3hw==', 'dWx0cmEtc3RhY2s=')
+    decpass.shutdownJVM()

+ 65 - 0
hostinfo.py

@@ -0,0 +1,65 @@
+#!/usr/bin/python2.7
+# -*- coding: utf-8 -*-
+"""
+Created on Fri Nov 30 15:28:17 2018
+
+@author: dufs
+ id ip_address port account password pwdkey
+"""
+
+import logging.config
+import ConfigParser
+import decodepasswd as decpwd
+import databaseconn as dbcn
+
+#logging.config.fileConfig('conf/logging.conf')
+#logger = logging.getLogger(__name__)
+logger = logging.getLogger('autocheck.hostinfo')
+
+
+def get_hostinfo(if_decodepasswd=True):
+    '''
+    '''
+
+    try:
+        cf = ConfigParser.SafeConfigParser()
+        cf.read('conf/autocheck.conf')
+        db_url=cf.get('db', 'url')
+        nls_lang=cf.get('db', 'nls_lang')
+    except Exception as e:
+        logger.error('parse config file error: ' + str(e) , exc_info=True)
+        return [-1, ]
+
+    if len(nls_lang)==0:
+        nls_lang='SIMPLIFIED CHINESE_CHINA.UTF8'
+    
+    v_sql='''select id,ip_address,nvl(port,0),nvl(account,''),nvl(password,''),nvl(pwdkey,'') from isp_autoinspection_device where ip_address is not null'''
+    
+    try:
+        dbclt=dbcn.DataBaseConn(db_url, nls_lang=nls_lang)
+    except Exception as e:
+        logger.error('connect db faild : ' + str(e) , exc_info=True)
+        return [-1, ]
+    try:
+        v_set=set()
+        res=dbclt.exec_sql(v_sql)
+        #logger.info('get hostinfo total %d', len(res))
+
+        if if_decodepasswd==True:
+            dp=decpwd.DecodePassword()
+        for dev_id, dev_ip, port, account, password, pwdkey in res:
+            logger.debug("id = %s, ip = %s, port = %d, account = %s, password = %s, pwdkey = %s" % (dev_id, dev_ip, int(port), account, password, pwdkey))
+            if if_decodepasswd==True:
+                desPass=dp.getdecodePassword(password, pwdkey)
+            else:
+                desPass=password
+            v_set.add(tuple([dev_id, dev_ip, port, account, desPass]))
+            #logger.debug("id = %s, ip = %s, port = %d, account = %s, password = %s" % (dev_id, dev_ip, int(port), account, desPass))
+        return [0, v_set]
+    except Exception as e:
+        logger.error('get Exception : ' + str(e) , exc_info=True)
+        return [-99, ]
+    
+    finally:
+        dbclt.close_connect()
+

+ 216 - 0
snmpclient.py

@@ -0,0 +1,216 @@
+#!/usr/bin/python2.7
+# -*- coding: utf-8 -*-
+"""
+Created on Sat Jul 28 12:34:00 2018
+
+@author: dufs
+"""
+
+import sys
+import time
+import netsnmp
+import commands
+import logging
+import logging.config
+import ConfigParser
+import multiprocessing
+import databaseconn as dbcn
+
+
+#logging.config.fileConfig('conf/logging.conf')
+#logger = logging.getLogger(__name__)
+
+logger = logging.getLogger('autocheck.snmpclient')
+
+
+def snmp_query(host, oid, version=2):
+    """
+    snmpwalk
+    """
+    dev_ip=host[0]
+    community=host[1]
+        
+    if oid[1]=='snmpdf':
+        try:
+            if version==2:
+                v_version="2c"
+            else:
+                v_version=str(version)
+            result = commands.getoutput("snmpdf -v " + v_version + " -c " + community + " " + dev_ip)
+            logger.debug('exec snmpdf result: %s', str(result))
+            result=tuple(result.split('\n'))
+            status = 0
+            
+        except Exception as e:
+            logger.error('get Exception : ' + str(e) , exc_info=True)
+            result = None
+            status = -1
+    else:
+        try:
+            result = netsnmp.snmpwalk(oid[1], Version=version, DestHost=dev_ip, Community=community)
+            logger.debug('exec snmpwalk oid[1] result: %s', str(result))
+            result = tuple(result)
+            status = 0
+        except Exception, err:
+            logger.error('get Exception : ' + str(e) , exc_info=True)
+            result = None
+            status = -1
+    return (host, oid, status, result)
+
+
+def snmp_result(res):
+    '''
+    '''
+    if res[2]==0:
+        logger.debug("%s exec command '%s' success." %(res[0][0], res[1][1]))
+    else:
+        logger.debug("%s exec command '%s' failed." %(res[0][0], res[1][1]))
+    
+    snmp_resultSet.add(res)
+
+
+def snmp_result_save(resSet):
+    '''
+    '''
+    if len(resSet)==0:
+        return
+    
+    saveSet=set()
+    
+    for res in resSet:
+        IP_ADDRESS=res[0][0]
+        DEVICE_ID=res[0][2]
+        oid=res[1][1]
+        status=res[2]
+        result=res[3]
+        if status!=0:
+            continue
+        if len(result)==0:
+            continue
+        if oid=='ssCpuIdle':
+            INSPECTION_INDEX='CPU_UTILIZATION'
+            INSPECTION_OBJECT='cpu'
+            INDEX_VALUE=100-int(result[0])
+            TOTAL=''
+            USED=''
+            saveSet.add((IP_ADDRESS, DEVICE_ID, INSPECTION_INDEX, INSPECTION_OBJECT, INDEX_VALUE, TOTAL, USED))
+        elif oid=='memTotalReal':
+            INSPECTION_INDEX='MEM_UTILIZATION'
+            INSPECTION_OBJECT=''
+            INSPECTION_OBJECT='Mem'
+            INDEX_VALUE=''
+            TOTAL=int(result[0])
+            USED=''
+            for res1 in resSet:
+                if IP_ADDRESS==res1[0][0] and DEVICE_ID==res1[0][2] and res1[1][1]=='memAvailReal':
+                    USED=TOTAL-int(res1[3][0])
+                    INDEX_VALUE=round(100*USED/TOTAL,2)
+            saveSet.add((IP_ADDRESS, DEVICE_ID, INSPECTION_INDEX, INSPECTION_OBJECT, INDEX_VALUE, TOTAL, USED))
+
+        elif oid=='snmpdf':
+            INSPECTION_INDEX='DISK_UTILIZATION'
+            for line in result:
+                if line.startswith('Description'):
+                    continue
+                if len(line.split())>5:
+                    INSPECTION_OBJECT=line.split()[0] + ' ' + line.split()[1]
+                    INDEX_VALUE=line.split()[5].replace('%','')
+                    TOTAL=line.split()[2]
+                    USED=line.split()[3] 
+                elif len(line.split())==5:
+                    INSPECTION_OBJECT=line.split()[0]
+                    INDEX_VALUE=line.split()[4].replace('%','')
+                    TOTAL=line.split()[1]
+                    USED=line.split()[2]
+                else:
+                    continue
+                saveSet.add((IP_ADDRESS, DEVICE_ID, INSPECTION_INDEX, INSPECTION_OBJECT, INDEX_VALUE, TOTAL, USED))
+        
+    logger.info('total %d result need to save', len(saveSet))
+    if len(saveSet)==0:
+        return 0
+
+    v_sql='''insert into isp_autoinspection_test(ip_address,device_id,inspection_index,inspection_object,index_value,total,used,inspection_time,into_time) values(:x1, :x2, :x3, :x4, :x5, :x6, :x7, trunc(sysdate,'hh24'), sysdate)'''
+    logger.info('exec result save sql : %s', v_sql)
+
+    try:
+        cf = ConfigParser.SafeConfigParser()
+        cf.read('conf/autocheck.conf')
+        db_url=cf.get('db', 'url')
+        nls_lang=cf.get('db', 'nls_lang')
+    except Exception as e:
+        logger.error('parse config file error: ' + str(e) , exc_info=True)
+        raise
+
+    if len(nls_lang)==0:
+        nls_lang='SIMPLIFIED CHINESE_CHINA.UTF8'
+
+    try:
+        dbclt=dbcn.DataBaseConn(db_url, nls_lang=nls_lang)
+    except Exception as e:
+        logger.error('connect db faild : ' + str(e) , exc_info=True)
+        return -1
+       
+    for rlst in saveSet:
+        try:
+            dbclt.exec_sql(v_sql, rlst)
+        except Exception as e:
+            logger.error('connect db faild : ' + str(e) , exc_info=True)
+    dbclt.conn.commit()
+    dbclt.close_connect()
+    logger.info('save result success')
+        
+
+def snmp_batch_cmd(hostSet, oidSet):
+    '''
+    '''
+    global snmp_resultSet
+    snmp_resultSet=set()
+    time_start=time.time()
+    max_thread=100
+
+    try:
+        cf = ConfigParser.SafeConfigParser()
+        cf.read('conf/autocheck.conf')
+        max_thread=cf.getint('snmpclient', 'max_thread')
+    except Exception as e:
+        logger.error('parse config file error: ' + str(e) , exc_info=True)
+        logger.debug('use defult : %d', max_thread)
+
+    if len(hostSet)<=max_thread:
+        pool_size=len(hostSet)
+    else:
+        pool_size=max_thread
+    
+    pool = multiprocessing.Pool(processes=pool_size)
+    
+    for host in hostSet:
+        for oid in oidSet:
+            pool.apply_async(snmp_query, (host, oid, ), callback=snmp_result)
+    pool.close()
+    pool.join()
+    
+    time_end=time.time()
+    time_used=time_end-time_start
+    logger.info("all sub-processes done, used time %d s" %time_used)
+
+    snmp_result_save(snmp_resultSet)
+    
+
+if __name__ == '__main__':
+
+    logging.config.fileConfig("conf/logging.conf")
+    #create logger
+    logger = logging.getLogger("snmpclient")
+
+    hostSet=set()
+    hostSet.add(('183.222.102.82', 'SNMP_COMMUNITY', 100))
+    hostSet.add(('183.222.102.14', 'SNMP_COMMUNITY', 101))
+
+    oidSet=set()
+    oidSet.add(('disk', 'snmpdf'))
+    oidSet.add(('mem', 'memTotalReal'))
+    oidSet.add(('mem', 'memAvailReal'))
+    oidSet.add(('cpu', 'ssCpuIdle'))
+    
+    snmp_batch_cmd(hostSet, oidSet)

+ 194 - 0
sshclient.py

@@ -0,0 +1,194 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""
+Created on Sat Dec  1 11:47:53 2018
+
+@author: dufs
+"""
+
+import time
+import logging
+import logging.config
+import ConfigParser
+import paramiko
+#import traceback
+import multiprocessing
+import databaseconn as dbcn
+
+
+#logging.config.fileConfig('conf/logging.conf')
+#logger = logging.getLogger(__name__)
+logger = logging.getLogger('autocheck.sshclient')
+
+
+def sshclient_execmd(host, execmd):
+
+    paramiko.util.log_to_file("log/paramiko.log")
+    
+    hostname=host[0]
+    port=host[1]
+    username=host[2]
+    password=host[3]
+    
+    try:
+        s = paramiko.SSHClient()
+        s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+
+        s.connect(hostname=hostname, port=port, username=username, password=password, timeout=3, compress=True)
+        stdin, stdout, stderr = s.exec_command (execmd[1])  
+        #stdin.write("Y")
+        result=stdout.read()
+        s.close()
+        logger.debug('get result : %s', str(result))
+        return (tuple([host[0], host[1], host[4]]), execmd, 0, result)
+
+    except Exception as e:
+        logger.error('get Exception : %s', str(e))
+        #traceback.print_exc()
+        return (tuple([host[0], host[1], host[4]]), execmd, -1, str(e))
+
+
+def ssh_result(res):
+    '''
+    '''
+    if res[2]==0:
+        logger.debug("%s exec command '%s' success.", res[0][0], res[1][1])
+    else:
+        logger.debug("%s exec command '%s' failed.", res[0][0], res[1][1])
+    
+    ssh_resultSet.add(res)
+
+
+def snmp_result_save(resSet):
+    '''
+    '''
+    if len(resSet)==0:
+        return
+    
+    saveSet=set()
+    
+    for res in resSet:
+        IP_ADDRESS=res[0][0]
+        DEVICE_ID=res[0][2]
+        cmd=res[1][0]
+        status=res[2]
+        result=res[3]
+        if status!=0:
+            continue
+        if cmd=='mkmfsinfo':
+            INSPECTION_INDEX='DISK_STATUS'
+            INSPECTION_OBJECT=''
+            INDEX_VALUE=''
+            TOTAL=''
+            USED=''
+            if len(result)==0:
+                continue
+            for line in result.split('\n'):
+                if len(line)==0:
+                    continue
+                if line.split()[0].startswith('devname'):
+                    continue
+                else:
+                    INSPECTION_OBJECT=line.split()[0]
+                    if line.split()[1]=='ACTIVE':
+                        INDEX_VALUE=1
+                    else:
+                        INDEX_VALUE=0
+                saveSet.add((IP_ADDRESS, DEVICE_ID, INSPECTION_INDEX, INSPECTION_OBJECT, INDEX_VALUE, TOTAL, USED))
+        elif cmd=='userinfo':
+            INSPECTION_INDEX='ACCOUNT'
+            INSPECTION_OBJECT=''
+            INDEX_VALUE=''
+            TOTAL=''
+            USED=''
+            for user in result.split('\n'):
+                if len(user)==0:
+                    continue
+                INSPECTION_OBJECT=user
+                saveSet.add((IP_ADDRESS, DEVICE_ID, INSPECTION_INDEX, INSPECTION_OBJECT, INDEX_VALUE, TOTAL, USED))
+
+    logger.info('total %d result need to save', len(saveSet))
+    if len(saveSet)==0:
+        return 0
+
+    v_sql='''insert into isp_autoinspection_test(ip_address,device_id,inspection_index,inspection_object,index_value,total,used,inspection_time,into_time) values(:x1, :x2, :x3, :x4, :x5, :x6, :x7, trunc(sysdate,'hh24'), sysdate)'''
+    logger.info('exec result save sql : %s', v_sql)
+
+    try:
+        cf = ConfigParser.SafeConfigParser()
+        cf.read('conf/autocheck.conf')
+        db_url=cf.get('db', 'url')
+        nls_lang=cf.get('db', 'nls_lang')
+    except Exception as e:
+        logger.error('parse config file error: ' + str(e) , exc_info=True)
+        raise
+
+    if len(nls_lang)==0:
+        nls_lang='SIMPLIFIED CHINESE_CHINA.UTF8'
+    
+    try:
+        dbclt=dbcn.DataBaseConn(db_url, nls_lang=nls_lang)
+    except Exception as e:
+        logger.error('connect db faild : ' + str(e) , exc_info=True)
+        raise
+
+    for rlst in saveSet:
+        try:
+            dbclt.exec_sql(v_sql, rlst)
+        except Exception as e:
+            logger.error('connect db faild : ' + str(e) , exc_info=True)
+    dbclt.conn.commit()
+    dbclt.close_connect()
+    logger.info('save result success')
+            
+    
+def ssh_batch_cmd(hostSet, cmdSet):
+    global ssh_resultSet
+    ssh_resultSet=set()
+    time_start=time.time()
+
+    max_thread=100
+    try:
+        cf = ConfigParser.SafeConfigParser()
+        cf.read('conf/autocheck.conf')
+        max_thread=cf.getint('sshclient', 'max_thread')
+    except Exception as e:
+        logger.error('parse config file error: ' + str(e) , exc_info=True)
+        logger.debug('use defult : %d', max_thread)
+
+    if len(hostSet)<=max_thread:
+        pool_size=len(hostSet)
+    else:
+        pool_size=max_thread
+    
+    pool = multiprocessing.Pool(processes=pool_size)
+    
+    for host in hostSet:        
+        for execmd in cmdSet:
+            pool.apply_async(sshclient_execmd, (host, execmd), callback=ssh_result)
+    pool.close()
+    pool.join()
+    
+    time_end=time.time()
+    time_used=time_end-time_start
+    logger.info("all sub-processes done, used time %d s", time_used)
+
+    snmp_result_save(ssh_resultSet)
+    
+
+if __name__ == "__main__":
+
+    logging.config.fileConfig("conf/logging.conf")
+    #create logger
+    logger = logging.getLogger("sshclient")
+    
+    hostSet=set()
+    hostSet.add(('10.102.52.9', 22444, 'iss', 'Iss@52.8!', 101))
+    hostSet.add(('10.102.52.10', 22444, 'iss', 'Iss@52.8!', 102))
+
+    cmdSet=set()
+    cmdSet.add(('userinfo', '''cat /etc/passwd |awk -F":" '{print $1}' '''))
+    cmdSet.add(('mkmfsinfo', "sudo -u root mkmfsinfo -querydisk |awk '{print $1,$8}'"))
+    
+    ssh_batch_cmd(hostSet, cmdSet)

BIN
testP.jar