[CalendarServer-changes] [10159] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Wed Dec 12 09:18:55 PST 2012
Revision: 10159
http://trac.calendarserver.org//changeset/10159
Author: cdaboo at apple.com
Date: 2012-12-12 09:18:55 -0800 (Wed, 12 Dec 2012)
Log Message:
-----------
More stats socket enhancements.
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/accesslog.py
CalendarServer/trunk/contrib/tools/readStats.py
Added Paths:
-----------
CalendarServer/trunk/calendarserver/logAnalysis.py
Removed Paths:
-------------
CalendarServer/trunk/calendarserver/methodDescriptor.py
Modified: CalendarServer/trunk/calendarserver/accesslog.py
===================================================================
--- CalendarServer/trunk/calendarserver/accesslog.py 2012-12-12 16:37:28 UTC (rev 10158)
+++ CalendarServer/trunk/calendarserver/accesslog.py 2012-12-12 17:18:55 UTC (rev 10159)
@@ -35,7 +35,8 @@
psutil = None
import time
-from calendarserver.methodDescriptor import getAdjustedMethodName
+from calendarserver.logAnalysis import getAdjustedMethodName, \
+ getAdjustedClientName
from twext.python.log import Logger
from twext.web2 import iweb
@@ -468,27 +469,34 @@
}
return {
- "requests" : 0,
- "method" : collections.defaultdict(int),
- "uid" : collections.defaultdict(int),
- "500" : 0,
- "t" : 0.0,
- "t-resp-wr": 0.0,
- "slots" : 0,
- "T" : initTimeHistogram(),
- "T-RESP-WR": initTimeHistogram(),
- "T-MAX" : 0.0,
- "cpu" : self.systemStats.items["cpu use"],
+ "requests" : 0,
+ "method" : collections.defaultdict(int),
+ "method-t" : collections.defaultdict(float),
+ "uid" : collections.defaultdict(int),
+ "user-agent" : collections.defaultdict(int),
+ "500" : 0,
+ "t" : 0.0,
+ "t-resp-wr" : 0.0,
+ "slots" : 0,
+ "T" : initTimeHistogram(),
+ "T-RESP-WR" : initTimeHistogram(),
+ "T-MAX" : 0.0,
+ "cpu" : self.systemStats.items["cpu use"],
}
def updateStats(self, current, stats):
# Gather specific information and aggregate into our persistent stats
+ adjustedMethod = getAdjustedMethodName(stats)
+ adjustedClient = getAdjustedClientName(stats)
+
if current["requests"] == 0:
current["cpu"] = 0.0
current["requests"] += 1
- current["method"][getAdjustedMethodName(stats["method"], stats["uri"], stats)] += 1
+ current["method"][adjustedMethod] += 1
+ current["method-t"][adjustedMethod] += stats.get("t", 0.0)
current["uid"][stats["uid"]] += 1
+ current["user-agent"][adjustedClient] += 1
if stats["statusCode"] >= 500:
current["500"] += 1
current["t"] += stats.get("t", 0.0)
@@ -532,8 +540,12 @@
current["requests"] += stats["requests"]
for method in stats["method"].keys():
current["method"][method] += stats["method"][method]
+ for method in stats["method-t"].keys():
+ current["method-t"][method] += stats["method-t"][method]
for uid in stats["uid"].keys():
current["uid"][uid] += stats["uid"][uid]
+ for ua in stats["user-agent"].keys():
+ current["user-agent"][ua] += stats["user-agent"][ua]
current["500"] += stats["500"]
current["t"] += stats["t"]
current["t-resp-wr"] += stats["t-resp-wr"]
Copied: CalendarServer/trunk/calendarserver/logAnalysis.py (from rev 10157, CalendarServer/trunk/calendarserver/methodDescriptor.py)
===================================================================
--- CalendarServer/trunk/calendarserver/logAnalysis.py (rev 0)
+++ CalendarServer/trunk/calendarserver/logAnalysis.py 2012-12-12 17:18:55 UTC (rev 10159)
@@ -0,0 +1,373 @@
+##
+# Copyright (c) 2012 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+# Adjust method names
+
+# PROPFINDs
+METHOD_PROPFIND_CALENDAR_HOME = "PROPFIND Calendar Home"
+METHOD_PROPFIND_CACHED_CALENDAR_HOME = "PROPFIND cached Calendar Home"
+METHOD_PROPFIND_CALENDAR = "PROPFIND Calendar"
+METHOD_PROPFIND_INBOX = "PROPFIND Inbox"
+METHOD_PROPFIND_ADDRESSBOOK_HOME = "PROPFIND Adbk Home"
+METHOD_PROPFIND_CACHED_ADDRESSBOOK_HOME = "PROPFIND cached Adbk Home"
+METHOD_PROPFIND_ADDRESSBOOK = "PROPFIND Adbk"
+METHOD_PROPFIND_DIRECTORY = "PROPFIND Directory"
+METHOD_PROPFIND_PRINCIPALS = "PROPFIND Principals"
+METHOD_PROPFIND_CACHED_PRINCIPALS = "PROPFIND cached Principals"
+
+# PROPPATCHs
+METHOD_PROPPATCH_CALENDAR = "PROPPATCH Calendar"
+METHOD_PROPPATCH_ADDRESSBOOK = "PROPPATCH Adbk Home"
+
+# REPORTs
+METHOD_REPORT_CALENDAR_MULTIGET = "REPORT cal-multi"
+METHOD_REPORT_CALENDAR_QUERY = "REPORT cal-query"
+METHOD_REPORT_CALENDAR_FREEBUSY = "REPORT freebusy"
+METHOD_REPORT_CALENDAR_SYNC = "REPORT cal-sync"
+METHOD_REPORT_ADDRESSBOOK_MULTIGET = "REPORT adbk-multi"
+METHOD_REPORT_ADDRESSBOOK_QUERY = "REPORT adbk-query"
+METHOD_REPORT_DIRECTORY_QUERY = "REPORT dir-query"
+METHOD_REPORT_ADDRESSBOOK_SYNC = "REPORT adbk-sync"
+METHOD_REPORT_P_SEARCH_P_SET = "REPORT p-set"
+METHOD_REPORT_P_P_SEARCH = "REPORT p-search"
+METHOD_REPORT_EXPAND_P = "REPORT expand"
+
+# POSTs
+METHOD_POST_CALENDAR_HOME = "POST Calendar Home"
+METHOD_POST_CALENDAR = "POST Calendar"
+METHOD_POST_CALENDAR_OBJECT = "POST Calendar Object"
+METHOD_POST_ADDRESSBOOK_HOME = "POST Adbk Home"
+METHOD_POST_ADDRESSBOOK = "POST Adbk"
+METHOD_POST_ISCHEDULE_FREEBUSY = "POST Freebusy iSchedule"
+METHOD_POST_ISCHEDULE = "POST iSchedule"
+METHOD_POST_TIMEZONES = "POST Timezones"
+METHOD_POST_FREEBUSY = "POST Freebusy"
+METHOD_POST_ORGANIZER = "POST Organizer"
+METHOD_POST_ATTENDEE = "POST Attendee"
+METHOD_POST_OUTBOX = "POST Outbox"
+METHOD_POST_APNS = "POST apns"
+
+# PUTs
+METHOD_PUT_ICS = "PUT ics"
+METHOD_PUT_ORGANIZER = "PUT Organizer"
+METHOD_PUT_ATTENDEE = "PUT Attendee"
+METHOD_PUT_DROPBOX = "PUT dropbox"
+METHOD_PUT_VCF = "PUT VCF"
+
+# GETs
+METHOD_GET_CALENDAR_HOME = "GET Calendar Home"
+METHOD_GET_CALENDAR = "GET Calendar"
+METHOD_GET_ICS = "GET ics"
+METHOD_GET_INBOX_ICS = "GET inbox ics"
+METHOD_GET_DROPBOX = "GET dropbox"
+METHOD_GET_ADDRESSBOOK_HOME = "GET Adbk Home"
+METHOD_GET_ADDRESSBOOK = "GET Adbk"
+METHOD_GET_VCF = "GET VCF"
+METHOD_GET_TIMEZONES = "GET Timezones"
+
+# DELETEs
+METHOD_DELETE_CALENDAR_HOME = "DELETE Calendar Home"
+METHOD_DELETE_CALENDAR = "DELETE Calendar"
+METHOD_DELETE_ICS = "DELETE ics"
+METHOD_DELETE_INBOX_ICS = "DELETE inbox ics"
+METHOD_DELETE_DROPBOX = "DELETE dropbox"
+METHOD_DELETE_ADDRESSBOOK_HOME = "DELETE Adbk Home"
+METHOD_DELETE_ADDRESSBOOK = "DELETE Adbk"
+METHOD_DELETE_VCF = "DELETE vcf"
+
+
+def getAdjustedMethodName(stats):
+
+ method = stats["method"]
+ uribits = stats["uri"].rstrip("/").split('/')[1:]
+ if len(uribits) == 0:
+ uribits = [stats["uri"]]
+
+ calendar_specials = ("attachments", "dropbox", "notification", "freebusy", "outbox",)
+ adbk_specials = ("notification",)
+
+ def _PROPFIND():
+ cached = "cached" in stats
+
+ if uribits[0] == "calendars":
+
+ if len(uribits) == 3:
+ return METHOD_PROPFIND_CACHED_CALENDAR_HOME if cached else METHOD_PROPFIND_CALENDAR_HOME
+ elif len(uribits) > 3:
+ if uribits[3] in calendar_specials:
+ return "PROPFIND %s" % (uribits[3],)
+ elif len(uribits) == 4:
+ if uribits[3] == "inbox":
+ return METHOD_PROPFIND_INBOX
+ else:
+ return METHOD_PROPFIND_CALENDAR
+
+ elif uribits[0] == "addressbooks":
+
+ if len(uribits) == 3:
+ return METHOD_PROPFIND_CACHED_ADDRESSBOOK_HOME if cached else METHOD_PROPFIND_ADDRESSBOOK_HOME
+ elif len(uribits) > 3:
+ if uribits[3] in adbk_specials:
+ return "PROPFIND %s" % (uribits[3],)
+ elif len(uribits) == 4:
+ return METHOD_PROPFIND_ADDRESSBOOK
+
+ elif uribits[0] == "directory":
+ return METHOD_PROPFIND_DIRECTORY
+
+ elif uribits[0] == "principals":
+ return METHOD_PROPFIND_CACHED_PRINCIPALS if cached else METHOD_PROPFIND_PRINCIPALS
+
+ return method
+
+
+ def _REPORT():
+
+ if "(" in method:
+ report_type = method.split("}" if "}" in method else ":")[1][:-1]
+ if report_type == "addressbook-query":
+ if uribits[0] == "directory":
+ report_type = "directory-query"
+ if report_type == "sync-collection":
+ if uribits[0] == "calendars":
+ report_type = "cal-sync"
+ elif uribits[0] == "addressbooks":
+ report_type = "adbk-sync"
+ mappedNames = {
+ "calendar-multiget" : METHOD_REPORT_CALENDAR_MULTIGET,
+ "calendar-query" : METHOD_REPORT_CALENDAR_QUERY,
+ "free-busy-query" : METHOD_REPORT_CALENDAR_FREEBUSY,
+ "cal-sync" : METHOD_REPORT_CALENDAR_SYNC,
+ "addressbook-multiget" : METHOD_REPORT_ADDRESSBOOK_MULTIGET,
+ "addressbook-query" : METHOD_REPORT_ADDRESSBOOK_QUERY,
+ "directory-query" : METHOD_REPORT_DIRECTORY_QUERY,
+ "adbk-sync" : METHOD_REPORT_ADDRESSBOOK_SYNC,
+ "principal-search-property-set" : METHOD_REPORT_P_SEARCH_P_SET,
+ "principal-property-search" : METHOD_REPORT_P_P_SEARCH,
+ "expand-property" : METHOD_REPORT_EXPAND_P,
+ }
+ return mappedNames.get(report_type, "REPORT %s" % (report_type,))
+
+ return method
+
+
+ def _PROPPATCH():
+
+ if uribits[0] == "calendars":
+ return METHOD_PROPPATCH_CALENDAR
+ elif uribits[0] == "addressbooks":
+ return METHOD_PROPPATCH_ADDRESSBOOK
+
+ return method
+
+
+ def _POST():
+
+ if uribits[0] == "calendars":
+
+ if len(uribits) == 3:
+ return METHOD_POST_CALENDAR_HOME
+ elif len(uribits) == 4:
+ if uribits[3] == "outbox":
+ if "recipients" in stats:
+ return METHOD_POST_FREEBUSY
+ elif "freebusy" in stats:
+ return METHOD_POST_FREEBUSY
+ elif "itip.request" in stats or "itip.cancel" in stats:
+ return METHOD_POST_ORGANIZER
+ elif "itip.reply" in stats:
+ return METHOD_POST_ATTENDEE
+ else:
+ return METHOD_POST_OUTBOX
+ elif uribits[3] in calendar_specials:
+ pass
+ else:
+ return METHOD_POST_CALENDAR
+ elif len(uribits) == 5:
+ return METHOD_POST_CALENDAR_OBJECT
+
+ elif uribits[0] == "addressbooks":
+
+ if len(uribits) == 3:
+ return METHOD_POST_ADDRESSBOOK_HOME
+ elif len(uribits) == 4:
+ if uribits[3] in adbk_specials:
+ pass
+ else:
+ return METHOD_POST_ADDRESSBOOK
+
+ elif uribits[0] == "ischedule":
+ if "fb-cached" in stats or "fb-uncached" in stats or "freebusy" in stats:
+ return METHOD_POST_ISCHEDULE_FREEBUSY
+ else:
+ return METHOD_POST_ISCHEDULE
+
+ elif uribits[0].startswith("timezones"):
+ return METHOD_POST_TIMEZONES
+
+ elif uribits[0].startswith("apns"):
+ return METHOD_POST_APNS
+
+ return method
+
+
+ def _PUT():
+
+ if uribits[0] == "calendars":
+ if len(uribits) > 3:
+ if uribits[3] in calendar_specials:
+ return "PUT %s" % (uribits[3],)
+ elif len(uribits) == 4:
+ pass
+ else:
+ if "itip.requests" in stats:
+ return METHOD_PUT_ORGANIZER
+ elif "itip.reply" in stats:
+ return METHOD_PUT_ATTENDEE
+ else:
+ return METHOD_PUT_ICS
+
+ elif uribits[0] == "addressbooks":
+ if len(uribits) > 3:
+ if uribits[3] in adbk_specials:
+ return "PUT %s" % (uribits[3],)
+ elif len(uribits) == 4:
+ pass
+ else:
+ return METHOD_PUT_VCF
+
+ return method
+
+
+ def _GET():
+
+ if uribits[0] == "calendars":
+
+ if len(uribits) == 3:
+ return METHOD_GET_CALENDAR_HOME
+ elif len(uribits) > 3:
+ if uribits[3] in calendar_specials:
+ return "GET %s" % (uribits[3],)
+ elif len(uribits) == 4:
+ return METHOD_GET_CALENDAR
+ elif uribits[3] == "inbox":
+ return METHOD_GET_INBOX_ICS
+ else:
+ return METHOD_GET_ICS
+
+ elif uribits[0] == "addressbooks":
+
+ if len(uribits) == 3:
+ return METHOD_GET_ADDRESSBOOK_HOME
+ elif len(uribits) > 3:
+ if uribits[3] in adbk_specials:
+ return "GET %s" % (uribits[3],)
+ elif len(uribits) == 4:
+ return METHOD_GET_ADDRESSBOOK
+ else:
+ return METHOD_GET_VCF
+
+ elif uribits[0].startswith("timezones"):
+ return METHOD_GET_TIMEZONES
+
+ return method
+
+
+ def _DELETE():
+
+ if uribits[0] == "calendars":
+
+ if len(uribits) == 3:
+ return METHOD_DELETE_CALENDAR_HOME
+ elif len(uribits) > 3:
+ if uribits[3] in calendar_specials:
+ return "DELETE %s" % (uribits[3],)
+ elif len(uribits) == 4:
+ return METHOD_DELETE_CALENDAR
+ elif uribits[3] == "inbox":
+ return METHOD_DELETE_INBOX_ICS
+ else:
+ return METHOD_DELETE_ICS
+
+ elif uribits[0] == "addressbooks":
+
+ if len(uribits) == 3:
+ return METHOD_DELETE_ADDRESSBOOK_HOME
+ elif len(uribits) > 3:
+ if uribits[3] in adbk_specials:
+ return "DELETE %s" % (uribits[3],)
+ elif len(uribits) == 4:
+ return METHOD_DELETE_ADDRESSBOOK
+ else:
+ return METHOD_DELETE_VCF
+
+ return method
+
+
+ def _ANY():
+ return method
+
+ return {
+ "DELETE" : _DELETE,
+ "GET" : _GET,
+ "POST" : _POST,
+ "PROPFIND" : _PROPFIND,
+ "PROPPATCH" : _PROPPATCH,
+ "PUT" : _PUT,
+ "REPORT" : _REPORT,
+ }.get(method.split("(")[0], _ANY)()
+
+
+
+versionClients = (
+ "Mac OS X/",
+ "iOS/",
+ "iCal/",
+ "iPhone/",
+ "CalendarAgent",
+ "Calendar/",
+ "CoreDAV/",
+ "Safari/",
+ "dataaccessd",
+ "curl/",
+ "DAVKit",
+)
+
+quickclients = (
+ ("InterMapper/", "InterMapper"),
+ ("CardDAVPlugin/", "CardDAVPlugin"),
+ ("Address%20Book/", "AddressBook"),
+ ("AddressBook/", "AddressBook"),
+ ("Mail/", "Mail"),
+ ("iChat/", "iChat"),
+)
+
+def getAdjustedClientName(stats):
+
+ userAgent = stats["userAgent"]
+ for client in versionClients:
+ index = userAgent.find(client)
+ if index != -1:
+ l = len(client)
+ endex = userAgent[index + l:].find(' ', index)
+ return userAgent[index:] if endex == -1 else userAgent[index:endex + l]
+
+ for quick, result in quickclients:
+ index = userAgent.find(quick)
+ if index != -1:
+ return result
+
+ return userAgent[:20]
Deleted: CalendarServer/trunk/calendarserver/methodDescriptor.py
===================================================================
--- CalendarServer/trunk/calendarserver/methodDescriptor.py 2012-12-12 16:37:28 UTC (rev 10158)
+++ CalendarServer/trunk/calendarserver/methodDescriptor.py 2012-12-12 17:18:55 UTC (rev 10159)
@@ -1,330 +0,0 @@
-##
-# Copyright (c) 2012 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-# Adjust method names
-
-# PROPFINDs
-METHOD_PROPFIND_CALENDAR_HOME = "PROPFIND Calendar Home"
-METHOD_PROPFIND_CACHED_CALENDAR_HOME = "PROPFIND cached Calendar Home"
-METHOD_PROPFIND_CALENDAR = "PROPFIND Calendar"
-METHOD_PROPFIND_INBOX = "PROPFIND Inbox"
-METHOD_PROPFIND_ADDRESSBOOK_HOME = "PROPFIND Adbk Home"
-METHOD_PROPFIND_CACHED_ADDRESSBOOK_HOME = "PROPFIND cached Adbk Home"
-METHOD_PROPFIND_ADDRESSBOOK = "PROPFIND Adbk"
-METHOD_PROPFIND_DIRECTORY = "PROPFIND Directory"
-METHOD_PROPFIND_PRINCIPALS = "PROPFIND Principals"
-METHOD_PROPFIND_CACHED_PRINCIPALS = "PROPFIND cached Principals"
-
-# PROPPATCHs
-METHOD_PROPPATCH_CALENDAR = "PROPPATCH Calendar"
-METHOD_PROPPATCH_ADDRESSBOOK = "PROPPATCH Adbk Home"
-
-# REPORTs
-METHOD_REPORT_CALENDAR_MULTIGET = "REPORT cal-multi"
-METHOD_REPORT_CALENDAR_QUERY = "REPORT cal-query"
-METHOD_REPORT_CALENDAR_FREEBUSY = "REPORT freebusy"
-METHOD_REPORT_CALENDAR_SYNC = "REPORT cal-sync"
-METHOD_REPORT_ADDRESSBOOK_MULTIGET = "REPORT adbk-multi"
-METHOD_REPORT_ADDRESSBOOK_QUERY = "REPORT adbk-query"
-METHOD_REPORT_DIRECTORY_QUERY = "REPORT dir-query"
-METHOD_REPORT_ADDRESSBOOK_SYNC = "REPORT adbk-sync"
-METHOD_REPORT_P_SEARCH_P_SET = "REPORT p-set"
-METHOD_REPORT_P_P_SEARCH = "REPORT p-search"
-METHOD_REPORT_EXPAND_P = "REPORT expand"
-
-# POSTs
-METHOD_POST_CALENDAR_HOME = "POST Calendar Home"
-METHOD_POST_CALENDAR = "POST Calendar"
-METHOD_POST_CALENDAR_OBJECT = "POST Calendar Object"
-METHOD_POST_ADDRESSBOOK_HOME = "POST Adbk Home"
-METHOD_POST_ADDRESSBOOK = "POST Adbk"
-METHOD_POST_ISCHEDULE_FREEBUSY = "POST Freebusy iSchedule"
-METHOD_POST_ISCHEDULE = "POST iSchedule"
-METHOD_POST_TIMEZONES = "POST Timezones"
-METHOD_POST_FREEBUSY = "POST Freebusy"
-METHOD_POST_ORGANIZER = "POST Organizer"
-METHOD_POST_ATTENDEE = "POST Attendee"
-METHOD_POST_OUTBOX = "POST Outbox"
-METHOD_POST_APNS = "POST apns"
-
-# PUTs
-METHOD_PUT_ICS = "PUT ics"
-METHOD_PUT_ORGANIZER = "PUT Organizer"
-METHOD_PUT_ATTENDEE = "PUT Attendee"
-METHOD_PUT_DROPBOX = "PUT dropbox"
-METHOD_PUT_VCF = "PUT VCF"
-
-# GETs
-METHOD_GET_CALENDAR_HOME = "GET Calendar Home"
-METHOD_GET_CALENDAR = "GET Calendar"
-METHOD_GET_ICS = "GET ics"
-METHOD_GET_INBOX_ICS = "GET inbox ics"
-METHOD_GET_DROPBOX = "GET dropbox"
-METHOD_GET_ADDRESSBOOK_HOME = "GET Adbk Home"
-METHOD_GET_ADDRESSBOOK = "GET Adbk"
-METHOD_GET_VCF = "GET VCF"
-METHOD_GET_TIMEZONES = "GET Timezones"
-
-# DELETEs
-METHOD_DELETE_CALENDAR_HOME = "DELETE Calendar Home"
-METHOD_DELETE_CALENDAR = "DELETE Calendar"
-METHOD_DELETE_ICS = "DELETE ics"
-METHOD_DELETE_INBOX_ICS = "DELETE inbox ics"
-METHOD_DELETE_DROPBOX = "DELETE dropbox"
-METHOD_DELETE_ADDRESSBOOK_HOME = "DELETE Adbk Home"
-METHOD_DELETE_ADDRESSBOOK = "DELETE Adbk"
-METHOD_DELETE_VCF = "DELETE vcf"
-
-
-def getAdjustedMethodName(method, uri, extended):
-
- uribits = uri.rstrip("/").split('/')[1:]
- if len(uribits) == 0:
- uribits = [uri]
-
- calendar_specials = ("attachments", "dropbox", "notification", "freebusy", "outbox",)
- adbk_specials = ("notification",)
-
- def _PROPFIND():
- cached = "cached" in extended
-
- if uribits[0] == "calendars":
-
- if len(uribits) == 3:
- return METHOD_PROPFIND_CACHED_CALENDAR_HOME if cached else METHOD_PROPFIND_CALENDAR_HOME
- elif len(uribits) > 3:
- if uribits[3] in calendar_specials:
- return "PROPFIND %s" % (uribits[3],)
- elif len(uribits) == 4:
- if uribits[3] == "inbox":
- return METHOD_PROPFIND_INBOX
- else:
- return METHOD_PROPFIND_CALENDAR
-
- elif uribits[0] == "addressbooks":
-
- if len(uribits) == 3:
- return METHOD_PROPFIND_CACHED_ADDRESSBOOK_HOME if cached else METHOD_PROPFIND_ADDRESSBOOK_HOME
- elif len(uribits) > 3:
- if uribits[3] in adbk_specials:
- return "PROPFIND %s" % (uribits[3],)
- elif len(uribits) == 4:
- return METHOD_PROPFIND_ADDRESSBOOK
-
- elif uribits[0] == "directory":
- return METHOD_PROPFIND_DIRECTORY
-
- elif uribits[0] == "principals":
- return METHOD_PROPFIND_CACHED_PRINCIPALS if cached else METHOD_PROPFIND_PRINCIPALS
-
- return method
-
-
- def _REPORT():
-
- if "(" in method:
- report_type = method.split("}" if "}" in method else ":")[1][:-1]
- if report_type == "addressbook-query":
- if uribits[0] == "directory":
- report_type = "directory-query"
- if report_type == "sync-collection":
- if uribits[0] == "calendars":
- report_type = "cal-sync"
- elif uribits[0] == "addressbooks":
- report_type = "adbk-sync"
- mappedNames = {
- "calendar-multiget" : METHOD_REPORT_CALENDAR_MULTIGET,
- "calendar-query" : METHOD_REPORT_CALENDAR_QUERY,
- "free-busy-query" : METHOD_REPORT_CALENDAR_FREEBUSY,
- "cal-sync" : METHOD_REPORT_CALENDAR_SYNC,
- "addressbook-multiget" : METHOD_REPORT_ADDRESSBOOK_MULTIGET,
- "addressbook-query" : METHOD_REPORT_ADDRESSBOOK_QUERY,
- "directory-query" : METHOD_REPORT_DIRECTORY_QUERY,
- "adbk-sync" : METHOD_REPORT_ADDRESSBOOK_SYNC,
- "principal-search-property-set" : METHOD_REPORT_P_SEARCH_P_SET,
- "principal-property-search" : METHOD_REPORT_P_P_SEARCH,
- "expand-property" : METHOD_REPORT_EXPAND_P,
- }
- return mappedNames.get(report_type, "REPORT %s" % (report_type,))
-
- return method
-
-
- def _PROPPATCH():
-
- if uribits[0] == "calendars":
- return METHOD_PROPPATCH_CALENDAR
- elif uribits[0] == "addressbooks":
- return METHOD_PROPPATCH_ADDRESSBOOK
-
- return method
-
-
- def _POST():
-
- if uribits[0] == "calendars":
-
- if len(uribits) == 3:
- return METHOD_POST_CALENDAR_HOME
- elif len(uribits) == 4:
- if uribits[3] == "outbox":
- if "recipients" in extended:
- return METHOD_POST_FREEBUSY
- elif "freebusy" in extended:
- return METHOD_POST_FREEBUSY
- elif "itip.request" in extended or "itip.cancel" in extended:
- return METHOD_POST_ORGANIZER
- elif "itip.reply" in extended:
- return METHOD_POST_ATTENDEE
- else:
- return METHOD_POST_OUTBOX
- elif uribits[3] in calendar_specials:
- pass
- else:
- return METHOD_POST_CALENDAR
- elif len(uribits) == 5:
- return METHOD_POST_CALENDAR_OBJECT
-
- elif uribits[0] == "addressbooks":
-
- if len(uribits) == 3:
- return METHOD_POST_ADDRESSBOOK_HOME
- elif len(uribits) == 4:
- if uribits[3] in adbk_specials:
- pass
- else:
- return METHOD_POST_ADDRESSBOOK
-
- elif uribits[0] == "ischedule":
- if "fb-cached" in extended or "fb-uncached" in extended or "freebusy" in extended:
- return METHOD_POST_ISCHEDULE_FREEBUSY
- else:
- return METHOD_POST_ISCHEDULE
-
- elif uribits[0].startswith("timezones"):
- return METHOD_POST_TIMEZONES
-
- elif uribits[0].startswith("apns"):
- return METHOD_POST_APNS
-
- return method
-
-
- def _PUT():
-
- if uribits[0] == "calendars":
- if len(uribits) > 3:
- if uribits[3] in calendar_specials:
- return "PUT %s" % (uribits[3],)
- elif len(uribits) == 4:
- pass
- else:
- if "itip.requests" in extended:
- return METHOD_PUT_ORGANIZER
- elif "itip.reply" in extended:
- return METHOD_PUT_ATTENDEE
- else:
- return METHOD_PUT_ICS
-
- elif uribits[0] == "addressbooks":
- if len(uribits) > 3:
- if uribits[3] in adbk_specials:
- return "PUT %s" % (uribits[3],)
- elif len(uribits) == 4:
- pass
- else:
- return METHOD_PUT_VCF
-
- return method
-
-
- def _GET():
-
- if uribits[0] == "calendars":
-
- if len(uribits) == 3:
- return METHOD_GET_CALENDAR_HOME
- elif len(uribits) > 3:
- if uribits[3] in calendar_specials:
- return "GET %s" % (uribits[3],)
- elif len(uribits) == 4:
- return METHOD_GET_CALENDAR
- elif uribits[3] == "inbox":
- return METHOD_GET_INBOX_ICS
- else:
- return METHOD_GET_ICS
-
- elif uribits[0] == "addressbooks":
-
- if len(uribits) == 3:
- return METHOD_GET_ADDRESSBOOK_HOME
- elif len(uribits) > 3:
- if uribits[3] in adbk_specials:
- return "GET %s" % (uribits[3],)
- elif len(uribits) == 4:
- return METHOD_GET_ADDRESSBOOK
- else:
- return METHOD_GET_VCF
-
- elif uribits[0].startswith("timezones"):
- return METHOD_GET_TIMEZONES
-
- return method
-
-
- def _DELETE():
-
- if uribits[0] == "calendars":
-
- if len(uribits) == 3:
- return METHOD_DELETE_CALENDAR_HOME
- elif len(uribits) > 3:
- if uribits[3] in calendar_specials:
- return "DELETE %s" % (uribits[3],)
- elif len(uribits) == 4:
- return METHOD_DELETE_CALENDAR
- elif uribits[3] == "inbox":
- return METHOD_DELETE_INBOX_ICS
- else:
- return METHOD_DELETE_ICS
-
- elif uribits[0] == "addressbooks":
-
- if len(uribits) == 3:
- return METHOD_DELETE_ADDRESSBOOK_HOME
- elif len(uribits) > 3:
- if uribits[3] in adbk_specials:
- return "DELETE %s" % (uribits[3],)
- elif len(uribits) == 4:
- return METHOD_DELETE_ADDRESSBOOK
- else:
- return METHOD_DELETE_VCF
-
- return method
-
-
- def _ANY():
- return method
-
- return {
- "DELETE" : _DELETE,
- "GET" : _GET,
- "POST" : _POST,
- "PROPFIND" : _PROPFIND,
- "PROPPATCH" : _PROPPATCH,
- "PUT" : _PUT,
- "REPORT" : _REPORT,
- }.get(method.split("(")[0], _ANY)()
Modified: CalendarServer/trunk/contrib/tools/readStats.py
===================================================================
--- CalendarServer/trunk/contrib/tools/readStats.py 2012-12-12 16:37:28 UTC (rev 10158)
+++ CalendarServer/trunk/contrib/tools/readStats.py 2012-12-12 17:18:55 UTC (rev 10159)
@@ -54,23 +54,23 @@
-def printStats(stats, multimode, showMethods, topUsers):
+def printStats(stats, multimode, showMethods, topUsers, showAgents):
if len(stats) == 1:
if "Failed" in stats[0]:
printFailedStats(stats[0]["Failed"])
else:
try:
- printStat(stats[0], multimode[0], showMethods, topUsers)
+ printStat(stats[0], multimode[0], showMethods, topUsers, showAgents)
except KeyError, e:
printFailedStats("Unable to find key '%s' in statistics from server socket" % (e,))
sys.exit(1)
else:
- printMultipleStats(stats, multimode, showMethods, topUsers)
+ printMultipleStats(stats, multimode, showMethods, topUsers, showAgents)
-def printStat(stats, index, showMethods, topUsers):
+def printStat(stats, index, showMethods, topUsers, showAgents):
print "- " * 40
print "Server: %s" % (stats["Server"],)
@@ -91,15 +91,17 @@
print "Current Memory Used: Unavailable"
print
printRequestSummary(stats)
- printHistogramSummary(stats[index])
+ printHistogramSummary(stats[index], index)
if showMethods:
printMethodCounts(stats[index])
if topUsers:
printUserCounts(stats[index], topUsers)
+ if showAgents:
+ printAgentCounts(stats[index])
-def printMultipleStats(stats, multimode, showMethods, topUsers):
+def printMultipleStats(stats, multimode, showMethods, topUsers, showAgents):
labels = serverLabels(stats)
@@ -130,6 +132,8 @@
printMultiMethodCounts(stats, multimode[0])
if topUsers:
printMultiUserCounts(stats, multimode[0], topUsers)
+ if showAgents:
+ printMultiAgentCounts(stats, multimode[0])
@@ -274,9 +278,9 @@
-def printHistogramSummary(stat):
+def printHistogramSummary(stat, index):
- print "5 minute average response histogram"
+ print "%s average response histogram" % (index,)
table = tables.Table()
table.addHeader(
("", "<10ms", "10ms<->100ms", "100ms<->1s", "1s<->10s", "10s<->30s", "30s<->60s", ">60s", "Over 1s", "Over 10s"),
@@ -329,41 +333,7 @@
for k in keys[1:]:
totals[i][k] += stat[index][i][k]
- print "%s average response histogram" % (index,)
- table = tables.Table()
- table.addHeader(
- ("", "<10ms", "10ms<->100ms", "100ms<->1s", "1s<->10s", "10s<->30s", "30s<->60s", ">60s", "Over 1s", "Over 10s"),
- )
- table.setDefaultColumnFormats(
- (
- tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.LEFT_JUSTIFY),
- tables.Table.ColumnFormat("%d (%.1f%%)", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
- tables.Table.ColumnFormat("%d (%.1f%%)", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
- tables.Table.ColumnFormat("%d (%.1f%%)", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
- tables.Table.ColumnFormat("%d (%.1f%%)", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
- tables.Table.ColumnFormat("%d (%.1f%%)", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
- tables.Table.ColumnFormat("%d (%.1f%%)", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
- tables.Table.ColumnFormat("%d (%.1f%%)", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
- tables.Table.ColumnFormat("%.1f%%", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
- tables.Table.ColumnFormat("%.1f%%", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
- )
- )
- for i in ("T", "T-RESP-WR",):
- table.addRow((
- "Overall Response" if i == "T" else "Response Write",
- (totals[i]["<10ms"], safeDivision(totals[i]["<10ms"], totals[i]["requests"], 100.0)),
- (totals[i]["10ms<->100ms"], safeDivision(totals[i]["10ms<->100ms"], totals[i]["requests"], 100.0)),
- (totals[i]["100ms<->1s"], safeDivision(totals[i]["100ms<->1s"], totals[i]["requests"], 100.0)),
- (totals[i]["1s<->10s"], safeDivision(totals[i]["1s<->10s"], totals[i]["requests"], 100.0)),
- (totals[i]["10s<->30s"], safeDivision(totals[i]["10s<->30s"], totals[i]["requests"], 100.0)),
- (totals[i]["30s<->60s"], safeDivision(totals[i]["30s<->60s"], totals[i]["requests"], 100.0)),
- (totals[i][">60s"], safeDivision(totals[i][">60s"], totals[i]["requests"], 100.0)),
- safeDivision(totals[i]["Over 1s"], totals[i]["requests"], 100.0),
- safeDivision(totals[i]["Over 10s"], totals[i]["requests"], 100.0),
- ))
- os = StringIO()
- table.printTable(os=os)
- print os.getvalue()
+ printHistogramSummary(totals, index)
@@ -372,22 +342,38 @@
print "Method Counts"
table = tables.Table()
table.addHeader(
- ("Method", "Total", "Percentage"),
+ ("Method", "Count", "%", "Av. Response", "%", "Total Resp. %"),
)
+ table.addHeader(
+ ("", "", "", "(ms)", "", ""),
+ )
table.setDefaultColumnFormats(
(
tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.LEFT_JUSTIFY),
tables.Table.ColumnFormat("%d", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
tables.Table.ColumnFormat("%.1f%%", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
+ tables.Table.ColumnFormat("%.1f", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
+ tables.Table.ColumnFormat("%.1f%%", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
+ tables.Table.ColumnFormat("%.1f%%", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
)
)
- total = sum(stat["method"].values())
+ response_average = {}
+ for method in stat["method"].keys():
+ response_average[method] = stat["method-t"][method] / stat["method"][method]
+
+ total_count = sum(stat["method"].values())
+ total_avresponse = sum(response_average.values())
+ total_response = sum(stat["method-t"].values())
+
for method in sorted(stat["method"].keys()):
table.addRow((
method,
stat["method"][method],
- safeDivision(stat["method"][method], total, 100.0),
+ safeDivision(stat["method"][method], total_count, 100.0),
+ response_average[method],
+ safeDivision(response_average[method], total_avresponse, 100.0),
+ safeDivision(stat["method-t"][method], total_response, 100.0),
))
os = StringIO()
table.printTable(os=os)
@@ -398,36 +384,17 @@
def printMultiMethodCounts(stats, index):
methods = collections.defaultdict(int)
+ method_times = collections.defaultdict(float)
for stat in stats:
for method in stat[index]["method"]:
methods[method] += stat[index]["method"][method]
+ for method_time in stat[index]["method-t"]:
+ method_times[method_time] += stat[index]["method-t"][method_time]
- print "Method Counts"
- table = tables.Table()
- table.addHeader(
- ("Method", "Total", "Percentage"),
- )
- table.setDefaultColumnFormats(
- (
- tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.LEFT_JUSTIFY),
- tables.Table.ColumnFormat("%d", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
- tables.Table.ColumnFormat("%.1f%%", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
- )
- )
+ printMethodCounts({"method": methods, "method-t": method_times})
- total = sum(methods.values())
- for method in sorted(methods.keys()):
- table.addRow((
- method,
- methods[method],
- safeDivision(methods[method], total, 100.0),
- ))
- os = StringIO()
- table.printTable(os=os)
- print os.getvalue()
-
def printUserCounts(stat, topUsers):
print "User Counts"
@@ -444,11 +411,11 @@
)
total = sum(stat["uid"].values())
- for uid in sorted(stat["uid"].items(), key=lambda x: x[1], reverse=True)[:topUsers]:
+ for uid, value in sorted(stat["uid"].items(), key=lambda x: x[1], reverse=True)[:topUsers]:
table.addRow((
uid,
- stat["uid"][uid],
- safeDivision(stat["uid"][uid], total, 100.0),
+ value,
+ safeDivision(value, total, 100.0),
))
os = StringIO()
table.printTable(os=os)
@@ -463,25 +430,31 @@
for uid in stat[index]["uid"]:
uids[uid] += stat[index]["uid"][uid]
- print "User Counts"
+ printUserCounts({"uid": uids}, topUsers)
+
+
+
+def printAgentCounts(stat):
+
+ print "User-Agent Counts"
table = tables.Table()
table.addHeader(
- ("User", "Total", "Percentage"),
+ ("User-Agent", "Total", "Percentage"),
)
table.setDefaultColumnFormats(
- (
+ (
tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.LEFT_JUSTIFY),
tables.Table.ColumnFormat("%d", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
tables.Table.ColumnFormat("%.1f%%", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
)
)
- total = sum(uids.values())
- for uid, count in sorted(uids.items(), key=lambda x: x[1], reverse=True)[:topUsers]:
+ total = sum(stat["user-agent"].values())
+ for ua in sorted(stat["user-agent"].keys()):
table.addRow((
- uid,
- count,
- safeDivision(count, total, 100.0),
+ ua,
+ stat["user-agent"][ua],
+ safeDivision(stat["user-agent"][ua], total, 100.0),
))
os = StringIO()
table.printTable(os=os)
@@ -489,6 +462,17 @@
+def printMultiAgentCounts(stats, index):
+
+ uas = collections.defaultdict(int)
+ for stat in stats:
+ for ua in stat[index]["user-agent"]:
+ uas[ua] += stat[index]["user-agent"][ua]
+
+ printUserCounts({"user-agent": uas})
+
+
+
def usage(error_msg=None):
if error_msg:
print error_msg
@@ -505,6 +489,7 @@
--60 Display multiserver 1 hour average
--methods Include details about HTTP method usage
--users N Include details about top N users
+ --agents Include details about HTTP User-Agent usage
Description:
This utility will print a summary of statistics read from a
@@ -525,11 +510,12 @@
useTCP = False
showMethods = False
topUsers = 0
+ showAgents = False
multimodes = (("Current", 60,), ("1 Minute", 60,), ("5 Minutes", 5 * 60,), ("1 Hour", 60 * 60,),)
multimode = multimodes[2]
- options, args = getopt.getopt(sys.argv[1:], "hs:t:", ["tcp=", "0", "1", "5", "60", "methods", "users="])
+ options, args = getopt.getopt(sys.argv[1:], "hs:t:", ["tcp=", "0", "1", "5", "60", "methods", "users=", "agents"])
for option, value in options:
if option == "-h":
@@ -553,7 +539,9 @@
showMethods = True
elif option == "--users":
topUsers = int(value)
+ elif option == "--agents":
+ showAgents = True
while True:
- printStats([readSock(server, useTCP) for server in servers], multimode, showMethods, topUsers)
+ printStats([readSock(server, useTCP) for server in servers], multimode, showMethods, topUsers, showAgents)
time.sleep(delay)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20121212/3cce5bd3/attachment-0001.html>
More information about the calendarserver-changes
mailing list