[Supervisor-checkins] r829 - superlance/trunk/superlance

Chris McDonough chrism at agendaless.com
Wed Dec 10 17:48:46 EST 2008


Author: Chris McDonough <chrism at agendaless.com>
Date: Wed Dec 10 17:48:45 2008
New Revision: 829

Log:
Add gcore capability.


Modified:
   superlance/trunk/superlance/httpok.py
   superlance/trunk/superlance/tests.py

Modified: superlance/trunk/superlance/httpok.py
==============================================================================
--- superlance/trunk/superlance/httpok.py	(original)
+++ superlance/trunk/superlance/httpok.py	Wed Dec 10 17:48:45 2008
@@ -25,7 +25,7 @@
 # events=TICK_60
 
 doc = """\
-httpok.py [-p processname] [-a] [-t timeout] [-c status_code] [-b inbody]
+httpok.py [-p processname] [-a] [-g] [-t timeout] [-c status_code] [-b inbody]
           [-m mail_address] [-s sendmail] URL
 
 Options:
@@ -41,6 +41,15 @@
       any -p parameters passed in the same httpok process
       invocation.
 
+-g -- The ``gcore`` program.  By default, this is ``/usr/bin/gcore
+      -o``.  The program should accept two arguments on the command
+      line: a filename and a pid.
+
+-d -- Core directory.  If a core directory is specified, httpok will
+      try to use the ``gcore`` program (see ``-g``) to write a core
+      file into this directory against each hung process before we
+      restart it.  Append gcore stdout output to email.
+
 -t -- The number of seconds that httpok should wait for a response
       before timing out.  If this timeout is exceeded, httpok will
       attempt to restart processes in the RUNNING state specified by
@@ -98,7 +107,7 @@
 class HTTPOk:
     connclass = None
     def __init__(self, rpc, programs, any, url, timeout, status, inbody,
-                 email, sendmail):
+                 email, sendmail, coredir, gcore):
         self.rpc = rpc
         self.programs = programs
         self.any = any
@@ -108,6 +117,8 @@
         self.inbody = inbody
         self.email = email
         self.sendmail = sendmail
+        self.coredir = coredir
+        self.gcore = gcore
         self.stdin = sys.stdin
         self.stdout = sys.stdout
         self.stderr = sys.stderr
@@ -237,6 +248,11 @@
     def restart(self, spec, write):
         namespec = make_namespec(spec['group'], spec['name'])
         if spec['state'] is ProcessStates.RUNNING:
+            if self.coredir and self.gcore:
+                corename = os.path.join(self.coredir, namespec)
+                m = os.popen(self.gcore + ' "%s" %s' % (corename, spec['pid']))
+                write('gcore output for %s:\n\n %s' % (namespec, m.read()))
+                m.close()
             write('%s is in RUNNING state, restarting' % namespec)
             try:
                 self.rpc.supervisor.stopProcess(namespec)
@@ -258,17 +274,18 @@
 
 def main(argv=sys.argv):
     import getopt
-    short_args="hp:g:at:c:b:s:m:"
+    short_args="hp:at:c:b:s:m:g:d:"
     long_args=[
         "help",
         "program=",
-        "group=",
         "any",
         "timeout=",
         "code=",
         "body=",
         "sendmail_program=",
         "email=",
+        "gcore=",
+        "coredir=",
         ]
     arguments = argv[1:]
     try:
@@ -284,6 +301,8 @@
     programs = []
     any = False
     sendmail = '/usr/sbin/sendmail -t -i'
+    gcore = '/usr/bin/gcore -o'
+    coredir = None
     email = None
     timeout = 10
     status = '200'
@@ -315,6 +334,12 @@
         if option in ('-b', '--body'):
             inbody = value
 
+        if option in ('-g', '--gcore'):
+            gcore = value
+
+        if option in ('-d', '--coredir'):
+            coredir = value
+
     url = arguments[-1]
 
     try:
@@ -328,7 +353,7 @@
         return
 
     prog = HTTPOk(rpc, programs, any, url, timeout, status, inbody, email,
-                  sendmail)
+                  sendmail, coredir, gcore)
     prog.runforever()
 
 if __name__ == '__main__':

Modified: superlance/trunk/superlance/tests.py
==============================================================================
--- superlance/trunk/superlance/tests.py	(original)
+++ superlance/trunk/superlance/tests.py	Wed Dec 10 17:48:45 2008
@@ -10,7 +10,8 @@
     def _makeOne(self, *opts):
         return self._getTargetClass()(*opts)
 
-    def _makeOnePopulated(self, programs, any, response=None, exc=None):
+    def _makeOnePopulated(self, programs, any, response=None, exc=None,
+                          gcore=None, coredir=None):
         if response is None:
             response = DummyResponse()
         rpc = DummyRPCServer()
@@ -20,8 +21,10 @@
         timeout = 10
         status = '200'
         inbody = None
+        gcore = gcore
+        coredir = coredir
         prog = self._makeOne(rpc, programs, any, url, timeout, status,
-                             inbody, email, sendmail)
+                             inbody, email, sendmail, coredir, gcore)
         prog.stdin = StringIO()
         prog.stdout = StringIO()
         prog.stderr = StringIO()
@@ -128,6 +131,35 @@
         self.assertEqual(mailed[1],
                     'Subject: httpok for http://foo/bar: bad status returned')
 
+    def test_runforever_gcore(self):
+        programs = ['foo', 'bar', 'baz_01', 'notexisting']
+        any = None
+        prog = self._makeOnePopulated(programs, any, exc=True, gcore="true",
+                                      coredir="/tmp")
+        prog.stdin.write('eventname:TICK len:0\n')
+        prog.stdin.seek(0)
+        prog.runforever(test=True)
+        lines = prog.stderr.getvalue().split('\n')
+        self.assertEqual(lines[0],
+                         ("Restarting selected processes ['foo', 'bar', "
+                          "'baz_01', 'notexisting']")
+                         )
+        self.assertEqual(lines[1], 'gcore output for foo:')
+        self.assertEqual(lines[2], '')
+        self.assertEqual(lines[3], ' ')
+        self.assertEqual(lines[4], 'foo is in RUNNING state, restarting')
+        self.assertEqual(lines[5], 'foo restarted')
+        self.assertEqual(lines[6], 'bar not in RUNNING state, NOT restarting')
+        self.assertEqual(lines[7],
+                         'baz:baz_01 not in RUNNING state, NOT restarting')
+        self.assertEqual(lines[8],
+          "Programs not restarted because they did not exist: ['notexisting']")
+        mailed = prog.mailed.split('\n')
+        self.assertEqual(len(mailed), 15)
+        self.assertEqual(mailed[0], 'To: chrism at plope.com')
+        self.assertEqual(mailed[1],
+                    'Subject: httpok for http://foo/bar: bad status returned')
+
 class CrashMailTests(unittest.TestCase):
     def _getTargetClass(self):
         from superlance.crashmail import CrashMail


More information about the Supervisor-checkins mailing list