1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
|
#!/usr/bin/env python
""" monitor.py
This runs a sequence of commands on a remote host using SSH.
It runs a simple system checks such as uptime and free to monitor
the state of the remote host.
./monitor.py [-s server_hostname] [-u username] [-p password]
-s : hostname of the remote server to login to.
-u : username to user for login.
-p : Password to user for login.
Example:
This will print information about the given host:
./monitor.py -s www.example.com -u mylogin -p mypassword
It works like this:
Login via SSH (This is the hardest part).
Run and parse 'uptime'.
Run 'iostat'.
Run 'vmstat'.
Run 'netstat'
Run 'free'.
Exit the remote host.
"""
import os, sys, time, re, getopt, getpass
import traceback
import pexpect
#
# Some constants.
#
COMMAND_PROMPT = '[#$] ' ### This is way too simple for industrial use -- we will change is ASAP.
TERMINAL_PROMPT = '(?i)terminal type\?'
TERMINAL_TYPE = 'vt100'
# This is the prompt we get if SSH does not have the remote host's public key stored in the cache.
SSH_NEWKEY = '(?i)are you sure you want to continue connecting'
def exit_with_usage():
print globals()['__doc__']
os._exit(1)
def main():
global COMMAND_PROMPT, TERMINAL_PROMPT, TERMINAL_TYPE, SSH_NEWKEY
######################################################################
## Parse the options, arguments, get ready, etc.
######################################################################
try:
optlist, args = getopt.getopt(sys.argv[1:], 'h?s:u:p:', ['help','h','?'])
except Exception, e:
print str(e)
exit_with_usage()
options = dict(optlist)
if len(args) > 1:
exit_with_usage()
if [elem for elem in options if elem in ['-h','--h','-?','--?','--help']]:
print "Help:"
exit_with_usage()
if '-s' in options:
host = options['-s']
else:
host = raw_input('hostname: ')
if '-u' in options:
user = options['-u']
else:
user = raw_input('username: ')
if '-p' in options:
password = options['-p']
else:
password = getpass.getpass('password: ')
#
# Login via SSH
#
child = pexpect.spawn('ssh -l %s %s'%(user, host))
i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY, COMMAND_PROMPT, '(?i)password'])
if i == 0: # Timeout
print 'ERROR! could not login with SSH. Here is what SSH said:'
print child.before, child.after
print str(child)
sys.exit (1)
if i == 1: # In this case SSH does not have the public key cached.
child.sendline ('yes')
child.expect ('(?i)password')
if i == 2:
# This may happen if a public key was setup to automatically login.
# But beware, the COMMAND_PROMPT at this point is very trivial and
# could be fooled by some output in the MOTD or login message.
pass
if i == 3:
child.sendline(password)
# Now we are either at the command prompt or
# the login process is asking for our terminal type.
i = child.expect ([COMMAND_PROMPT, TERMINAL_PROMPT])
if i == 1:
child.sendline (TERMINAL_TYPE)
child.expect (COMMAND_PROMPT)
#
# Set command prompt to something more unique.
#
COMMAND_PROMPT = "\[PEXPECT\]\$ "
child.sendline ("PS1='[PEXPECT]\$ '") # In case of sh-style
i = child.expect ([pexpect.TIMEOUT, COMMAND_PROMPT], timeout=10)
if i == 0:
print "# Couldn't set sh-style prompt -- trying csh-style."
child.sendline ("set prompt='[PEXPECT]\$ '")
i = child.expect ([pexpect.TIMEOUT, COMMAND_PROMPT], timeout=10)
if i == 0:
print "Failed to set command prompt using sh or csh style."
print "Response was:"
print child.before
sys.exit (1)
# Now we should be at the command prompt and ready to run some commands.
print '---------------------------------------'
print 'Report of commands run on remote host.'
print '---------------------------------------'
# Run uname.
child.sendline ('uname -a')
child.expect (COMMAND_PROMPT)
print child.before
if 'linux' in child.before.lower():
LINUX_MODE = 1
else:
LINUX_MODE = 0
# Run and parse 'uptime'.
child.sendline ('uptime')
child.expect('up\s+(.*?),\s+([0-9]+) users?,\s+load averages?: ([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9])')
duration, users, av1, av5, av15 = child.match.groups()
days = '0'
hours = '0'
mins = '0'
if 'day' in duration:
child.match = re.search('([0-9]+)\s+day',duration)
days = str(int(child.match.group(1)))
if ':' in duration:
child.match = re.search('([0-9]+):([0-9]+)',duration)
hours = str(int(child.match.group(1)))
mins = str(int(child.match.group(2)))
if 'min' in duration:
child.match = re.search('([0-9]+)\s+min',duration)
mins = str(int(child.match.group(1)))
print
print 'Uptime: %s days, %s users, %s (1 min), %s (5 min), %s (15 min)' % (
duration, users, av1, av5, av15)
child.expect (COMMAND_PROMPT)
# Run iostat.
child.sendline ('iostat')
child.expect (COMMAND_PROMPT)
print child.before
# Run vmstat.
child.sendline ('vmstat')
child.expect (COMMAND_PROMPT)
print child.before
# Run free.
if LINUX_MODE:
child.sendline ('free') # Linux systems only.
child.expect (COMMAND_PROMPT)
print child.before
# Run df.
child.sendline ('df')
child.expect (COMMAND_PROMPT)
print child.before
# Run lsof.
child.sendline ('lsof')
child.expect (COMMAND_PROMPT)
print child.before
# # Run netstat
# child.sendline ('netstat')
# child.expect (COMMAND_PROMPT)
# print child.before
# # Run MySQL show status.
# child.sendline ('mysql -p -e "SHOW STATUS;"')
# child.expect (PASSWORD_PROMPT_MYSQL)
# child.sendline (password_mysql)
# child.expect (COMMAND_PROMPT)
# print
# print child.before
# Now exit the remote host.
child.sendline ('exit')
index = child.expect([pexpect.EOF, "(?i)there are stopped jobs"])
if index==1:
child.sendline("exit")
child.expect(EOF)
if __name__ == "__main__":
try:
main()
except Exception, e:
print str(e)
traceback.print_exc()
os._exit(1)
|