[CalendarServer-changes] [10761] CalendarServer/trunk/contrib/tools/request_monitor.py

source_changes at macosforge.org source_changes at macosforge.org
Tue Feb 19 14:13:57 PST 2013


Revision: 10761
          http://trac.calendarserver.org//changeset/10761
Author:   cdaboo at apple.com
Date:     2013-02-19 14:13:57 -0800 (Tue, 19 Feb 2013)
Log Message:
-----------
Allow number of top users to be set on the cmdline.

Modified Paths:
--------------
    CalendarServer/trunk/contrib/tools/request_monitor.py

Modified: CalendarServer/trunk/contrib/tools/request_monitor.py
===================================================================
--- CalendarServer/trunk/contrib/tools/request_monitor.py	2013-02-19 20:42:18 UTC (rev 10760)
+++ CalendarServer/trunk/contrib/tools/request_monitor.py	2013-02-19 22:13:57 UTC (rev 10761)
@@ -65,10 +65,10 @@
     VMSTAT = "/usr/bin/vmstat"
     enableFreeMem = os.path.exists(VMSTAT)
 
-sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) 
+sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
 
 
-filenames = ["/var/log/caldavd/access.log",]
+filenames = ["/var/log/caldavd/access.log", ]
 debug = False
 
 def listenq():
@@ -79,7 +79,7 @@
         stdout=PIPE, stderr=STDOUT,
     )
     output, _ignore_error = child.communicate()
-    ssl = nonssl = 0   
+    ssl = nonssl = 0
     for line in output.split("\n"):
         if line.find("8443") != -1:
             ssl = int(line.split("/")[0])
@@ -121,6 +121,8 @@
         results[filename].extend(output.splitlines())
     return results
 
+
+
 def range(filenames, start, end):
     results = collections.defaultdict(list)
     for filename in filenames:
@@ -132,6 +134,8 @@
                     break
     return results
 
+
+
 def cpuPerDaemon():
     a = {}
     child = Popen(
@@ -155,6 +159,7 @@
     return ", ".join([v for _ignore_k, v in sorted(a.items(), key=lambda i:i[0])])
 
 
+
 def cpuidle():
     if OS == "OS X":
         child = Popen(
@@ -175,6 +180,8 @@
         output, _ignore_ = child.communicate()
         return output.splitlines()[-2].split()[5]
 
+
+
 def freemem():
     try:
         if OS == "OS X":
@@ -186,11 +193,11 @@
             )
             output, _ignore_ = child.communicate()
             lines = output.split("\n")
-            
+
             line = lines[0]
-            pageSize = int(line[line.find("page size of")+12:].split()[0])
+            pageSize = int(line[line.find("page size of") + 12:].split()[0])
             line = lines[1]
-            freeSize = int(line[line.find("Pages free:")+11:].split()[0][:-1])
+            freeSize = int(line[line.find("Pages free:") + 11:].split()[0][:-1])
             freed = freeSize * pageSize
             return "%d bytes (%.1f GB)" % (freed, freed / (1024.0 * 1024 * 1024),)
         elif OS == "Linux":
@@ -202,7 +209,7 @@
             )
             output, _ignore_ = child.communicate()
             lines = output.splitlines()
-            
+
             line = lines[4]
             freed = int(line.split()[0]) * 1024
             return "%d bytes (%.1f GB)" % (freed, freed / (1024.0 * 1024 * 1024),)
@@ -212,11 +219,13 @@
             print traceback.print_exc()
         return "error"
 
+
+
 def parseLine(line):
 
     startPos = line.find("- ")
     endPos = line.find(" [")
-    userId = line[startPos+2:endPos]
+    userId = line[startPos + 2:endPos]
 
     startPos = endPos + 2
     endPos = line.find(']', startPos)
@@ -236,7 +245,7 @@
         uri = line[startPos:endPos]
         startPos = endPos + 11
 
-    status = int(line[startPos:startPos+3])
+    status = int(line[startPos:startPos + 3])
 
     startPos += 4
     endPos = line.find(' ', startPos)
@@ -266,16 +275,20 @@
         endPos = line.find(' ', startPos)
         extended["or"] = int(line[startPos:endPos])
     else:
-        
+
         items = line[startPos:].split()
         extended = dict([item.split('=') for item in items if item.find("=") != -1])
 
     return userId, logTime, method, uri, status, bytes, referer, client, extended
 
+
+
 def safePercent(value, total):
-    
+
     return value * 100.0 / total if total else 0.0
 
+
+
 def usage():
     print "request_monitor [OPTIONS] [FILENAME]"
     print
@@ -288,6 +301,7 @@
     print "--range M:N  specifies a range of lines to analyze from access.log (default: all)"
     print "--procs N  specifies how many python processes are expected in the log file (default: 80)"
     print "--top N    how many long requests to print (default: 10)"
+    print "--users N  how many top users to print (default: 5)"
     print "--router   analyze a partition server router node"
     print "--worker   analyze a partition server worker node"
     print
@@ -296,10 +310,11 @@
 numLines = 10000
 numProcs = 80
 numTop = 10
