~launchpad-pqm/launchpad/devel

10637.3.1 by Guilherme Salgado
Use the default python version instead of a hard-coded version
1
#!/usr/bin/python -S
8687.15.22 by Karl Fogel
Add the copyright header block to the remaining .py files.
2
#
3
# Copyright 2009 Canonical Ltd.  This software is licensed under the
4
# GNU Affero General Public License version 3 (see the file LICENSE).
4417.4.1 by Tom Haddon
First draft of script monitoring
5
6
"""Monitor scripts."""
7
8
__metaclass__ = type
4417.4.9 by Tom Haddon
Checking command line options
9
__all__ = ['check_script']
4417.4.1 by Tom Haddon
First draft of script monitoring
10
11
import _pythonpath
12
4417.4.11 by Tom Haddon
Use MAX(date_completed) as cleaner that ORDER BY and LIMIT, clearer error messages and formatting
13
from datetime import datetime, timedelta
4417.4.14 by Tom Haddon
Using own email to send out notifications
14
from email.MIMEText import MIMEText
4417.4.1 by Tom Haddon
First draft of script monitoring
15
from optparse import OptionParser
16
from time import strftime
4417.4.14 by Tom Haddon
Using own email to send out notifications
17
import smtplib
4417.4.1 by Tom Haddon
First draft of script monitoring
18
import sys
19
20
from canonical.database.sqlbase import connect
21
from canonical.launchpad.scripts import db_options, logger_options, logger
4417.4.12 by Tom Haddon
Basic tests (not working) for script monitoring
22
from canonical.launchpad.scripts.scriptmonitor import check_script
23
4417.4.1 by Tom Haddon
First draft of script monitoring
24
25
def main():
10303.1.1 by Gary Poster
use newest version of zc.buildout
26
    # XXX: Tom Haddon 2007-07-12
4417.4.16 by Tom Haddon
Using sqlvalues, commenting on untested parts, and cleaning up
27
    # There's a lot of untested stuff here: parsing options and sending
28
    # emails - this should be moved into a testable location.
4417.4.22 by Tom Haddon
Clean up code after comments from Andrew Bennets
29
    # Also duplicated code in scripts/script-monitor-nagios.py
4417.4.1 by Tom Haddon
First draft of script monitoring
30
    parser = OptionParser(
4417.4.9 by Tom Haddon
Checking command line options
31
            '%prog [options] (minutes) (host:scriptname) [host:scriptname]'
4417.4.1 by Tom Haddon
First draft of script monitoring
32
            )
33
    db_options(parser)
34
    logger_options(parser)
35
36
    (options, args) = parser.parse_args()
37
4417.4.9 by Tom Haddon
Checking command line options
38
    if len(args) < 2:
39
        parser.error("Must specify at time in minutes and "
40
            "at least one host and script")
4417.4.1 by Tom Haddon
First draft of script monitoring
41
4417.4.6 by Tom Haddon
Cleaning up formatting
42
    # First argument is the number of minutes into the past
43
    # we want to look for the scripts on the specified hosts
4417.4.9 by Tom Haddon
Checking command line options
44
    try:
45
        minutes_ago, args = int(args[0]), args[1:]
46
        start_date = datetime.now() - timedelta(minutes=minutes_ago)
47
48
        completed_from = strftime("%Y-%m-%d %H:%M:%S", start_date.timetuple())
49
        completed_to = strftime("%Y-%m-%d %H:%M:%S", datetime.now().timetuple())
50
4417.4.16 by Tom Haddon
Using sqlvalues, commenting on untested parts, and cleaning up
51
        hosts_scripts = []
4417.4.9 by Tom Haddon
Checking command line options
52
        for arg in args:
4417.4.16 by Tom Haddon
Using sqlvalues, commenting on untested parts, and cleaning up
53
            try:
54
                hostname, scriptname = arg.split(':')
55
            except TypeError:
56
                parser.error(
57
                    "%r is not in the format 'host:scriptname'" % (arg,))
58
            hosts_scripts.append((hostname, scriptname))
59
    except ValueError:
4417.4.11 by Tom Haddon
Use MAX(date_completed) as cleaner that ORDER BY and LIMIT, clearer error messages and formatting
60
        parser.error("Must specify time in minutes and "
4417.4.9 by Tom Haddon
Checking command line options
61
            "at least one host and script")
4417.4.1 by Tom Haddon
First draft of script monitoring
62
63
    log = logger(options)
64
65
    try:
66
        log.debug("Connecting to database")
13879.1.3 by William Grant
Drop now-obsolete connect(user) args.
67
        con = connect()
4417.4.16 by Tom Haddon
Using sqlvalues, commenting on untested parts, and cleaning up
68
        error_found = False
4417.4.14 by Tom Haddon
Using own email to send out notifications
69
        msg, subj = [], []
4417.4.16 by Tom Haddon
Using sqlvalues, commenting on untested parts, and cleaning up
70
        for hostname, scriptname in hosts_scripts:
10303.1.1 by Gary Poster
use newest version of zc.buildout
71
            failure_msg = check_script(con, log, hostname,
4417.4.16 by Tom Haddon
Using sqlvalues, commenting on untested parts, and cleaning up
72
                scriptname, completed_from, completed_to)
73
            if failure_msg is not None:
4417.4.14 by Tom Haddon
Using own email to send out notifications
74
                msg.append(failure_msg)
4417.4.16 by Tom Haddon
Using sqlvalues, commenting on untested parts, and cleaning up
75
                subj.append("%s:%s" % (hostname, scriptname))
4417.4.11 by Tom Haddon
Use MAX(date_completed) as cleaner that ORDER BY and LIMIT, clearer error messages and formatting
76
                error_found = 2
4417.4.14 by Tom Haddon
Using own email to send out notifications
77
        if error_found:
78
            # Construct our email
79
            msg = MIMEText('\n'.join(msg))
80
            msg['Subject'] = "Scripts failed to run: %s" % ", ".join(subj)
5046.1.1 by Tom Haddon
Better from address for script monitor
81
            msg['From'] = 'script-failures@launchpad.net'
82
            msg['Reply-To'] = 'launchpad@lists.canonical.com'
4417.4.14 by Tom Haddon
Using own email to send out notifications
83
            msg['To'] = 'launchpad@lists.canonical.com'
10303.1.1 by Gary Poster
use newest version of zc.buildout
84
4417.4.14 by Tom Haddon
Using own email to send out notifications
85
            # Send out the email
86
            smtp = smtplib.SMTP()
87
            smtp.connect()
5046.1.1 by Tom Haddon
Better from address for script monitor
88
            smtp.sendmail('script-failures@launchpad.net', ['launchpad@lists.canonical.com'], msg.as_string())
4417.4.14 by Tom Haddon
Using own email to send out notifications
89
            smtp.close()
4417.4.16 by Tom Haddon
Using sqlvalues, commenting on untested parts, and cleaning up
90
            return 2
4417.4.1 by Tom Haddon
First draft of script monitoring
91
    except:
92
        log.exception("Unhandled exception")
93
        return 1
94
95
if __name__ == '__main__':
96
    sys.exit(main())