[CalendarServer-changes] [1602] CalendarServer/trunk/twistedcaldav/admin

source_changes at macosforge.org source_changes at macosforge.org
Sat Jun 9 08:35:52 PDT 2007


Revision: 1602
          http://trac.macosforge.org/projects/calendarserver/changeset/1602
Author:   cdaboo at apple.com
Date:     2007-06-09 08:35:51 -0700 (Sat, 09 Jun 2007)

Log Message:
-----------
Add time-of-day breakdown by method. Add HTML output option.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/admin/formatters.py
    CalendarServer/trunk/twistedcaldav/admin/logs.py

Modified: CalendarServer/trunk/twistedcaldav/admin/formatters.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/admin/formatters.py	2007-06-08 18:31:09 UTC (rev 1601)
+++ CalendarServer/trunk/twistedcaldav/admin/formatters.py	2007-06-09 15:35:51 UTC (rev 1602)
@@ -122,16 +122,17 @@
             values = [types[i](value) for i, value in enumerate(values)]
             self.writeLine(values)
 
-    def writeFrequencies(self, frequencies):
+    def writeFrequencies(self, frequencies, max_count=None):
         
         width = len(frequencies)
         plot = [[" "] * width for ignore in range(20)]
         plot.append(["|---"] * 24)
         plot.append(["%02d  " % d for d in range(24)])
         
-        max_count = 0
-        for freq in frequencies:
-            max_count = max(freq, max_count)
+        if max_count is None:
+            max_count = 0
+            for freq in frequencies:
+                max_count = max(freq, max_count)
             
         for column, freq in enumerate(frequencies):
             if freq == 0:
@@ -143,6 +144,8 @@
         
         self.write("\n".join(["".join(p) for p in plot]))
         self.write("\n")
+        
+        return max_count
 
     def writeReport(self, report, name, fields, headings):
         if self.options.has_key('fields'):
@@ -249,8 +252,13 @@
         self.write('\n')
 
         self.write('  # Requests by time of day:\n')
-        self.writeFrequencies(report['data']['timeOfDayStats'])
+        max_count = self.writeFrequencies(report['data']['timeOfDayStats'])
         self.write('\n')
+        
+        for request, freqs in report['data']['requestByTimeOfDayStats'].iteritems():
+            self.write('  # %s requests by time of day:\n' % (request,))
+            self.writeFrequencies(freqs)
+            self.write('\n')
 
         self.write('  User Agents:\n')
 
@@ -328,3 +336,243 @@
     report_logs = report_stats
 
 registerFormatter(PlistFormatter)
