[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'> </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(' %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> </td><td> </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