Skip to content

Commit 1a14069

Browse files
committed
implement --program option in crashmail
1 parent 5823ecd commit 1a14069

File tree

7 files changed

+90
-6
lines changed

7 files changed

+90
-6
lines changed

conftest/README

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
To test
2+
- copy crashin fakemail to /R/bin
3+
- copy crashmail.conf testcrash.conf testcrash2.conf to /etc/supervisor/conf.d
4+
5+
monitor log files in /L/
6+
- You'll get an 'Ignoring hostname: testcrash' message every 10s in /L/crashmail.log (testcrash)
7+
8+
- You'll get 2 'unexpected exit, mailing' message every 30s in /L/crashmail.log (notifycrash:testcrash2, notifycrash:testcrash3)
9+
and the message in /L/fakemail.log

conftest/crashin

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash
2+
# test program: non 0 exit code after timeout
3+
timeout="$1"
4+
echo $(date) "Crashing in $timeout seconds"
5+
sleep "$timeout"
6+
echo $(date) "CRASHING NOW"
7+
exit 123

conftest/crashmail.conf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# config to use the fakemail mail sender
2+
# and monitor only testcrash2 (crashes every 30s)
3+
[eventlistener:crashmail]
4+
command =
5+
/usr/local/bin/crashmail
6+
-p notifycrash:*
7+
-o hostname -m [email protected]
8+
-s '/R/bin/fakemail -t -i -f [email protected]'
9+
events=PROCESS_STATE_EXITED
10+
stderr_logfile=/L/crashmail.log

conftest/fakemail

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/bash
2+
# don't send any mail: only write the args and stdin to the logfile
3+
logfile=/L/fakemail.log
4+
echo $(date) "$*" >> "$logfile"
5+
cat >> "$logfile"
6+
echo >> "$logfile"

conftest/testcrash.conf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# test program: crashes every 10 seconds
2+
[program:testcrash]
3+
command=/R/bin/crashin 10
4+
5+
autostart=true
6+
autorestart=true
7+
8+
stdout_logfile=/L/testcrash.log
9+
redirect_stderr=true

conftest/testcrash2.conf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[group:notifycrash]
2+
programs=testcrash2,testcrash3
3+
4+
# test program: crashes every 30 seconds
5+
[program:testcrash2]
6+
command=/R/bin/crashin 30
7+
8+
autostart=true
9+
autorestart=true
10+
11+
stdout_logfile=/L/testcrash2.log
12+
redirect_stderr=true
13+
14+
[program:testcrash3]
15+
command=/R/bin/crashin 33
16+
17+
autostart=true
18+
autorestart=true
19+
20+
stdout_logfile=/L/testcrash3.log
21+
redirect_stderr=true

superlance/crashmail.py

100644100755
Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
3838
-p -- specify a supervisor process_name. Send mail when this process
3939
transitions to the EXITED state unexpectedly. If this process is
40-
part of a group, it can be specified using the
40+
part of a group, it must be specified using the
4141
'process_name:group_name' syntax.
4242
4343
-a -- Send mail when any child of the supervisord transitions
@@ -66,6 +66,7 @@
6666
"""
6767

6868
import os
69+
import re
6970
import sys
7071

7172
from supervisor import childutils
@@ -124,10 +125,25 @@ def runforever(self, test=False):
124125
if self.optionalheader:
125126
subject = self.optionalheader + ':' + subject
126127

127-
self.stderr.write('unexpected exit, mailing\n')
128-
self.stderr.flush()
129128

130-
self.mail(self.email, subject, msg)
129+
ident = pheaders['processname']
130+
if pheaders['groupname'] != ident:
131+
ident = pheaders['groupname'] + ":" + ident
132+
133+
if self.any or \
134+
not self.programs or \
135+
any(prog.match(ident) for prog in self.programs):
136+
137+
self.stderr.write('\nunexpected exit, mailing\n')
138+
self.stderr.flush()
139+
140+
self.mail(self.email, subject, msg)
141+
142+
else:
143+
144+
self.stderr.write('\nignoring %s\n' % subject)
145+
self.stderr.flush()
146+
131147

132148
childutils.listener.ok(self.stdout)
133149
if test:
@@ -140,7 +156,7 @@ def mail(self, email, subject, msg):
140156
body += msg
141157
with os.popen(self.sendmail, 'w') as m:
142158
m.write(body)
143-
self.stderr.write('Mailed:\n\n%s' % body)
159+
self.stderr.write('Mailed:\n\n%s\n' % body)
144160
self.mailed = body
145161

146162

@@ -167,13 +183,19 @@ def main(argv=sys.argv):
167183
email = None
168184
optionalheader = None
169185

186+
progGroupRE = re.compile(r"(\w+):\*")
187+
170188
for option, value in opts:
171189

172190
if option in ('-h', '--help'):
173191
usage()
174192

175193
if option in ('-p', '--program'):
176-
programs.append(value)
194+
pg = progGroupRE.match(value)
195+
if pg:
196+
programs.append(re.compile(pg.group(1)+":.*"))
197+
else:
198+
programs.append(re.compile(re.escape(value)))
177199

178200
if option in ('-a', '--any'):
179201
any = True

0 commit comments

Comments
 (0)