+
+class HTMLFormatter(BaseFormatter):
+    name = "html"
+
+    def writeLine(self, fields, spacing=None):
+
+        if not spacing:
+            spacing = self.options.get('spacing', 16)
+
+        for f in fields:
+            if isinstance(f, float):
+                p = ("% " + str(spacing - 1) + ".2f") % (f,)
+            elif isinstance(f, int) or isinstance(f, long):
+                p = ("% " + str(spacing - 1) + "d") % (f,)
+            else:
+                p = str(f)
+            self.write(p)
+            self.write(' '*(int(spacing) - len(p)))
+
+        self.write('\n')
+
+    def writeTable(self, report, fields, headings):
+        if self.options.has_key('fields'):
+            fields = self.options.get('fields', '').split(',')
+
+        self.write("<table>\n")
+
+        self.write("  <tr>\n")
+        for f in fields:
+            self.write("    <td>%s</td>\n" % headings[f])
+        self.write("  <tr>\n")
+
+        for record in report['records']:
+            self.writeTableRow((record[f] for f in fields))
+
+        self.write("  </tr>\n")
+        self.write("</table>\n")
+
+    def writeTableRow(self, fields):
+
+        self.write("  <tr>\n")
+
+        for f in fields:
+            align = ""
+            if isinstance(f, float):
+                p = ("%.2f") % (f,)
+                align = " align='right'"
+            elif isinstance(f, int) or isinstance(f, long):
+                p = ("%d") % (f,)
+                align = " align='right'"
+            else:
+                p = str(f)
+            self.write("    <td%s>%s</td>\n" % (align, p,))
+
+        self.write("  </tr>\n")
+
+    def writeMap(self, reportmap, fields, types, headings):
+
+        self.write("<table border='1'>\n")
+
+        self.write("  <tr>\n")
+        for f in fields:
+            self.write("    <td>%s</td>\n" % headings[f])
+        self.write("  <tr>\n")
+
+        for key, value in reportmap.iteritems():
+            values = (key,)
+            values += tuple(value[f] for f in fields[1:])
+            values = [types[i](value) for i, value in enumerate(values)]
+            self.writeTableRow(values)
+
+        self.write("  </tr>\n")
+        self.write("</table>\n")
+
+    def writeFrequencies(self, frequencies, max_count = None):
+        
+        if max_count is None:
+            max_count = 0
+            for freq in frequencies:
+                max_count = max(freq, max_count)
+            
+        self.write("<table>\n")
+
+        for row in range(20):
+            self.write("  <tr>\n")
+            for freq in frequencies:
+                scaled = (20 * freq) / max_count
+                if 19 - row <= scaled:
+                    self.write("    <td><font size='1'>*</font></td>\n")
+                else:
+                    self.write("    <td><font size='1'>&nbsp;</font></td>\n")
+            self.write("  </tr>\n")
+
+        self.write("  <tr>\n")
+        for i in range(len(frequencies) / 4):
+            self.write("    <td align='center'><font size='1'>|</font></td>\n")
+            self.write("    <td align='center'><font size='1'>-</font></td>\n")
+            self.write("    <td align='center'><font size='1'>-</font></td>\n")
+            self.write("    <td align='center'><font size='1'>-</font></td>\n")
+        self.write("  </tr>\n")
+        self.write("  <tr>\n")
+        for i in range(len(frequencies) / 4):
+            self.write("    <td colspan='4'><font size='1'>%s</font></td>\n" % (i,))
+        self.write("  </tr>\n")
+        self.write("</table>\n")
+        
+        return max_count
+
+    def writeReport(self, report, name, fields, headings):
+        if self.options.has_key('fields'):
+            fields = self.options.get('fields', '').split(',')
+        
+        if name:
+            self.write('<h3>%s:</h3>\n' % (name,))
+
+        for f in fields:
+            self.write('&nbsp;&nbsp;%s: %s<br>\n' % (headings[f], report['data'][f]))
+
+    def report_principals(self, report):
+        fields = ('principalName', 'calendarCount', 'eventCount', 'todoCount',
+                  'quotaRoot', 'quotaUsed', 'quotaAvail')
+
+        headings = {
+            'principalName': 'Name',
+            'calendarCount': '# Calendars',
+            'eventCount': '# Events',
+            'todoCount': '# Todos',
+            'quotaRoot': 'Quota',
+            'quotaUsed': 'Used',
+            'quotaAvail': 'Available',
+            'disabled': 'Disaabled',
+            'quotaFree': 'Free %',
+            'calendarHome': 'Home',
+            }
+
+        self.writeTable(report, fields, headings)
+
+    report_users = report_groups = report_resources = report_locations = report_principals
+
+    def report_stats(self, report):
+        fields = ('accountCount', 'groupCount', 'resourceCount', 'locationCount',
+                  'calendarCount', 'eventCount', 
+                  'todoCount', 'diskUsage')
+
+        headings = {
+            'accountCount':  '# Accounts ',
+            'groupCount':    '# Groups   ',
+            'resourceCount': '# Resources',
+            'locationCount': '# Locations',
+            'calendarCount': '# Calendars',
+            'eventCount':    '# Events   ',
+            'todoCount':     '# Todos    ',
+            'diskUsage':     'Disk Usage ',
+            }
+
+        self.writeReport(report, 'Statistics', fields, headings)
+
+    def report_logs(self, report):
+        
+        self.write('<html>\n<body>\n')
+
+        self.write('<h2>Log Statistics:</h2><br>\n<br>\n')
+
+        self.write("<table>\n")
+        self.write('<tr><td>Start Date:</td><td>%s</td></tr>\n' % report['data']['dateRange'][0])
+        self.write('<tr><td>End Date:</td><td>%s</td></tr>\n' % report['data']['dateRange'][1])
+        self.write('<tr><td>&nbsp;</td><td>&nbsp;</td></tr>\n')
+        self.write('<tr><td>Bytes Out:</td><td>%s (%.2f GB)</td></tr>\n' % (report['data']['bytesOut'], report['data']['bytesOut'] / (1024.0 * 1024 * 1024)))
+        self.write("</table>\n")
+
+        self.write('<h3># Requests:</h3>\n')
+
+        title_spacing = self.options.get('spacing', 16) - 1
+
+        fields = (
+            'method',
+            'num',
+            'numOK',
+            'numBAD',
+            'numISE',
+            'numOther',
+            'minbytes',
+            'avbytes',
+            'maxbytes',
+            'mintime',
+            'avtime',
+            'maxtime',
+        )
+        types = (
+            str,
+            long,
+            long,
+            long,
+            long,
+            long,
+            long,
+            long,
+            long,
+            float,
+            float,
+            float,
+        )
+        headings = {
+            'method':        'Method',
+            'num':           '# Requests'.rjust(title_spacing),
+            'numOK':         '# OK'.rjust(title_spacing),
+            'numBAD':        '# BAD'.rjust(title_spacing),
+            'numISE':        '# Failed'.rjust(title_spacing),
+            'numOther':      '# Other'.rjust(title_spacing),
+            'minbytes':      'Min. bytes'.rjust(title_spacing),
+            'avbytes':       'Av. bytes'.rjust(title_spacing),
+            'maxbytes':      'Max. bytes'.rjust(title_spacing),
+            'mintime':       'Min. time (ms)'.rjust(title_spacing),
+            'avtime':        'Av. time (ms)'.rjust(title_spacing),
+            'maxtime':       'Max. time (ms)'.rjust(title_spacing),
+        }
+        self.writeMap(report['data']['requestStats'], fields, types, headings)
+        self.write('<br>\n')
+
+        self.write('<h3># Requests by time of day:</h3>\n')
+        max_count = self.writeFrequencies(report['data']['timeOfDayStats'])
+        self.write('<br>\n')
+
+        
+        for request, freqs in report['data']['requestByTimeOfDayStats'].iteritems():
+            self.write('<h3># %s requests by time of day:</h3>\n' % (request,))
+            self.writeFrequencies(freqs)
+            self.write('<br>\n')
+
+        self.write('<h3>User Agents:</h3>\n')
+
+        self.write("<table border='1'>")
+        self.write('  <tr><td>User Agent</td><td># Requests</td></tr>\n')
+        for ua, count in report['data']['userAgents'].iteritems():
+            self.write('  <tr><td>%s:</td><td align=\'right\'>%s</td></tr>\n' % (ua, count))
+        self.write('</table>\n')
+        
+        self.write('</body>\n</html>\n')
+
+registerFormatter(HTMLFormatter)

