[CalendarServer-changes] [1865] CalDAVTester/trunk

source_changes at macosforge.org source_changes at macosforge.org
Tue Sep 11 09:37:58 PDT 2007


Revision: 1865
          http://trac.macosforge.org/projects/calendarserver/changeset/1865
Author:   cdaboo at apple.com
Date:     2007-09-11 09:37:57 -0700 (Tue, 11 Sep 2007)

Log Message:
-----------
Add option to monitor tool so that it can generate am uptime report for a server based on the monitor logs.

Modified Paths:
--------------
    CalDAVTester/trunk/monitor.py
    CalDAVTester/trunk/scripts/monitoring/monitorinfo.dtd
    CalDAVTester/trunk/scripts/monitoring/monitorinfo.xml
    CalDAVTester/trunk/src/monitorinfo.py
    CalDAVTester/trunk/src/xmlDefs.py

Modified: CalDAVTester/trunk/monitor.py
===================================================================
--- CalDAVTester/trunk/monitor.py	2007-09-11 16:35:34 UTC (rev 1864)
+++ CalDAVTester/trunk/monitor.py	2007-09-11 16:37:57 UTC (rev 1865)
@@ -22,6 +22,7 @@
 #
 
 from getpass import getpass
+import getopt
 import socket
 import datetime
 import signal
@@ -44,8 +45,9 @@
         self.pswd = pswd
         self.minfo = None
 
-        if logname:
-            self.log = open(logname, "a")
+        self.logname = logname
+        if self.logname:
+            self.log = open(self.logname, "a")
         else:
             self.log = None
             
@@ -141,35 +143,129 @@
                     self.doNotification(msg)
                     last_notify = time.time()
 
+    def reportUptime(self, html):
+        
+        # Read in the logfile and count failures.
+        startstops = []
+        failures = 0
+        fd = open(self.logname, "r")
+        for line in fd:
+            if line.find("Starting Monitor") != -1:
+                startstops.append(line)
+            elif line.find("Stopped Monitor") != -1:
+                startstops.append(line)
+            elif line.find("WARNING: request failed") != -1:
+                failures += 1
+        
+        # Failed time = number of failures * monitor period (seconds)
+        downtime = int(failures * self.minfo.period)
+        
+        # Now calculate actual monitor run time
+        elapsed_time = 0
+        start = None
+        for item in startstops:
+            if start is None and item.find("Starting Monitor") != -1:
+                start = self.parse_date(item)
+            elif start is not None and item.find("Stopped Monitor"):
+                end = self.parse_date(item)
+                delta = end - start
+                elapsed_time += delta.days * 24 * 60 * 60 + delta.seconds
+                start = None
+        
+        if start is not None:
+            end = datetime.datetime.now()
+            delta = end - start
+            elapsed_time += delta.days * 24 * 60 * 60 + delta.seconds
+        
+        uptime = elapsed_time - downtime
+
+        if html:
+            print """<html>
+<head><title>Server Status</title></head>
+<body>
+<h2>Server Status: %s</h2>
+<table>
+<tr><td>Uptime</td><td>approx. %d (hours) / %d (days)</td></tr>
+<tr><td>Downtime</td><td>approx. %d (minutes) / %d (hours)</td></tr>
+<tr><td>Percentage</td><td>%.3f%%</td></tr>
+</table>
+</body>
+</html>
+""" % (self.minfo.name, uptime/60/60, uptime/60/60/24, downtime/60, downtime/60/60, ((uptime - downtime) * 100.0)/uptime)
+        else:
+            print """Server Status: %s
+    Uptime:     approx. %d (hours) / %d (days)
+    Downtime:   approx. %d (minutes) / %d (hours)
+    Percentage: %.3f%%
+""" % (self.minfo.name, uptime/60/60, uptime/60/60/24, downtime/60, downtime/60/60, ((uptime - downtime) * 100.0)/uptime)
+
+    def parse_date(self, line):
+        
+        date = line[1:].split(']')[0]
+        return datetime.datetime(*(time.strptime(date, "%Y-%m-%d %H:%M:%S")[0:6]))
+
+def usage():
+    print """Usage: monitor.py [options] [<configfile>] [<logfile>]
+Options:
+    -h       Print this help and exit
+    -u       generate report of server uptime
+    --html   generate report as HTML
+"""
+
 if __name__ == "__main__":
     
     infoname = "scripts/monitoring/monitorinfo.xml"
-    if len(sys.argv) > 1:
-        infoname = sys.argv[1]
+    uptime = False
+    html = False
+
+    options, args = getopt.getopt(sys.argv[1:], "huw", ["html"])
+
+    for option, value in options:
+        if option == "-h":
+            usage()
+            sys.exit(0)
+        elif option == "-u":
+            uptime = True
+        elif option == "--html":
+            html = True
+        else:
+            print "Unrecognized option: %s" % (option,)
+            usage()
+            raise ValueError
+
+    if len(args) > 0:
+        infoname = args[0]
         
-    if len(sys.argv) > 2:
-        logname = sys.argv[2]
+    if len(args) > 1:
+        logname = args[1]
     else:
         logname = None
 
-    user = raw_input("User: ")
-    pswd = getpass("Password: ")
+    if uptime:
+        user = ""
+        pswd = ""
+    else:
+        user = raw_input("User: ")
+        pswd = getpass("Password: ")
     
     m = monitor(infoname, logname, user, pswd)
     m.readXML()
 
