hi chris
updated memmon.py, docs and tests.
patch attached.
not sure about the additional test_subject_no_name.
maybe there is a way to test this in a cleaner way?
i did not test the option/argument parser yet.
would be great to see a 0.6 release soon, so i can use the new feature in
production ;-)
regards, harald
Am Freitag, 30. Juli 2010, um 08:48:21 schrieb Chris McDonough:
> On Fri, 2010-07-30 at 08:42 +0200, Harald Friessnegger wrote:
> > hi chris
> >
> > you are right about the slam-dunk, and about the *-mail.
> >
> > i'll see if i can add the feature this weekend - looks like it'll be
> > raining anyway here in austria ;-)
> >
> > could you give me access to http://svn.supervisord.org/superlance/ or do
> > you prefere a patch for current trunk?
>
> A patch is fine. The tests can be run via "python setup.py test".
> Please add tests if possible, too. There are docs in the "docs"
> directory of superlance that will need updating too.
>
> Thanks!
--
Webmeisterei GmbH - Büro für Netzfragen
Tel: +43 5572 908877, Fax: +43 5572 908877-66
Steinebach 18, A-6850 Dornbirn
http://www.webmeisterei.com
Index: CHANGES.txt
===================================================================
--- CHANGES.txt (revision 980)
+++ CHANGES.txt (working copy)
@@ -4,6 +4,12 @@
Next Release
------------
+- Added ``-n`` option to memmon that adds this name to the email
+ subject to identify which memmon process restarted a process.
+ Useful in case you run multiple supervisors that control
+ different processes with the same name.
+ [fRiSi]
+
- Separated unit tests into their own files
- Created ``fatalmailbatch`` plugin
Index: docs/memmon.rst
===================================================================
--- docs/memmon.rst (revision 980)
+++ docs/memmon.rst (working copy)
@@ -29,7 +29,7 @@
.. code-block:: sh
$ memmon [-p processname=byte_size] [-g groupname=byte_size] \
- [-a byte_size] [-s sendmail] [-m email_address]
+ [-a byte_size] [-s sendmail] [-m email_address] [-n memmon_name]
.. program:: memmon
@@ -84,6 +84,17 @@
By default, memmon will not send any mail unless an email address is
specified.
+.. cmdoption:: -n <memmon name>, --name=<memmon name>
+
+ An optional name that identifies this memmon process. If given, the
+ email subject will start with ``memmon [<memmon name>]:`` instead
+ of ``memmon:``
+ In case you run multiple supervisors on a single host that control
+ different processes with the same name (eg `zopeinstance1`) you can
+ use this option to indicate which project the restarted instance
+ belongs to.
+
+
Configuring :command:`memmon` Into the Supervisor Config
--------------------------------------------------------
Index: superlance/memmon.py
===================================================================
--- superlance/memmon.py (revision 980)
+++ superlance/memmon.py (working copy)
@@ -27,8 +27,9 @@
# events=TICK_60
doc = """\
-memmon.py [-p processname=byte_size] [-g groupname=byte_size]
+memmon.py [-p processname=byte_size] [-g groupname=byte_size]
[-a byte_size] [-s sendmail] [-m email_address]
+ [-n memmon_name]
Options:
@@ -36,10 +37,10 @@
process named 'process_name' when it uses more than byte_size
RSS. If this process is in a group, it can be specified using
the 'process_name:group_name' syntax.
-
+
-g -- specify a group_name=byte_size pair. Restart any process in this group
when it uses more than byte_size RSS.
-
+
-a -- specify a global byte_size. Restart any child of the supervisord
under which this runs if it uses more than byte_size RSS.
@@ -52,6 +53,10 @@
address when any process is restarted. If no email address is
specified, email will not be sent.
+-n -- optionally specify the name of the memmon process. This name will
+ be used in the email subject to identify which memmon process
+ restarted the process.
+
The -p and -g options may be specified more than once, allowing for
specification of multiple groups and processes.
@@ -61,7 +66,7 @@
A sample invocation:
-memmon.py -p program1=200MB -p theprog:thegroup=100MB -g thegroup=100MB -a 1GB
-s "/usr/sbin/sendmail -t -i" -m [email protected]
+memmon.py -p program1=200MB -p theprog:thegroup=100MB -g thegroup=100MB -a 1GB
-s "/usr/sbin/sendmail -t -i" -m [email protected] -n "Project 1"
"""
import os
@@ -80,12 +85,13 @@
return os.popen(cmd).read()
class Memmon:
- def __init__(self, programs, groups, any, sendmail, email, rpc):
+ def __init__(self, programs, groups, any, sendmail, email, name, rpc):
self.programs = programs
self.groups = groups
self.any = any
self.sendmail = sendmail
self.email = email
+ self.memmonName = name
self.rpc = rpc
self.stdin = sys.stdin
self.stdout = sys.stdout
@@ -174,7 +180,7 @@
def restart(self, name, rss):
self.stderr.write('Restarting %s\n' % name)
-
+ memmonId = self.memmonName and " [%s]" % self.memmonName or ""
try:
self.rpc.supervisor.stopProcess(name)
except xmlrpclib.Fault, what:
@@ -182,7 +188,7 @@
(name, rss, what))
self.stderr.write(str(msg))
if self.email:
- subject = 'memmon: failed to stop process %s, exiting' % name
+ subject = 'memmon%s: failed to stop process %s, exiting' %
(memmonId, name)
self.mail(self.email, subject, msg)
raise
@@ -193,7 +199,7 @@
'exiting: %s' % (name, what))
self.stderr.write(str(msg))
if self.email:
- subject = 'memmon: failed to start process %s, exiting' % name
+ subject = 'memmon%s: failed to start process %s, exiting' %
(memmonId, name)
self.mail(self.email, subject, msg)
raise
@@ -204,7 +210,7 @@
'it was consuming too much memory (%s bytes RSS)' % (
name, now, rss)
)
- subject = 'memmon: process %s restarted' % name
+ subject = 'memmon%s: process %s restarted' % (memmonId, name)
self.mail(self.email, subject, msg)
def mail(self, email, subject, msg):
@@ -216,7 +222,7 @@
m.write(body)
m.close()
self.mailed = body
-
+
def parse_namesize(option, value):
try:
name, size = value.split('=')
@@ -232,12 +238,12 @@
except:
print 'Unparseable byte_size in %r for %r' % (value, option)
usage()
-
+
return size
def main():
import getopt
- short_args="hp:g:a:s:m:"
+ short_args="hp:g:a:s:m:n:"
long_args=[
"help",
"program=",
@@ -245,6 +251,7 @@
"any=",
"sendmail_program=",
"email=",
+ "name=",
]
arguments = sys.argv[1:]
if not arguments:
@@ -260,6 +267,7 @@
any = None
sendmail = '/usr/sbin/sendmail -t -i'
email = None
+ name = None
for option, value in opts:
@@ -284,12 +292,15 @@
if option in ('-m', '--email'):
email = value
+ if option in ('-n', '--name'):
+ name = value
+
rpc = childutils.getRPCInterface(os.environ)
- memmon = Memmon(programs, groups, any, sendmail, email, rpc)
+ memmon = Memmon(programs, groups, any, sendmail, email, name, rpc)
memmon.runforever()
if __name__ == '__main__':
main()
-
-
-
+
+
+
Index: superlance/tests/memmon_test.py
===================================================================
--- superlance/tests/memmon_test.py (revision 980)
+++ superlance/tests/memmon_test.py (working copy)
@@ -7,7 +7,7 @@
def _getTargetClass(self):
from superlance.memmon import Memmon
return Memmon
-
+
def _makeOne(self, *opts):
return self._getTargetClass()(*opts)
@@ -15,13 +15,14 @@
rpc = DummyRPCServer()
sendmail = 'cat - > /dev/null'
email = '[email protected]'
- memmon = self._makeOne(programs, groups, any, sendmail, email, rpc)
+ name = 'test'
+ memmon = self._makeOne(programs, groups, any, sendmail, email, name,
rpc)
memmon.stdin = StringIO()
memmon.stdout = StringIO()
memmon.stderr = StringIO()
memmon.pscommand = 'echo 22%s'
return memmon
-
+
def test_runforever_notatick(self):
programs = {'foo':0, 'bar':0, 'baz_01':0 }
groups = {}
@@ -54,7 +55,7 @@
self.assertEqual(len(mailed), 4)
self.assertEqual(mailed[0], 'To: [email protected]')
self.assertEqual(mailed[1],
- 'Subject: memmon: process baz:baz_01 restarted')
+ 'Subject: memmon [test]: process baz:baz_01
restarted')
self.assertEqual(mailed[2], '')
self.failUnless(mailed[3].startswith('memmon.py restarted'))
@@ -76,7 +77,7 @@
self.assertEqual(len(mailed), 4)
self.assertEqual(mailed[0], 'To: [email protected]')
self.assertEqual(mailed[1],
- 'Subject: memmon: process foo:foo restarted')
+ 'Subject: memmon [test]: process foo:foo restarted')
self.assertEqual(mailed[2], '')
self.failUnless(mailed[3].startswith('memmon.py restarted'))
@@ -122,7 +123,7 @@
self.assertEqual(len(mailed), 4)
self.assertEqual(mailed[0], 'To: [email protected]')
self.assertEqual(mailed[1],
- 'Subject: memmon: process baz:baz_01 restarted')
+ 'Subject: memmon [test]: process baz:baz_01
restarted')
self.assertEqual(mailed[2], '')
self.failUnless(mailed[3].startswith('memmon.py restarted'))
@@ -188,9 +189,27 @@
self.assertEqual(len(mailed), 4)
self.assertEqual(mailed[0], 'To: [email protected]')
self.assertEqual(mailed[1],
- 'Subject: memmon: failed to stop process BAD_NAME:BAD_NAME, exiting')
+ 'Subject: memmon [test]: failed to stop process BAD_NAME:BAD_NAME,
exiting')
self.assertEqual(mailed[2], '')
self.failUnless(mailed[3].startswith('Failed'))
-
+
+ def test_subject_no_name(self):
+ """set the name to None to check if subject
+ stays `memmon:...` instead `memmon [<name>]:...`
+ """
+ programs = {}
+ groups = {}
+ any = 0
+ memmon = self._makeOnePopulated(programs, groups, any)
+ memmon.memmonName = None
+ memmon.stdin.write('eventname:TICK len:0\n')
+ memmon.stdin.seek(0)
+ memmon.runforever(test=True)
+
+ mailed = memmon.mailed.split('\n')
+ self.assertEqual(mailed[1],
+ 'Subject: memmon: process baz:baz_01 restarted')
+
+
if __name__ == '__main__':
- unittest.main()
\ No newline at end of file
+ unittest.main()
\ No newline at end of file
_______________________________________________
Supervisor-users mailing list
[email protected]
http://lists.supervisord.org/mailman/listinfo/supervisor-users