Modified: CalendarServer/trunk/twistedcaldav/admin/logs.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/admin/logs.py	2007-06-08 18:31:09 UTC (rev 1601)
+++ CalendarServer/trunk/twistedcaldav/admin/logs.py	2007-06-09 15:35:51 UTC (rev 1602)
@@ -30,16 +30,16 @@
 
 from twistedcaldav.admin import util
 
-PLIST_VERSION = 2
+PLIST_VERSION = 3
 
 statsTemplate = plistlib.Dict(
     version=PLIST_VERSION,
     bytesOut="0",
     startDate="",
     endDate="",
-    requestStats=plistlib.Dict(
-        ),
+    requestStats=plistlib.Dict(),
     timeOfDayStats=[0] * 96,
+    requestByTimeOfDayStats=plistlib.Dict(),
     invitations=plistlib.Dict(
         day=0, 
         week=0, 
@@ -132,10 +132,16 @@
         hour, minute = time.split(":")
         bucket = int(hour) * 4 + divmod(int(minute), 15)[0]
         self._data.timeOfDayStats[bucket] = self._data.timeOfDayStats[bucket] + 1
+        if request not in self._data.requestByTimeOfDayStats:
+            self._data.requestByTimeOfDayStats[request] = [0] * 96
+        self._data.requestByTimeOfDayStats[request][bucket] = self._data.requestByTimeOfDayStats[request][bucket] + 1
     
     def getTimeOfDayStats(self):
         return self._data.timeOfDayStats
 
+    def getRequestByTimeOfDayStats(self):
+        return self._data.requestByTimeOfDayStats
+
     def addUserAgent(self, useragent):
         if useragent in self._data.userAgents:
             self._data.userAgents[useragent] += 1
@@ -245,6 +251,7 @@
                                                       self.stats.getBytes()),
                     'requestStats': self.stats.getRequestStats(),
                     'timeOfDayStats': self.stats.getTimeOfDayStats(),
+                    'requestByTimeOfDayStats': self.stats.getRequestByTimeOfDayStats(),
                     'userAgents': self.stats.getUserAgents(),
                     }
                 }

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


More information about the calendarserver-changes mailing list