+numUsers = 5
 lineRange = None
 router = False
 worker = False
-options, args = getopt.getopt(sys.argv[1:], "h", ["debug", "router", "worker", "lines=", "range=", "procs=", "top="])
+options, args = getopt.getopt(sys.argv[1:], "h", ["debug", "router", "worker", "lines=", "range=", "procs=", "top=", "users="])
 for option, value in options:
     if option == "-h":
         usage()
@@ -318,6 +333,8 @@
         numProcs = int(value)
     elif option == "--top":
         numTop = int(value)
+    elif option == "--users":
+        numUsers = int(value)
 
 if len(args):
     filenames = sorted([os.path.expanduser(arg) for arg in args])
@@ -367,7 +384,7 @@
     totalOver1s = [0, 0]
     totalOver10s = [0, 0]
     requests = []
-    users = { }
+    users = {}
     startTime = None
     endTime = None
     errorCount = 0
@@ -379,35 +396,35 @@
             for line in lines[filename]:
                 if not line or line.startswith("Log"):
                     continue
-    
+
                 numRequests[filename] += 1
-    
+
                 try:
                     userId, logTime, method, uri, status, bytes, _ignore_referer, client, extended = parseLine(line)
                 except Exception, e:
                     parseErrors += 1
-                    
+
                     if debug:
                         print "Access log line parse failure", e
                         print traceback.print_exc()
                         print "---"
                         print line
                         print "---"
-                        
+
                     continue
-    
+
                 logTime = dateparse(logTime, fuzzy=True)
                 times.append(logTime)
                 perfile_times[filename].append(logTime)
-    
+
                 if status >= 500:
                     errorCount += 1
-    
+
                 if uri == "/ischedule":
                     numServerToServer[filename] += 1
                 elif uri.startswith("/calendars"):
                     numProxied[filename] += 1
-    
+
                 outstanding = int(extended['or'])
                 logId = int(extended['i'] if extended['i'] else 0)
                 raw = rawCounts.get(logId, 0) + 1
@@ -416,7 +433,7 @@
                 if outstanding > prevMax:
                     ids[logId] = outstanding
                 slotCount[filename] += outstanding
-    
+
                 respTime = float(extended['t'])
                 wrTime = float(extended.get('t-resp-wr', 0.0))
                 timeSpent = timesSpent.get(logId, 0.0) + respTime
@@ -425,65 +442,63 @@
                 totalRespWithoutWRTime[filename] += respTime - wrTime
                 if respTime > maxRespTime[filename]:
                     maxRespTime[filename] = respTime
-    
+
                 for index, testTime in enumerate((respTime, respTime - wrTime,)):
                     if testTime >= 60000.0:
                         over60s[index] += 1
                     elif testTime >= 30000.0:
-                        over30s[index] +=1
+                        over30s[index] += 1
                     elif testTime >= 10000.0:
-                        over10s[index] +=1
+                        over10s[index] += 1
                     elif testTime >= 1000.0:
-                        over1s[index] +=1
+                        over1s[index] += 1
                     elif testTime >= 100.0:
-                        over100ms[index] +=1
+                        over100ms[index] += 1
                     elif testTime >= 10.0:
-                        over10ms[index] +=1
+                        over10ms[index] += 1
                     else:
-                        under10ms[index] +=1
+                        under10ms[index] += 1
                     if testTime >= 1000.0:
-                        totalOver1s[index] +=1
+                        totalOver1s[index] += 1
                     if testTime >= 10000.0:
-                        totalOver10s[index] +=1
-    
-    
+                        totalOver10s[index] += 1
+
                 ext = []
                 for key, value in extended.iteritems():
                     if key not in ('i', 't'):
                         if key == "cl":
-                            value = float(value)/1024
+                            value = float(value) / 1024
                             value = "%.1fKB" % (value,)
                             key = "req"
                         ext.append("%s:%s" % (key, value))
                 ext = ", ".join(ext)
-    
+
                 try:
                     client = client.split(";")[2]
                     client = client.strip()
                 except:
                     pass
-    
+
                 if userId != "-":
-                    userStat = users.get(userId, { 'count' : 0, 'clients' : {} })
+                    userStat = users.get(userId, {'count' : 0, 'clients' : {}})
                     userStat['count'] += 1
                     clientCount = userStat['clients'].get(client, 0)
                     userStat['clients'][client] = clientCount + 1
                     users[userId] = userStat
-    
+
                 reqStartTime = logTime - datetime.timedelta(milliseconds=respTime)
-                requests.append((respTime, userId, method, bytes/1024.0, ext, client, logId, logTime, reqStartTime))
+                requests.append((respTime, userId, method, bytes / 1024.0, ext, client, logId, logTime, reqStartTime))
 
-
         times.sort()
         if len(times) == 0:
             print "No data to analyze"
             time.sleep(10)
             continue
-        
+
         totalRequests = sum(numRequests.values())
 
         print "- " * 40