-    def signalEnd(sig, frame):
-        m.doEnd()
-        sys.exit()
-
-    signal.signal(signal.SIGINT, signalEnd)
-    socket.setdefaulttimeout(120)    # Two minute timeout
-
-    m.doStart()
-
-    try:
-        m.runLoop()
-    except SystemExit:
-        pass
-    except Exception, e:
-        m.doError(str(e))
+    if uptime:
+        m.reportUptime(html)
+    else:
+        def signalEnd(sig, frame):
+            m.doEnd()
+            sys.exit()
+    
+        signal.signal(signal.SIGINT, signalEnd)
+        socket.setdefaulttimeout(m.minfo.timeout)
+    
+        m.doStart()
+    
+        try:
+            m.runLoop()
+        except SystemExit:
+            pass
+        except Exception, e:
+            m.doError(str(e))

Modified: CalDAVTester/trunk/scripts/monitoring/monitorinfo.dtd
===================================================================
--- CalDAVTester/trunk/scripts/monitoring/monitorinfo.dtd	2007-09-11 16:35:34 UTC (rev 1864)
+++ CalDAVTester/trunk/scripts/monitoring/monitorinfo.dtd	2007-09-11 16:37:57 UTC (rev 1865)
@@ -16,13 +16,16 @@
  DRI: Cyrus Daboo, cdaboo at apple.com
  -->
 
-<!ELEMENT monitorinfo (logging, period, serverinfo, start, testinfo, end, warningtime, notify?) >
+<!ELEMENT monitorinfo (logging, period, timeout, serverinfo, start, testinfo, end, warningtime, notify?) >
+	<!ATTLIST monitorinfo	name CDATA	"">
 
 	<!ELEMENT logging		EMPTY>
 		<!ATTLIST logging	enable (yes|no) "no">
 
 	<!ELEMENT period    	(#PCDATA)>
 
+	<!ELEMENT timeout    	(#PCDATA)>
+
 	<!ELEMENT serverinfo	(#PCDATA)>
 
 	<!ELEMENT start	        (#PCDATA)>

Modified: CalDAVTester/trunk/scripts/monitoring/monitorinfo.xml
===================================================================
--- CalDAVTester/trunk/scripts/monitoring/monitorinfo.xml	2007-09-11 16:35:34 UTC (rev 1864)
+++ CalDAVTester/trunk/scripts/monitoring/monitorinfo.xml	2007-09-11 16:37:57 UTC (rev 1865)
@@ -20,9 +20,10 @@
  DRI: Cyrus Daboo, cdaboo at apple.com
  -->
 
-<monitorinfo>
+<monitorinfo name="test.example.com">
 	<logging enable="no"/>
 	<period>1</period>
+	<timeout>60</timeout>
 	<serverinfo>scripts/server/serverinfo-monitor.xml</serverinfo>
 	<start>monitor/get/get-start.xml</start>
 	<testinfo>monitor/get/get-small.xml</testinfo>

Modified: CalDAVTester/trunk/src/monitorinfo.py
===================================================================
--- CalDAVTester/trunk/src/monitorinfo.py	2007-09-11 16:35:34 UTC (rev 1864)
+++ CalDAVTester/trunk/src/monitorinfo.py	2007-09-11 16:37:57 UTC (rev 1865)
@@ -31,8 +31,10 @@
     Maintains information about the monitoring test scenario.
     """
     __slots__  = [
+        'name',
         'logging',
         'period',
+        'timeout',
         'serverinfo',
         'startscript',
         'testinfo',
@@ -48,8 +50,10 @@
     ]
 
     def __init__( self ):
+        self.name = ""
         self.logging = False
         self.period = 1.0
+        self.timeout = 60
         self.serverinfo = ""
         self.startscript = ""
         self.testinfo = ""
@@ -64,11 +68,15 @@
         self.notify_body = None
 
     def parseXML( self, node ):
+        
+        self.name = getDefaultAttributeValue(node, src.xmlDefs.ATTR_NAME, "")
         for child in node._get_childNodes():
             if child._get_localName() == src.xmlDefs.ELEMENT_LOGGING:
                 self.logging = getYesNoAttributeValue(child, src.xmlDefs.ATTR_ENABLE)
             elif child._get_localName() == src.xmlDefs.ELEMENT_PERIOD:
                 self.period = float(child.firstChild.data)
+            elif child._get_localName() == src.xmlDefs.ELEMENT_TIMEOUT:
+                self.timeout = int(child.firstChild.data)
             elif child._get_localName() == src.xmlDefs.ELEMENT_SERVERINFO:
                 self.serverinfo = child.firstChild.data
             elif child._get_localName() == src.xmlDefs.ELEMENT_START:

Modified: CalDAVTester/trunk/src/xmlDefs.py
===================================================================
--- CalDAVTester/trunk/src/xmlDefs.py	2007-09-11 16:35:34 UTC (rev 1864)
+++ CalDAVTester/trunk/src/xmlDefs.py	2007-09-11 16:37:57 UTC (rev 1865)
@@ -65,6 +65,7 @@
 ELEMENT_TESTINFO = "testinfo"
 ELEMENT_TESTS = "tests"
 ELEMENT_TESTSUITE = "test-suite"
+ELEMENT_TIMEOUT = "timeout"
 ELEMENT_THREADS = "threads"
 ELEMENT_VALUE = "value"
 ELEMENT_VARIABLE = "variable"

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070911/feb12fbc/attachment.html


More information about the calendarserver-changes mailing list