[CalendarServer-changes] [15116] CalendarServer/branches/release/CalendarServer-5.4-dev/contrib/ tools/readStats.py

source_changes at macosforge.org source_changes at macosforge.org
Thu Sep 10 09:07:25 PDT 2015


Revision: 15116
          http://trac.calendarserver.org//changeset/15116
Author:   cdaboo at apple.com
Date:     2015-09-10 09:07:24 -0700 (Thu, 10 Sep 2015)
Log Message:
-----------
Add ability to generate terminal/bell sounds when certain values exceed a threshold.

Modified Paths:
--------------
    CalendarServer/branches/release/CalendarServer-5.4-dev/contrib/tools/readStats.py

Modified: CalendarServer/branches/release/CalendarServer-5.4-dev/contrib/tools/readStats.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.4-dev/contrib/tools/readStats.py	2015-09-09 20:30:31 UTC (rev 15115)
+++ CalendarServer/branches/release/CalendarServer-5.4-dev/contrib/tools/readStats.py	2015-09-10 16:07:24 UTC (rev 15116)
@@ -34,7 +34,10 @@
     return value * factor / total if total else 0
 
 
+SummaryValues = collections.namedtuple("SummaryValues", ("requests", "response", "slots", "cpu", "errors"))
 
+
+
 def readSock(sockname, useTCP):
     try:
         s = socket.socket(socket.AF_INET if useTCP else socket.AF_UNIX, socket.SOCK_STREAM)
@@ -61,16 +64,18 @@
             printFailedStats(stats[0]["Failed"])
         else:
             try:
-                printStat(stats[0], multimode[0], showMethods, topUsers, showAgents)
+                summary = 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, showAgents)
+        summary = printMultipleStats(stats, multimode, showMethods, topUsers, showAgents)
 
+    return summary
 
 
+
 def printStat(stats, index, showMethods, topUsers, showAgents):
 
     print("- " * 40)
@@ -91,7 +96,7 @@
         print("Current CPU: Unavailable")
         print("Current Memory Used: Unavailable")
     print
-    printRequestSummary(stats)
+    summary = printRequestSummary(stats)
     printHistogramSummary(stats[index], index)
     if showMethods:
         printMethodCounts(stats[index])
@@ -100,8 +105,10 @@
     if showAgents:
         printAgentCounts(stats[index])
 
+    return summary
 
 
+
 def printMultipleStats(stats, multimode, showMethods, topUsers, showAgents):
 
     labels = serverLabels(stats)
@@ -127,7 +134,7 @@
             cpus.append(-1)
             memories.append(-1)
 
-    printMultiRequestSummary(stats, cpus, memories, times, labels, multimode)
+    summary = printMultiRequestSummary(stats, cpus, memories, times, labels, multimode)
     printMultiHistogramSummary(stats, multimode[0])
     if showMethods:
         printMultiMethodCounts(stats, multimode[0])
@@ -136,8 +143,10 @@
     if showAgents:
         printMultiAgentCounts(stats, multimode[0])
 
+    return summary
 
 
+
 def serverLabels(stats):
     servers = [stat["Server"] for stat in stats]
     if isinstance(servers[0], tuple):
@@ -225,8 +234,17 @@
     table.printTable(os=os)
     print(os.getvalue())
 
+    stat = stats["1m"]
+    return SummaryValues(
+        requests=safeDivision(float(stat["requests"]), seconds),
+        response=safeDivision(stat["t"], stat["requests"]),
+        slots=safeDivision(float(stat["slots"]), stat["requests"]),
+        cpu=safeDivision(stat["cpu"], stat["requests"]),
+        errors=stat["500"],
+    )
 
 
+
 def printMultiRequestSummary(stats, cpus, memories, times, labels, index):
 
     key, seconds = index
@@ -294,8 +312,16 @@
     table.printTable(os=os)
     print(os.getvalue())
 
+    return SummaryValues(
+        requests=totals[2],
+        response=totals[3],
+        slots=totals[6],
+        cpu=totals[7],
+        errors=totals[10],
+    )
 
 
+
 def printHistogramSummary(stat, index):
 
     print("%s average response histogram" % (index,))
@@ -493,6 +519,32 @@
 
 
 
+def alert(summary, alerts):
+
+    alert = []
+    for attr, description in (
+        ("requests", "Request count",),
+        ("response", "Response time",),
+        ("slots", "Slot count",),
+        ("cpu", "CPU time",),
+        ("errors", "Error count",),
+    ):
+        threshold = getattr(alerts, attr)
+        value = getattr(summary, attr)
+        if threshold is not None and value > threshold:
+            if isinstance(value, float):
+                value = "{:.1f}".format(value)
+            alert.append("{} threshold exceeded: {}".format(description, value))
+
+    if alert:
+        for _ignore in range(10):
+            print('\a', end='')
+            sys.stdout.flush()
+            time.sleep(0.15)
+        print("\n".join(alert))
+
+
+
 def usage(error_msg=None):
     if error_msg:
         print(error_msg)
@@ -511,6 +563,17 @@
     --users N     Include details about top N users
     --agents      Include details about HTTP User-Agent usage
 
+    --alert-requests N     Generate an alert if the overall request
+                            count exceeds a threshold [INT]
+    --alert-response N     Generate an alert if the overall average
+                            response time exceeds a threshold [INT]
+    --alert-slots N        Generate an alert if the overall slot
+                            count exceeds a threshold [FLOAT]
+    --alert-cpu N          Generate an alert if the overall average
+                            cpu percent use exceeds a threshold [INT]
+    --alert-errors N       Generate an alert if the overall error
+                            count exceeds a threshold [INT]
+
 Description:
     This utility will print a summary of statistics read from a
     server continuously with the specified delay.
@@ -531,11 +594,21 @@
     showMethods = False
     topUsers = 0
     showAgents = False
+    alerts = SummaryValues(
+        requests=None,
+        response=None,
+        slots=None,
+        cpu=None,
+        errors=None,
+    )
 
     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=", "agents"])
+    options, args = getopt.getopt(sys.argv[1:], "hs:t:", [
+        "tcp=", "0", "1", "5", "60", "methods", "users=", "agents",
+        "alert-requests=", "alert-response=", "alert-slots=", "alert-cpu=", "alert-errors=",
+    ])
 
     for option, value in options:
         if option == "-h":
@@ -561,7 +634,19 @@
             topUsers = int(value)
         elif option == "--agents":
             showAgents = True
+        elif option == "--alert-requests":
+            alerts = alerts._replace(requests=int(value))
+        elif option == "--alert-response":
+            alerts = alerts._replace(response=int(value))
+        elif option == "--alert-slots":
+            alerts = alerts._replace(slots=float(value))
+        elif option == "--alert-cpu":
+            alerts = alerts._replace(cpu=int(value))
+        elif option == "--alert-errors":
+            alerts = alerts._replace(errors=int(value))
 
     while True:
-        printStats([readSock(server, useTCP) for server in servers], multimode, showMethods, topUsers, showAgents)
-        time.sleep(delay)
+        now = time.time()
+        summary = printStats([readSock(server, useTCP) for server in servers], multimode, showMethods, topUsers, showAgents)
+        alert(summary, alerts)
+        time.sleep(delay - (time.time() - now))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20150910/f87c4f86/attachment-0001.html>


More information about the calendarserver-changes mailing list