Quick statistics on support response times
authorAdam Chlipala <adamc@hcoop.net>
Mon, 26 Feb 2007 00:23:09 +0000 (00:23 +0000)
committerAdam Chlipala <adamc@hcoop.net>
Mon, 26 Feb 2007 00:23:09 +0000 (00:23 +0000)
qos.mlt
qos.sig
qos.sml

diff --git a/qos.mlt b/qos.mlt
index cc0cfaa..47231b7 100644 (file)
--- a/qos.mlt
+++ b/qos.mlt
@@ -2,9 +2,12 @@
 
 val days = case $"days" of
                  "" => 7
-               | days => Web.stoi days %>
+               | days => Web.stoi days;
+
+if $"cmd" = "list" then %>
 
 <form method="post">
+<input type="hidden" name="cmd" value="list">
 Show me the entries from the last <input name="days" size="7" value="<% days %>"> days.
 <input type="submit" value="Show">
 </form>
@@ -24,6 +27,31 @@ foreach qos in Qos.recent days do %>
 
 </table>
 
+<% else %>
+
+<p><a href="qos?cmd=list">List all recent support requests</a></p>
+
+<form method="post">
+Refresh statistics to include the last <input name="days" size="7" value="<% days %>"> days.
+<input type="submit" value="Show">
+</form>
+
+<br><hr><br>
+
+<% val stats = Qos.reportCard days %>
+<table>
+<tr> <td><b>Kind</b></td> <td><b>Total resolved issues</b></td> <td><b>Minutes to resolve</b></td> </tr>
+<tr> <td>APT packages</td> <td><% #count (#apt stats) %></td> <td><% #minutes (#apt stats) %></td> </tr>
+<tr> <td>Domains</td> <td><% #count (#domain stats) %></td> <td><% #minutes (#domain stats) %></td> </tr>
+<tr> <td>Mailing lists</td> <td><% #count (#mailingList stats) %></td> <td><% #minutes (#mailingList stats) %></td> </tr>
+<tr> <td>Security</td> <td><% #count (#sec stats) %></td> <td><% #minutes (#sec stats) %></td> </tr>
+<tr> <td>Miscellaneous</td> <td><% #count (#closed (#misc stats)) %></td> <td><% #minutes (#closed (#misc stats)) %></td> </tr>
+</table>
+
+<p>Additionally, <% #count (#pending (#misc stats)) %> miscellaneous support requests placed in this period have at some time been marked as pending or closed, and it took on average <% #minutes (#pending (#misc stats)) %> minutes to do so.</p>
+
+<% end %>
+
 <% @footer [] %>
 
 
diff --git a/qos.sig b/qos.sig
index d617aec..144c564 100644 (file)
--- a/qos.sig
+++ b/qos.sig
@@ -5,4 +5,14 @@ signature QOS = sig
 
     val recent : int -> entry list
 
+    type grade = { count : int, minutes : int }
+    type grades = { pending : grade, closed : grade }
+    type reportCard = { misc : grades,
+                       apt : grade,
+                       domain : grade,
+                       mailingList : grade,
+                       sec : grade }
+
+    val reportCard : int -> reportCard
+
 end
diff --git a/qos.sml b/qos.sml
index 4d06332..cd71246 100644 (file)
--- a/qos.sml
+++ b/qos.sml
@@ -42,4 +42,45 @@ fun recent days =
                               ORDER BY stamp DESC`)
     end
 
+type grade = { count : int, minutes : int }
+type grades = { pending : grade, closed : grade }
+type reportCard = { misc : grades,
+                   apt : grade,
+                   domain : grade,
+                   mailingList : grade,
+                   sec : grade }
+
+fun mkGradeRow [count, minutes] =
+    {count = C.intFromSql count,
+     minutes = if C.isNull minutes then 0 else C.intFromSql minutes}
+  | mkGradeRow row = rowError ("grade", row)
+
+fun reportCard days =
+    let
+       val db = getDb ()
+
+       fun gradeRow s = mkGradeRow (C.oneRow db s)
+
+       fun default tab =
+           gradeRow ($`SELECT COUNT(*), AVG(cstamp - stamp)
+                         FROM ^tab
+                         WHERE stamp >= CURRENT_TIMESTAMP - interval '^(C.intToSql days) DAYS'
+                            AND cstamp IS NOT NULL`)
+    in
+       {misc = {pending = gradeRow
+                ($`SELECT COUNT(*), AVG(COALESCE(pstamp, cstamp) - stamp)
+                     FROM SupIssue
+                      WHERE stamp >= CURRENT_TIMESTAMP - interval '^(C.intToSql days) DAYS'
+                        AND COALESCE(pstamp, cstamp) IS NOT NULL`),
+                closed = gradeRow
+                ($`SELECT COUNT(*), AVG(cstamp - stamp)
+                     FROM SupIssue
+                     WHERE stamp >= CURRENT_TIMESTAMP - interval '^(C.intToSql days) DAYS'
+                        AND cstamp IS NOT NULL`)},
+        apt = default "Apt",
+        domain = default "Domain",
+        mailingList = default "MailingList",
+        sec = default "Sec"}
+    end
+
 end