18a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#!/usr/bin/env python
28a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
38a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen""" This runs a sequence of commands on a remote host using SSH. It runs a
48a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chensimple system checks such as uptime and free to monitor the state of the remote
58a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenhost.
68a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
78a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen./monitor.py [-s server_hostname] [-u username] [-p password]
88a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    -s : hostname of the remote server to login to.
98a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    -u : username to user for login.
108a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    -p : Password to user for login.
118a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
128a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny ChenExample:
138a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    This will print information about the given host:
148a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        ./monitor.py -s www.example.com -u mylogin -p mypassword
158a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
168a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny ChenIt works like this:
178a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    Login via SSH (This is the hardest part).
188a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    Run and parse 'uptime'.
198a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    Run 'iostat'.
208a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    Run 'vmstat'.
218a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    Run 'netstat'
228a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    Run 'free'.
238a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    Exit the remote host.
248a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen"""
258a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
268a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenimport os, sys, time, re, getopt, getpass
278a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenimport traceback
288a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenimport pexpect
298a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
308a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#
318a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen# Some constants.
328a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#
338a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny ChenCOMMAND_PROMPT = '[#$] ' ### This is way too simple for industrial use -- we will change is ASAP.
348a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny ChenTERMINAL_PROMPT = '(?i)terminal type\?'
358a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny ChenTERMINAL_TYPE = 'vt100'
368a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen# This is the prompt we get if SSH does not have the remote host's public key stored in the cache.
378a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny ChenSSH_NEWKEY = '(?i)are you sure you want to continue connecting'
388a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
398a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chendef exit_with_usage():
408a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
418a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    print globals()['__doc__']
428a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    os._exit(1)
438a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
448a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chendef main():
458a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
468a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    global COMMAND_PROMPT, TERMINAL_PROMPT, TERMINAL_TYPE, SSH_NEWKEY
478a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    ######################################################################
488a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    ## Parse the options, arguments, get ready, etc.
498a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    ######################################################################
508a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    try:
518a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        optlist, args = getopt.getopt(sys.argv[1:], 'h?s:u:p:', ['help','h','?'])
528a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    except Exception, e:
538a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        print str(e)
548a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        exit_with_usage()
558a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    options = dict(optlist)
568a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if len(args) > 1:
578a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        exit_with_usage()
588a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
598a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if [elem for elem in options if elem in ['-h','--h','-?','--?','--help']]:
608a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        print "Help:"
618a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        exit_with_usage()
628a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
638a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if '-s' in options:
648a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        host = options['-s']
658a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    else:
668a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        host = raw_input('hostname: ')
678a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if '-u' in options:
688a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        user = options['-u']
698a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    else:
708a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        user = raw_input('username: ')
718a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if '-p' in options:
728a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        password = options['-p']
738a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    else:
748a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        password = getpass.getpass('password: ')
758a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
768a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    #
778a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    # Login via SSH
788a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    #
798a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child = pexpect.spawn('ssh -l %s %s'%(user, host))
808a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY, COMMAND_PROMPT, '(?i)password'])
818a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if i == 0: # Timeout
828a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        print 'ERROR! could not login with SSH. Here is what SSH said:'
838a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        print child.before, child.after
848a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        print str(child)
858a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        sys.exit (1)
868a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if i == 1: # In this case SSH does not have the public key cached.
878a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        child.sendline ('yes')
888a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        child.expect ('(?i)password')
898a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if i == 2:
908a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        # This may happen if a public key was setup to automatically login.
918a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        # But beware, the COMMAND_PROMPT at this point is very trivial and
928a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        # could be fooled by some output in the MOTD or login message.
938a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        pass
948a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if i == 3:
958a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        child.sendline(password)
968a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        # Now we are either at the command prompt or
978a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        # the login process is asking for our terminal type.
988a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        i = child.expect ([COMMAND_PROMPT, TERMINAL_PROMPT])
998a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        if i == 1:
1008a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            child.sendline (TERMINAL_TYPE)
1018a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            child.expect (COMMAND_PROMPT)
1028a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    #
1038a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    # Set command prompt to something more unique.
1048a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    #
1058a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    COMMAND_PROMPT = "\[PEXPECT\]\$ "
1068a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.sendline ("PS1='[PEXPECT]\$ '") # In case of sh-style
1078a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    i = child.expect ([pexpect.TIMEOUT, COMMAND_PROMPT], timeout=10)
1088a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if i == 0:
1098a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        print "# Couldn't set sh-style prompt -- trying csh-style."
1108a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        child.sendline ("set prompt='[PEXPECT]\$ '")
1118a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        i = child.expect ([pexpect.TIMEOUT, COMMAND_PROMPT], timeout=10)
1128a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        if i == 0:
1138a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            print "Failed to set command prompt using sh or csh style."
1148a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            print "Response was:"
1158a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            print child.before
1168a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            sys.exit (1)
1178a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1188a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    # Now we should be at the command prompt and ready to run some commands.
1198a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    print '---------------------------------------'
1208a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    print 'Report of commands run on remote host.'
1218a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    print '---------------------------------------'
1228a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1238a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    # Run uname.
1248a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.sendline ('uname -a')
1258a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.expect (COMMAND_PROMPT)
1268a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    print child.before
1278a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if 'linux' in child.before.lower():
1288a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        LINUX_MODE = 1
1298a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    else:
1308a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        LINUX_MODE = 0
1318a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1328a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    # Run and parse 'uptime'.
1338a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.sendline ('uptime')
1348a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    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])')
1358a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    duration, users, av1, av5, av15 = child.match.groups()
1368a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    days = '0'
1378a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    hours = '0'
1388a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    mins = '0'
1398a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if 'day' in duration:
1408a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        child.match = re.search('([0-9]+)\s+day',duration)
1418a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        days = str(int(child.match.group(1)))
1428a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if ':' in duration:
1438a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        child.match = re.search('([0-9]+):([0-9]+)',duration)
1448a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        hours = str(int(child.match.group(1)))
1458a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        mins = str(int(child.match.group(2)))
1468a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if 'min' in duration:
1478a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        child.match = re.search('([0-9]+)\s+min',duration)
1488a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        mins = str(int(child.match.group(1)))
1498a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    print
1508a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    print 'Uptime: %s days, %s users, %s (1 min), %s (5 min), %s (15 min)' % (
1518a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        duration, users, av1, av5, av15)
1528a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.expect (COMMAND_PROMPT)
1538a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1548a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    # Run iostat.
1558a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.sendline ('iostat')
1568a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.expect (COMMAND_PROMPT)
1578a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    print child.before
1588a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1598a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    # Run vmstat.
1608a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.sendline ('vmstat')
1618a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.expect (COMMAND_PROMPT)
1628a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    print child.before
1638a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1648a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    # Run free.
1658a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if LINUX_MODE:
1668a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        child.sendline ('free') # Linux systems only.
1678a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        child.expect (COMMAND_PROMPT)
1688a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        print child.before
1698a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1708a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    # Run df.
1718a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.sendline ('df')
1728a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.expect (COMMAND_PROMPT)
1738a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    print child.before
1748a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1758a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    # Run lsof.
1768a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.sendline ('lsof')
1778a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.expect (COMMAND_PROMPT)
1788a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    print child.before
1798a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1808a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#    # Run netstat
1818a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#    child.sendline ('netstat')
1828a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#    child.expect (COMMAND_PROMPT)
1838a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#    print child.before
1848a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1858a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#    # Run MySQL show status.
1868a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#    child.sendline ('mysql -p -e "SHOW STATUS;"')
1878a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#    child.expect (PASSWORD_PROMPT_MYSQL)
1888a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#    child.sendline (password_mysql)
1898a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#    child.expect (COMMAND_PROMPT)
1908a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#    print
1918a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#    print child.before
1928a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1938a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    # Now exit the remote host.
1948a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    child.sendline ('exit')
1958a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    index = child.expect([pexpect.EOF, "(?i)there are stopped jobs"])
1968a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    if index==1:
1978a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        child.sendline("exit")
1988a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        child.expect(EOF)
1998a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
2008a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenif __name__ == "__main__":
2018a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
2028a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    try:
2038a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        main()
2048a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    except Exception, e:
2058a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        print str(e)
2068a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        traceback.print_exc()
2078a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        os._exit(1)
2088a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
209