-        print datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"), 
+        print datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
         if enableListenQueue:
             q, lqssl, lqnon = listenQueueHistory()
             print "Listenq (ssl+non):", q[0], " (Recent", ", ".join(q[1:]), "Oldest)"
@@ -497,14 +512,14 @@
 
         table = tables.Table()
         table.addHeader(
-            ("Instance", "Requests", "Av. Requests", "Av. Response", "Av. Response", "Max. Response",     "Slot", "Start",  "End", "File Name"),
+            ("Instance", "Requests", "Av. Requests", "Av. Response", "Av. Response", "Max. Response", "Slot", "Start", "End", "File Name"),
         )
         table.addHeader(
-            (        "",         "",   "per second",         "(ms)", "no write(ms)",          "(ms)",  "Average", "Time", "Time",          ""),
+            ("", "", "per second", "(ms)", "no write(ms)", "(ms)", "Average", "Time", "Time", ""),
         )
         table.setDefaultColumnFormats(
            (
-                tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.CENTER_JUSTIFY), 
+                tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.CENTER_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),
@@ -516,7 +531,7 @@
                 tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
             )
         )
-        
+
         totalAverage = 0.0
         totalResponseTime = 0.0
         totalResponseWithoutWRTime = 0.0
@@ -525,14 +540,14 @@
         minStartTime = None
         maxEndTime = None
         for ctr, filename in enumerate(sorted(perfile_times.keys())):
-            
+
             times = sorted(perfile_times[filename])
             startTime = times[0]
             minStartTime = startTime if minStartTime is None else min(minStartTime, startTime)
 
             endTime = times[-1]
             maxEndTime = endTime if maxEndTime is None else min(maxEndTime, endTime)
-            
+
             deltaTime = endTime - startTime
 
             avgRequests = float(len(times)) / deltaTime.seconds
@@ -540,16 +555,16 @@
 
             avgResponse = totalRespTime[filename] / len(times)
             totalResponseTime += totalRespTime[filename]
-            
+
             avgResponseWithWR = totalRespWithoutWRTime[filename] / len(times)
             totalResponseWithoutWRTime += totalRespWithoutWRTime[filename]
-            
+
             maxResponseTime = max(maxResponseTime, maxRespTime[filename])
-            
+
             totalSlots += slotCount[filename]
 
             table.addRow((
-                "#%s" % (ctr+1,),
+                "#%s" % (ctr + 1,),
                 len(times),
                 avgRequests,
                 avgResponse,
@@ -560,7 +575,7 @@
                 endTime,
                 filename[prefix:],
             ))
-            
+
         if len(perfile_times) > 1:
             table.addFooter((
                 "Total:",
@@ -574,7 +589,7 @@
                 maxEndTime,
                 "",
             ))
-            
+
         os = StringIO()
         table.printTable(os=os)
         print os.getvalue()
@@ -585,14 +600,14 @@
                 lqlatency[0],
                 lqlatency[1],
             )
-        
+
         table = tables.Table()
         table.addHeader(
-            ("", "<10ms", "10ms<->100ms", "100ms<->1s", "1s<->10s", "10s<->30s", "30s<->60s", ">60s",  "Over 1s", "Over 10s"),
+            ("", "<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.CENTER_JUSTIFY), 
+                tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.CENTER_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),
@@ -629,11 +644,11 @@
             print
 
         print "Proc:   Peak outstanding:        Seconds of processing (number of requests):"
-        for l in xrange((numProcs-1)/10 + 1):
+        for l in xrange((numProcs - 1) / 10 + 1):
             base = l * 10
-            print "%2d-%2d: " % (base, base+9),
+            print "%2d-%2d: " % (base, base + 9),
 
-            for i in xrange(base, base+10):
+            for i in xrange(base, base + 10):
                 try:
                     r = ids[i]
                     s = "%1d" % (r,)
@@ -643,16 +658,15 @@
 
             print "    ",
 
-            for i in xrange(base, base+10):
+            for i in xrange(base, base + 10):
                 try:
                     r = timesSpent[i] / 1000
                     c = rawCounts[i]
-                    s = "%4.0f(%4d)" % (r,c)
+                    s = "%4.0f(%4d)" % (r, c)
                 except KeyError:
                     s = "         ."
                 print s,
 
-
             print
 
         print
@@ -675,16 +689,14 @@
             except:
                 pass
 
-            
-
         print
-        print "Top 5 busiest users (in most recent %d requests):" % (totalRequests,)
+        print "Top %d busiest users (in most recent %d requests):" % (numUsers, totalRequests,)
         userlist = []
         for user, userStat in users.iteritems():
             userlist.append((userStat['count'], user, userStat))
         userlist.sort()
         userlist.reverse()
-        for i in xrange(5):
+        for i in xrange(numUsers):
             try:
                 count, user, userStat = userlist[i]
                 print "%3d  %-12s " % (count, user),
@@ -701,7 +713,7 @@
                 pass
 
         print
-        
+
         # lineRange => do loop only once
         if lineRange is not None:
             break
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130219/3cdf1b7b/attachment-0001.html>


More information about the calendarserver-changes mailing list