diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.html b/src/nl/astraeus/jdbc/web/page/LiveOverview.html new file mode 100644 index 0000000..67c99aa --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.html @@ -0,0 +1,54 @@ + + +
+
+ +
# Queries: {count}
+
Time span: {deltaTime} ({fromTime} - {toTime})
+
Avg. time/query: {avgTime}
+
+
+ + + + + + diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@
+ + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.html b/src/nl/astraeus/jdbc/web/page/LiveOverview.html new file mode 100644 index 0000000..67c99aa --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.html @@ -0,0 +1,54 @@ + + +
+
+ +
# Queries: {count}
+
Time span: {deltaTime} ({fromTime} - {toTime})
+
Avg. time/query: {avgTime}
+
+
+ + + + + + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.java b/src/nl/astraeus/jdbc/web/page/LiveOverview.java new file mode 100644 index 0000000..5133e39 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.java @@ -0,0 +1,160 @@ +package nl.astraeus.jdbc.web.page; + +import nl.astraeus.jdbc.JdbcLogger; +import nl.astraeus.jdbc.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * User: rnentjes + * Date: 4/12/12 + * Time: 9:16 PM + */ +public class LiveOverview extends TemplatePage { + private static Logger logger = LoggerFactory.getLogger(LiveOverview.class); + + boolean sortTotalCalls = true; + boolean sortAvgTime = false; + boolean sortTotalTime = false; + + @Override + public Page processGetRequest(String action, String value) { + Page result = this; + + if ("select".equals(action)) { + return new QueryDetail(this, Integer.parseInt(value)); + } + + return result; + } + + @Override + public Page processRequest(HttpServletRequest request) { + if ("sortTotalCalls".equals(request.getParameter("action"))) { + sortTotalCalls = true; + sortAvgTime = false; + sortTotalTime = false; + } else if ("sortAvgTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = true; + sortTotalTime = false; + } else if ("sortTotalTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = false; + sortTotalTime = true; + } else if ("record".equals(request.getParameter("action"))) { + JdbcLogger.get().switchRecording(); + } else if ("clear".equals(request.getParameter("action"))) { + JdbcLogger.get().clear(); + } else if ("select".equals(request.getParameter("action"))) { + String hash = request.getParameter("actionValue"); + + return new QueryDetail(this, Integer.parseInt(hash)); + } + + return this; + } + + @Override + public Map defineModel(HttpServletRequest request) { + Map result = new HashMap(); + + List entries = JdbcLogger.get().getEntries(); + + long fromTime = System.currentTimeMillis(); + long toTime = System.currentTimeMillis(); + long avgTime = 0; + + Map condensed = new HashMap(); + List list; + + if (!entries.isEmpty()) { + fromTime = entries.get(0).getTimestamp(); + toTime = entries.get(entries.size()-1).getTimestamp(); + + long total = 0; + + for (JdbcLogger.LogEntry le : entries) { + total += le.getNano(); + + JdbcLogger.LogEntry entry = condensed.get(le.getHash()); + + if (entry == null) { + entry = new JdbcLogger.LogEntry(le); + condensed.put(entry.getHash(), entry); + } else { + entry.addCount(le); + } + } + + avgTime = total / entries.size(); + } + + list = new LinkedList(condensed.values()); + + if (sortTotalCalls) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + return o2.getCount() - o1.getCount(); + } + }); + } else if (sortAvgTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + long n1 = o1.getNano() / o1.getCount(); + long n2 = o2.getNano() / o2.getCount(); + + if (n2 > n1) { + return 1; + } else if (n2 < n1) { + return -1; + } else { + return 0; + } + } + }); + } else if (sortTotalTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + if (o2.getNano() > o1.getNano()) { + return 1; + } else if (o2.getNano() < o1.getNano()) { + return -1; + } else { + return 0; + } + } + }); + } + + result.put("queries", list); + result.put("count", entries.size()); + + result.put("sortTotalCalls", sortTotalCalls); + result.put("sortAvgTime", sortAvgTime); + result.put("sortTotalTime", sortTotalTime); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + DateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); + + result.put("fromTime", dateFormatter.format(new Date(fromTime))); + result.put("toTime", dateFormatter.format(new Date(toTime))); + result.put("deltaTime", dateFormatter.format(new Date(toTime-fromTime))); + result.put("avgTime", Util.formatNano(avgTime)); + + result.put("recording", JdbcLogger.get().isRecording()); + + result.put("test", getTest()); + + return result; + } + + public String getTest() { + return "Test HaHa"; + } +} diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@
+ + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.html b/src/nl/astraeus/jdbc/web/page/LiveOverview.html new file mode 100644 index 0000000..67c99aa --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.html @@ -0,0 +1,54 @@ + + +
+
+ +
# Queries: {count}
+
Time span: {deltaTime} ({fromTime} - {toTime})
+
Avg. time/query: {avgTime}
+
+
+ + + + + + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.java b/src/nl/astraeus/jdbc/web/page/LiveOverview.java new file mode 100644 index 0000000..5133e39 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.java @@ -0,0 +1,160 @@ +package nl.astraeus.jdbc.web.page; + +import nl.astraeus.jdbc.JdbcLogger; +import nl.astraeus.jdbc.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * User: rnentjes + * Date: 4/12/12 + * Time: 9:16 PM + */ +public class LiveOverview extends TemplatePage { + private static Logger logger = LoggerFactory.getLogger(LiveOverview.class); + + boolean sortTotalCalls = true; + boolean sortAvgTime = false; + boolean sortTotalTime = false; + + @Override + public Page processGetRequest(String action, String value) { + Page result = this; + + if ("select".equals(action)) { + return new QueryDetail(this, Integer.parseInt(value)); + } + + return result; + } + + @Override + public Page processRequest(HttpServletRequest request) { + if ("sortTotalCalls".equals(request.getParameter("action"))) { + sortTotalCalls = true; + sortAvgTime = false; + sortTotalTime = false; + } else if ("sortAvgTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = true; + sortTotalTime = false; + } else if ("sortTotalTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = false; + sortTotalTime = true; + } else if ("record".equals(request.getParameter("action"))) { + JdbcLogger.get().switchRecording(); + } else if ("clear".equals(request.getParameter("action"))) { + JdbcLogger.get().clear(); + } else if ("select".equals(request.getParameter("action"))) { + String hash = request.getParameter("actionValue"); + + return new QueryDetail(this, Integer.parseInt(hash)); + } + + return this; + } + + @Override + public Map defineModel(HttpServletRequest request) { + Map result = new HashMap(); + + List entries = JdbcLogger.get().getEntries(); + + long fromTime = System.currentTimeMillis(); + long toTime = System.currentTimeMillis(); + long avgTime = 0; + + Map condensed = new HashMap(); + List list; + + if (!entries.isEmpty()) { + fromTime = entries.get(0).getTimestamp(); + toTime = entries.get(entries.size()-1).getTimestamp(); + + long total = 0; + + for (JdbcLogger.LogEntry le : entries) { + total += le.getNano(); + + JdbcLogger.LogEntry entry = condensed.get(le.getHash()); + + if (entry == null) { + entry = new JdbcLogger.LogEntry(le); + condensed.put(entry.getHash(), entry); + } else { + entry.addCount(le); + } + } + + avgTime = total / entries.size(); + } + + list = new LinkedList(condensed.values()); + + if (sortTotalCalls) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + return o2.getCount() - o1.getCount(); + } + }); + } else if (sortAvgTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + long n1 = o1.getNano() / o1.getCount(); + long n2 = o2.getNano() / o2.getCount(); + + if (n2 > n1) { + return 1; + } else if (n2 < n1) { + return -1; + } else { + return 0; + } + } + }); + } else if (sortTotalTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + if (o2.getNano() > o1.getNano()) { + return 1; + } else if (o2.getNano() < o1.getNano()) { + return -1; + } else { + return 0; + } + } + }); + } + + result.put("queries", list); + result.put("count", entries.size()); + + result.put("sortTotalCalls", sortTotalCalls); + result.put("sortAvgTime", sortAvgTime); + result.put("sortTotalTime", sortTotalTime); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + DateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); + + result.put("fromTime", dateFormatter.format(new Date(fromTime))); + result.put("toTime", dateFormatter.format(new Date(toTime))); + result.put("deltaTime", dateFormatter.format(new Date(toTime-fromTime))); + result.put("avgTime", Util.formatNano(avgTime)); + + result.put("recording", JdbcLogger.get().isRecording()); + + result.put("test", getTest()); + + return result; + } + + public String getTest() { + return "Test HaHa"; + } +} diff --git a/src/nl/astraeus/jdbc/web/page/Login.html b/src/nl/astraeus/jdbc/web/page/Login.html index 1be0ee2..57d7fcf 100644 --- a/src/nl/astraeus/jdbc/web/page/Login.html +++ b/src/nl/astraeus/jdbc/web/page/Login.html @@ -23,6 +23,6 @@
- Login + Login
\ No newline at end of file diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@
+ + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.html b/src/nl/astraeus/jdbc/web/page/LiveOverview.html new file mode 100644 index 0000000..67c99aa --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.html @@ -0,0 +1,54 @@ + + +
+
+ +
# Queries: {count}
+
Time span: {deltaTime} ({fromTime} - {toTime})
+
Avg. time/query: {avgTime}
+
+
+ + + + + + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.java b/src/nl/astraeus/jdbc/web/page/LiveOverview.java new file mode 100644 index 0000000..5133e39 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.java @@ -0,0 +1,160 @@ +package nl.astraeus.jdbc.web.page; + +import nl.astraeus.jdbc.JdbcLogger; +import nl.astraeus.jdbc.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * User: rnentjes + * Date: 4/12/12 + * Time: 9:16 PM + */ +public class LiveOverview extends TemplatePage { + private static Logger logger = LoggerFactory.getLogger(LiveOverview.class); + + boolean sortTotalCalls = true; + boolean sortAvgTime = false; + boolean sortTotalTime = false; + + @Override + public Page processGetRequest(String action, String value) { + Page result = this; + + if ("select".equals(action)) { + return new QueryDetail(this, Integer.parseInt(value)); + } + + return result; + } + + @Override + public Page processRequest(HttpServletRequest request) { + if ("sortTotalCalls".equals(request.getParameter("action"))) { + sortTotalCalls = true; + sortAvgTime = false; + sortTotalTime = false; + } else if ("sortAvgTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = true; + sortTotalTime = false; + } else if ("sortTotalTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = false; + sortTotalTime = true; + } else if ("record".equals(request.getParameter("action"))) { + JdbcLogger.get().switchRecording(); + } else if ("clear".equals(request.getParameter("action"))) { + JdbcLogger.get().clear(); + } else if ("select".equals(request.getParameter("action"))) { + String hash = request.getParameter("actionValue"); + + return new QueryDetail(this, Integer.parseInt(hash)); + } + + return this; + } + + @Override + public Map defineModel(HttpServletRequest request) { + Map result = new HashMap(); + + List entries = JdbcLogger.get().getEntries(); + + long fromTime = System.currentTimeMillis(); + long toTime = System.currentTimeMillis(); + long avgTime = 0; + + Map condensed = new HashMap(); + List list; + + if (!entries.isEmpty()) { + fromTime = entries.get(0).getTimestamp(); + toTime = entries.get(entries.size()-1).getTimestamp(); + + long total = 0; + + for (JdbcLogger.LogEntry le : entries) { + total += le.getNano(); + + JdbcLogger.LogEntry entry = condensed.get(le.getHash()); + + if (entry == null) { + entry = new JdbcLogger.LogEntry(le); + condensed.put(entry.getHash(), entry); + } else { + entry.addCount(le); + } + } + + avgTime = total / entries.size(); + } + + list = new LinkedList(condensed.values()); + + if (sortTotalCalls) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + return o2.getCount() - o1.getCount(); + } + }); + } else if (sortAvgTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + long n1 = o1.getNano() / o1.getCount(); + long n2 = o2.getNano() / o2.getCount(); + + if (n2 > n1) { + return 1; + } else if (n2 < n1) { + return -1; + } else { + return 0; + } + } + }); + } else if (sortTotalTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + if (o2.getNano() > o1.getNano()) { + return 1; + } else if (o2.getNano() < o1.getNano()) { + return -1; + } else { + return 0; + } + } + }); + } + + result.put("queries", list); + result.put("count", entries.size()); + + result.put("sortTotalCalls", sortTotalCalls); + result.put("sortAvgTime", sortAvgTime); + result.put("sortTotalTime", sortTotalTime); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + DateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); + + result.put("fromTime", dateFormatter.format(new Date(fromTime))); + result.put("toTime", dateFormatter.format(new Date(toTime))); + result.put("deltaTime", dateFormatter.format(new Date(toTime-fromTime))); + result.put("avgTime", Util.formatNano(avgTime)); + + result.put("recording", JdbcLogger.get().isRecording()); + + result.put("test", getTest()); + + return result; + } + + public String getTest() { + return "Test HaHa"; + } +} diff --git a/src/nl/astraeus/jdbc/web/page/Login.html b/src/nl/astraeus/jdbc/web/page/Login.html index 1be0ee2..57d7fcf 100644 --- a/src/nl/astraeus/jdbc/web/page/Login.html +++ b/src/nl/astraeus/jdbc/web/page/Login.html @@ -23,6 +23,6 @@
- Login + Login
\ No newline at end of file diff --git a/src/nl/astraeus/jdbc/web/page/Menu.html b/src/nl/astraeus/jdbc/web/page/Menu.html index 3e8d139..4c21bfb 100644 --- a/src/nl/astraeus/jdbc/web/page/Menu.html +++ b/src/nl/astraeus/jdbc/web/page/Menu.html @@ -9,13 +9,16 @@ Simple JDBC Statistics
- Login + Login
\ No newline at end of file diff --git a/src/nl/astraeus/jdbc/web/page/Menu.html b/src/nl/astraeus/jdbc/web/page/Menu.html index 3e8d139..4c21bfb 100644 --- a/src/nl/astraeus/jdbc/web/page/Menu.html +++ b/src/nl/astraeus/jdbc/web/page/Menu.html @@ -9,13 +9,16 @@ Simple JDBC Statistics @@ -45,7 +45,7 @@ {each(queries as q)} - + diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.html b/src/nl/astraeus/jdbc/web/page/LiveOverview.html new file mode 100644 index 0000000..67c99aa --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.html @@ -0,0 +1,54 @@ + + +
+
+ +
# Queries: {count}
+
Time span: {deltaTime} ({fromTime} - {toTime})
+
Avg. time/query: {avgTime}
+
+
+ + + + + + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.java b/src/nl/astraeus/jdbc/web/page/LiveOverview.java new file mode 100644 index 0000000..5133e39 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.java @@ -0,0 +1,160 @@ +package nl.astraeus.jdbc.web.page; + +import nl.astraeus.jdbc.JdbcLogger; +import nl.astraeus.jdbc.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * User: rnentjes + * Date: 4/12/12 + * Time: 9:16 PM + */ +public class LiveOverview extends TemplatePage { + private static Logger logger = LoggerFactory.getLogger(LiveOverview.class); + + boolean sortTotalCalls = true; + boolean sortAvgTime = false; + boolean sortTotalTime = false; + + @Override + public Page processGetRequest(String action, String value) { + Page result = this; + + if ("select".equals(action)) { + return new QueryDetail(this, Integer.parseInt(value)); + } + + return result; + } + + @Override + public Page processRequest(HttpServletRequest request) { + if ("sortTotalCalls".equals(request.getParameter("action"))) { + sortTotalCalls = true; + sortAvgTime = false; + sortTotalTime = false; + } else if ("sortAvgTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = true; + sortTotalTime = false; + } else if ("sortTotalTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = false; + sortTotalTime = true; + } else if ("record".equals(request.getParameter("action"))) { + JdbcLogger.get().switchRecording(); + } else if ("clear".equals(request.getParameter("action"))) { + JdbcLogger.get().clear(); + } else if ("select".equals(request.getParameter("action"))) { + String hash = request.getParameter("actionValue"); + + return new QueryDetail(this, Integer.parseInt(hash)); + } + + return this; + } + + @Override + public Map defineModel(HttpServletRequest request) { + Map result = new HashMap(); + + List entries = JdbcLogger.get().getEntries(); + + long fromTime = System.currentTimeMillis(); + long toTime = System.currentTimeMillis(); + long avgTime = 0; + + Map condensed = new HashMap(); + List list; + + if (!entries.isEmpty()) { + fromTime = entries.get(0).getTimestamp(); + toTime = entries.get(entries.size()-1).getTimestamp(); + + long total = 0; + + for (JdbcLogger.LogEntry le : entries) { + total += le.getNano(); + + JdbcLogger.LogEntry entry = condensed.get(le.getHash()); + + if (entry == null) { + entry = new JdbcLogger.LogEntry(le); + condensed.put(entry.getHash(), entry); + } else { + entry.addCount(le); + } + } + + avgTime = total / entries.size(); + } + + list = new LinkedList(condensed.values()); + + if (sortTotalCalls) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + return o2.getCount() - o1.getCount(); + } + }); + } else if (sortAvgTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + long n1 = o1.getNano() / o1.getCount(); + long n2 = o2.getNano() / o2.getCount(); + + if (n2 > n1) { + return 1; + } else if (n2 < n1) { + return -1; + } else { + return 0; + } + } + }); + } else if (sortTotalTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + if (o2.getNano() > o1.getNano()) { + return 1; + } else if (o2.getNano() < o1.getNano()) { + return -1; + } else { + return 0; + } + } + }); + } + + result.put("queries", list); + result.put("count", entries.size()); + + result.put("sortTotalCalls", sortTotalCalls); + result.put("sortAvgTime", sortAvgTime); + result.put("sortTotalTime", sortTotalTime); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + DateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); + + result.put("fromTime", dateFormatter.format(new Date(fromTime))); + result.put("toTime", dateFormatter.format(new Date(toTime))); + result.put("deltaTime", dateFormatter.format(new Date(toTime-fromTime))); + result.put("avgTime", Util.formatNano(avgTime)); + + result.put("recording", JdbcLogger.get().isRecording()); + + result.put("test", getTest()); + + return result; + } + + public String getTest() { + return "Test HaHa"; + } +} diff --git a/src/nl/astraeus/jdbc/web/page/Login.html b/src/nl/astraeus/jdbc/web/page/Login.html index 1be0ee2..57d7fcf 100644 --- a/src/nl/astraeus/jdbc/web/page/Login.html +++ b/src/nl/astraeus/jdbc/web/page/Login.html @@ -23,6 +23,6 @@
- Login + Login
\ No newline at end of file diff --git a/src/nl/astraeus/jdbc/web/page/Menu.html b/src/nl/astraeus/jdbc/web/page/Menu.html index 3e8d139..4c21bfb 100644 --- a/src/nl/astraeus/jdbc/web/page/Menu.html +++ b/src/nl/astraeus/jdbc/web/page/Menu.html @@ -9,13 +9,16 @@ Simple JDBC Statistics
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.formattedTimestamp} {q.threadId} {q.type.description}
@@ -45,7 +45,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.html b/src/nl/astraeus/jdbc/web/page/QueryOverview.html index 9dd140f..b52b2c4 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.html +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.html @@ -1,5 +1,5 @@
@@ -10,17 +10,17 @@
Avg. time/query: {avgTime}
- Clear + Clear
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.formattedTimestamp} {q.threadId} {q.type.description}
@@ -36,7 +36,7 @@ {each(queries as q)} - + diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.html b/src/nl/astraeus/jdbc/web/page/LiveOverview.html new file mode 100644 index 0000000..67c99aa --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.html @@ -0,0 +1,54 @@ + + +
+
+ +
# Queries: {count}
+
Time span: {deltaTime} ({fromTime} - {toTime})
+
Avg. time/query: {avgTime}
+
+
+ + + + + + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.java b/src/nl/astraeus/jdbc/web/page/LiveOverview.java new file mode 100644 index 0000000..5133e39 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.java @@ -0,0 +1,160 @@ +package nl.astraeus.jdbc.web.page; + +import nl.astraeus.jdbc.JdbcLogger; +import nl.astraeus.jdbc.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * User: rnentjes + * Date: 4/12/12 + * Time: 9:16 PM + */ +public class LiveOverview extends TemplatePage { + private static Logger logger = LoggerFactory.getLogger(LiveOverview.class); + + boolean sortTotalCalls = true; + boolean sortAvgTime = false; + boolean sortTotalTime = false; + + @Override + public Page processGetRequest(String action, String value) { + Page result = this; + + if ("select".equals(action)) { + return new QueryDetail(this, Integer.parseInt(value)); + } + + return result; + } + + @Override + public Page processRequest(HttpServletRequest request) { + if ("sortTotalCalls".equals(request.getParameter("action"))) { + sortTotalCalls = true; + sortAvgTime = false; + sortTotalTime = false; + } else if ("sortAvgTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = true; + sortTotalTime = false; + } else if ("sortTotalTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = false; + sortTotalTime = true; + } else if ("record".equals(request.getParameter("action"))) { + JdbcLogger.get().switchRecording(); + } else if ("clear".equals(request.getParameter("action"))) { + JdbcLogger.get().clear(); + } else if ("select".equals(request.getParameter("action"))) { + String hash = request.getParameter("actionValue"); + + return new QueryDetail(this, Integer.parseInt(hash)); + } + + return this; + } + + @Override + public Map defineModel(HttpServletRequest request) { + Map result = new HashMap(); + + List entries = JdbcLogger.get().getEntries(); + + long fromTime = System.currentTimeMillis(); + long toTime = System.currentTimeMillis(); + long avgTime = 0; + + Map condensed = new HashMap(); + List list; + + if (!entries.isEmpty()) { + fromTime = entries.get(0).getTimestamp(); + toTime = entries.get(entries.size()-1).getTimestamp(); + + long total = 0; + + for (JdbcLogger.LogEntry le : entries) { + total += le.getNano(); + + JdbcLogger.LogEntry entry = condensed.get(le.getHash()); + + if (entry == null) { + entry = new JdbcLogger.LogEntry(le); + condensed.put(entry.getHash(), entry); + } else { + entry.addCount(le); + } + } + + avgTime = total / entries.size(); + } + + list = new LinkedList(condensed.values()); + + if (sortTotalCalls) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + return o2.getCount() - o1.getCount(); + } + }); + } else if (sortAvgTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + long n1 = o1.getNano() / o1.getCount(); + long n2 = o2.getNano() / o2.getCount(); + + if (n2 > n1) { + return 1; + } else if (n2 < n1) { + return -1; + } else { + return 0; + } + } + }); + } else if (sortTotalTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + if (o2.getNano() > o1.getNano()) { + return 1; + } else if (o2.getNano() < o1.getNano()) { + return -1; + } else { + return 0; + } + } + }); + } + + result.put("queries", list); + result.put("count", entries.size()); + + result.put("sortTotalCalls", sortTotalCalls); + result.put("sortAvgTime", sortAvgTime); + result.put("sortTotalTime", sortTotalTime); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + DateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); + + result.put("fromTime", dateFormatter.format(new Date(fromTime))); + result.put("toTime", dateFormatter.format(new Date(toTime))); + result.put("deltaTime", dateFormatter.format(new Date(toTime-fromTime))); + result.put("avgTime", Util.formatNano(avgTime)); + + result.put("recording", JdbcLogger.get().isRecording()); + + result.put("test", getTest()); + + return result; + } + + public String getTest() { + return "Test HaHa"; + } +} diff --git a/src/nl/astraeus/jdbc/web/page/Login.html b/src/nl/astraeus/jdbc/web/page/Login.html index 1be0ee2..57d7fcf 100644 --- a/src/nl/astraeus/jdbc/web/page/Login.html +++ b/src/nl/astraeus/jdbc/web/page/Login.html @@ -23,6 +23,6 @@
- Login + Login
\ No newline at end of file diff --git a/src/nl/astraeus/jdbc/web/page/Menu.html b/src/nl/astraeus/jdbc/web/page/Menu.html index 3e8d139..4c21bfb 100644 --- a/src/nl/astraeus/jdbc/web/page/Menu.html +++ b/src/nl/astraeus/jdbc/web/page/Menu.html @@ -9,13 +9,16 @@ Simple JDBC Statistics
{q.total} {q.formattedNano} {q.count}
@@ -45,7 +45,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.html b/src/nl/astraeus/jdbc/web/page/QueryOverview.html index 9dd140f..b52b2c4 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.html +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.html @@ -1,5 +1,5 @@
@@ -10,17 +10,17 @@
Avg. time/query: {avgTime}
- Clear + Clear
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.formattedTimestamp} {q.threadId} {q.type.description}
@@ -36,7 +36,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.java b/src/nl/astraeus/jdbc/web/page/QueryOverview.java index f2a1c46..3c7e20b 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.java +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.java @@ -149,8 +149,12 @@ result.put("recording", JdbcLogger.get().isRecording()); + result.put("test", getTest()); return result; } + public String getTest() { + return "Test HaHa"; + } } diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.html b/src/nl/astraeus/jdbc/web/page/LiveOverview.html new file mode 100644 index 0000000..67c99aa --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.html @@ -0,0 +1,54 @@ + + +
+
+ +
# Queries: {count}
+
Time span: {deltaTime} ({fromTime} - {toTime})
+
Avg. time/query: {avgTime}
+
+
+ + + + + + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.java b/src/nl/astraeus/jdbc/web/page/LiveOverview.java new file mode 100644 index 0000000..5133e39 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.java @@ -0,0 +1,160 @@ +package nl.astraeus.jdbc.web.page; + +import nl.astraeus.jdbc.JdbcLogger; +import nl.astraeus.jdbc.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * User: rnentjes + * Date: 4/12/12 + * Time: 9:16 PM + */ +public class LiveOverview extends TemplatePage { + private static Logger logger = LoggerFactory.getLogger(LiveOverview.class); + + boolean sortTotalCalls = true; + boolean sortAvgTime = false; + boolean sortTotalTime = false; + + @Override + public Page processGetRequest(String action, String value) { + Page result = this; + + if ("select".equals(action)) { + return new QueryDetail(this, Integer.parseInt(value)); + } + + return result; + } + + @Override + public Page processRequest(HttpServletRequest request) { + if ("sortTotalCalls".equals(request.getParameter("action"))) { + sortTotalCalls = true; + sortAvgTime = false; + sortTotalTime = false; + } else if ("sortAvgTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = true; + sortTotalTime = false; + } else if ("sortTotalTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = false; + sortTotalTime = true; + } else if ("record".equals(request.getParameter("action"))) { + JdbcLogger.get().switchRecording(); + } else if ("clear".equals(request.getParameter("action"))) { + JdbcLogger.get().clear(); + } else if ("select".equals(request.getParameter("action"))) { + String hash = request.getParameter("actionValue"); + + return new QueryDetail(this, Integer.parseInt(hash)); + } + + return this; + } + + @Override + public Map defineModel(HttpServletRequest request) { + Map result = new HashMap(); + + List entries = JdbcLogger.get().getEntries(); + + long fromTime = System.currentTimeMillis(); + long toTime = System.currentTimeMillis(); + long avgTime = 0; + + Map condensed = new HashMap(); + List list; + + if (!entries.isEmpty()) { + fromTime = entries.get(0).getTimestamp(); + toTime = entries.get(entries.size()-1).getTimestamp(); + + long total = 0; + + for (JdbcLogger.LogEntry le : entries) { + total += le.getNano(); + + JdbcLogger.LogEntry entry = condensed.get(le.getHash()); + + if (entry == null) { + entry = new JdbcLogger.LogEntry(le); + condensed.put(entry.getHash(), entry); + } else { + entry.addCount(le); + } + } + + avgTime = total / entries.size(); + } + + list = new LinkedList(condensed.values()); + + if (sortTotalCalls) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + return o2.getCount() - o1.getCount(); + } + }); + } else if (sortAvgTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + long n1 = o1.getNano() / o1.getCount(); + long n2 = o2.getNano() / o2.getCount(); + + if (n2 > n1) { + return 1; + } else if (n2 < n1) { + return -1; + } else { + return 0; + } + } + }); + } else if (sortTotalTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + if (o2.getNano() > o1.getNano()) { + return 1; + } else if (o2.getNano() < o1.getNano()) { + return -1; + } else { + return 0; + } + } + }); + } + + result.put("queries", list); + result.put("count", entries.size()); + + result.put("sortTotalCalls", sortTotalCalls); + result.put("sortAvgTime", sortAvgTime); + result.put("sortTotalTime", sortTotalTime); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + DateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); + + result.put("fromTime", dateFormatter.format(new Date(fromTime))); + result.put("toTime", dateFormatter.format(new Date(toTime))); + result.put("deltaTime", dateFormatter.format(new Date(toTime-fromTime))); + result.put("avgTime", Util.formatNano(avgTime)); + + result.put("recording", JdbcLogger.get().isRecording()); + + result.put("test", getTest()); + + return result; + } + + public String getTest() { + return "Test HaHa"; + } +} diff --git a/src/nl/astraeus/jdbc/web/page/Login.html b/src/nl/astraeus/jdbc/web/page/Login.html index 1be0ee2..57d7fcf 100644 --- a/src/nl/astraeus/jdbc/web/page/Login.html +++ b/src/nl/astraeus/jdbc/web/page/Login.html @@ -23,6 +23,6 @@
- Login + Login
\ No newline at end of file diff --git a/src/nl/astraeus/jdbc/web/page/Menu.html b/src/nl/astraeus/jdbc/web/page/Menu.html index 3e8d139..4c21bfb 100644 --- a/src/nl/astraeus/jdbc/web/page/Menu.html +++ b/src/nl/astraeus/jdbc/web/page/Menu.html @@ -9,13 +9,16 @@ Simple JDBC Statistics
{q.total} {q.formattedNano} {q.count}
@@ -45,7 +45,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.html b/src/nl/astraeus/jdbc/web/page/QueryOverview.html index 9dd140f..b52b2c4 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.html +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.html @@ -1,5 +1,5 @@
@@ -10,17 +10,17 @@
Avg. time/query: {avgTime}
- Clear + Clear
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.formattedTimestamp} {q.threadId} {q.type.description}
@@ -36,7 +36,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.java b/src/nl/astraeus/jdbc/web/page/QueryOverview.java index f2a1c46..3c7e20b 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.java +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.java @@ -149,8 +149,12 @@ result.put("recording", JdbcLogger.get().isRecording()); + result.put("test", getTest()); return result; } + public String getTest() { + return "Test HaHa"; + } } diff --git a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html index 68c4c77..4c1a56a 100644 --- a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html +++ b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html @@ -29,6 +29,6 @@
- Save + Save
diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.html b/src/nl/astraeus/jdbc/web/page/LiveOverview.html new file mode 100644 index 0000000..67c99aa --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.html @@ -0,0 +1,54 @@ + + +
+
+ +
# Queries: {count}
+
Time span: {deltaTime} ({fromTime} - {toTime})
+
Avg. time/query: {avgTime}
+
+
+ + + + + + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.java b/src/nl/astraeus/jdbc/web/page/LiveOverview.java new file mode 100644 index 0000000..5133e39 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.java @@ -0,0 +1,160 @@ +package nl.astraeus.jdbc.web.page; + +import nl.astraeus.jdbc.JdbcLogger; +import nl.astraeus.jdbc.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * User: rnentjes + * Date: 4/12/12 + * Time: 9:16 PM + */ +public class LiveOverview extends TemplatePage { + private static Logger logger = LoggerFactory.getLogger(LiveOverview.class); + + boolean sortTotalCalls = true; + boolean sortAvgTime = false; + boolean sortTotalTime = false; + + @Override + public Page processGetRequest(String action, String value) { + Page result = this; + + if ("select".equals(action)) { + return new QueryDetail(this, Integer.parseInt(value)); + } + + return result; + } + + @Override + public Page processRequest(HttpServletRequest request) { + if ("sortTotalCalls".equals(request.getParameter("action"))) { + sortTotalCalls = true; + sortAvgTime = false; + sortTotalTime = false; + } else if ("sortAvgTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = true; + sortTotalTime = false; + } else if ("sortTotalTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = false; + sortTotalTime = true; + } else if ("record".equals(request.getParameter("action"))) { + JdbcLogger.get().switchRecording(); + } else if ("clear".equals(request.getParameter("action"))) { + JdbcLogger.get().clear(); + } else if ("select".equals(request.getParameter("action"))) { + String hash = request.getParameter("actionValue"); + + return new QueryDetail(this, Integer.parseInt(hash)); + } + + return this; + } + + @Override + public Map defineModel(HttpServletRequest request) { + Map result = new HashMap(); + + List entries = JdbcLogger.get().getEntries(); + + long fromTime = System.currentTimeMillis(); + long toTime = System.currentTimeMillis(); + long avgTime = 0; + + Map condensed = new HashMap(); + List list; + + if (!entries.isEmpty()) { + fromTime = entries.get(0).getTimestamp(); + toTime = entries.get(entries.size()-1).getTimestamp(); + + long total = 0; + + for (JdbcLogger.LogEntry le : entries) { + total += le.getNano(); + + JdbcLogger.LogEntry entry = condensed.get(le.getHash()); + + if (entry == null) { + entry = new JdbcLogger.LogEntry(le); + condensed.put(entry.getHash(), entry); + } else { + entry.addCount(le); + } + } + + avgTime = total / entries.size(); + } + + list = new LinkedList(condensed.values()); + + if (sortTotalCalls) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + return o2.getCount() - o1.getCount(); + } + }); + } else if (sortAvgTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + long n1 = o1.getNano() / o1.getCount(); + long n2 = o2.getNano() / o2.getCount(); + + if (n2 > n1) { + return 1; + } else if (n2 < n1) { + return -1; + } else { + return 0; + } + } + }); + } else if (sortTotalTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + if (o2.getNano() > o1.getNano()) { + return 1; + } else if (o2.getNano() < o1.getNano()) { + return -1; + } else { + return 0; + } + } + }); + } + + result.put("queries", list); + result.put("count", entries.size()); + + result.put("sortTotalCalls", sortTotalCalls); + result.put("sortAvgTime", sortAvgTime); + result.put("sortTotalTime", sortTotalTime); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + DateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); + + result.put("fromTime", dateFormatter.format(new Date(fromTime))); + result.put("toTime", dateFormatter.format(new Date(toTime))); + result.put("deltaTime", dateFormatter.format(new Date(toTime-fromTime))); + result.put("avgTime", Util.formatNano(avgTime)); + + result.put("recording", JdbcLogger.get().isRecording()); + + result.put("test", getTest()); + + return result; + } + + public String getTest() { + return "Test HaHa"; + } +} diff --git a/src/nl/astraeus/jdbc/web/page/Login.html b/src/nl/astraeus/jdbc/web/page/Login.html index 1be0ee2..57d7fcf 100644 --- a/src/nl/astraeus/jdbc/web/page/Login.html +++ b/src/nl/astraeus/jdbc/web/page/Login.html @@ -23,6 +23,6 @@
- Login + Login
\ No newline at end of file diff --git a/src/nl/astraeus/jdbc/web/page/Menu.html b/src/nl/astraeus/jdbc/web/page/Menu.html index 3e8d139..4c21bfb 100644 --- a/src/nl/astraeus/jdbc/web/page/Menu.html +++ b/src/nl/astraeus/jdbc/web/page/Menu.html @@ -9,13 +9,16 @@ Simple JDBC Statistics
{q.total} {q.formattedNano} {q.count}
@@ -45,7 +45,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.html b/src/nl/astraeus/jdbc/web/page/QueryOverview.html index 9dd140f..b52b2c4 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.html +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.html @@ -1,5 +1,5 @@
@@ -10,17 +10,17 @@
Avg. time/query: {avgTime}
- Clear + Clear
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.formattedTimestamp} {q.threadId} {q.type.description}
@@ -36,7 +36,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.java b/src/nl/astraeus/jdbc/web/page/QueryOverview.java index f2a1c46..3c7e20b 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.java +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.java @@ -149,8 +149,12 @@ result.put("recording", JdbcLogger.get().isRecording()); + result.put("test", getTest()); return result; } + public String getTest() { + return "Test HaHa"; + } } diff --git a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html index 68c4c77..4c1a56a 100644 --- a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html +++ b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html @@ -29,6 +29,6 @@
- Save + Save
diff --git a/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html b/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html index d9b93d1..5f28fa2 100644 --- a/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html +++ b/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html @@ -4,7 +4,7 @@
- Back + Back
diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.html b/src/nl/astraeus/jdbc/web/page/LiveOverview.html new file mode 100644 index 0000000..67c99aa --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.html @@ -0,0 +1,54 @@ + + +
+
+ +
# Queries: {count}
+
Time span: {deltaTime} ({fromTime} - {toTime})
+
Avg. time/query: {avgTime}
+
+
+ + + + + + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.java b/src/nl/astraeus/jdbc/web/page/LiveOverview.java new file mode 100644 index 0000000..5133e39 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.java @@ -0,0 +1,160 @@ +package nl.astraeus.jdbc.web.page; + +import nl.astraeus.jdbc.JdbcLogger; +import nl.astraeus.jdbc.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * User: rnentjes + * Date: 4/12/12 + * Time: 9:16 PM + */ +public class LiveOverview extends TemplatePage { + private static Logger logger = LoggerFactory.getLogger(LiveOverview.class); + + boolean sortTotalCalls = true; + boolean sortAvgTime = false; + boolean sortTotalTime = false; + + @Override + public Page processGetRequest(String action, String value) { + Page result = this; + + if ("select".equals(action)) { + return new QueryDetail(this, Integer.parseInt(value)); + } + + return result; + } + + @Override + public Page processRequest(HttpServletRequest request) { + if ("sortTotalCalls".equals(request.getParameter("action"))) { + sortTotalCalls = true; + sortAvgTime = false; + sortTotalTime = false; + } else if ("sortAvgTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = true; + sortTotalTime = false; + } else if ("sortTotalTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = false; + sortTotalTime = true; + } else if ("record".equals(request.getParameter("action"))) { + JdbcLogger.get().switchRecording(); + } else if ("clear".equals(request.getParameter("action"))) { + JdbcLogger.get().clear(); + } else if ("select".equals(request.getParameter("action"))) { + String hash = request.getParameter("actionValue"); + + return new QueryDetail(this, Integer.parseInt(hash)); + } + + return this; + } + + @Override + public Map defineModel(HttpServletRequest request) { + Map result = new HashMap(); + + List entries = JdbcLogger.get().getEntries(); + + long fromTime = System.currentTimeMillis(); + long toTime = System.currentTimeMillis(); + long avgTime = 0; + + Map condensed = new HashMap(); + List list; + + if (!entries.isEmpty()) { + fromTime = entries.get(0).getTimestamp(); + toTime = entries.get(entries.size()-1).getTimestamp(); + + long total = 0; + + for (JdbcLogger.LogEntry le : entries) { + total += le.getNano(); + + JdbcLogger.LogEntry entry = condensed.get(le.getHash()); + + if (entry == null) { + entry = new JdbcLogger.LogEntry(le); + condensed.put(entry.getHash(), entry); + } else { + entry.addCount(le); + } + } + + avgTime = total / entries.size(); + } + + list = new LinkedList(condensed.values()); + + if (sortTotalCalls) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + return o2.getCount() - o1.getCount(); + } + }); + } else if (sortAvgTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + long n1 = o1.getNano() / o1.getCount(); + long n2 = o2.getNano() / o2.getCount(); + + if (n2 > n1) { + return 1; + } else if (n2 < n1) { + return -1; + } else { + return 0; + } + } + }); + } else if (sortTotalTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + if (o2.getNano() > o1.getNano()) { + return 1; + } else if (o2.getNano() < o1.getNano()) { + return -1; + } else { + return 0; + } + } + }); + } + + result.put("queries", list); + result.put("count", entries.size()); + + result.put("sortTotalCalls", sortTotalCalls); + result.put("sortAvgTime", sortAvgTime); + result.put("sortTotalTime", sortTotalTime); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + DateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); + + result.put("fromTime", dateFormatter.format(new Date(fromTime))); + result.put("toTime", dateFormatter.format(new Date(toTime))); + result.put("deltaTime", dateFormatter.format(new Date(toTime-fromTime))); + result.put("avgTime", Util.formatNano(avgTime)); + + result.put("recording", JdbcLogger.get().isRecording()); + + result.put("test", getTest()); + + return result; + } + + public String getTest() { + return "Test HaHa"; + } +} diff --git a/src/nl/astraeus/jdbc/web/page/Login.html b/src/nl/astraeus/jdbc/web/page/Login.html index 1be0ee2..57d7fcf 100644 --- a/src/nl/astraeus/jdbc/web/page/Login.html +++ b/src/nl/astraeus/jdbc/web/page/Login.html @@ -23,6 +23,6 @@
- Login + Login
\ No newline at end of file diff --git a/src/nl/astraeus/jdbc/web/page/Menu.html b/src/nl/astraeus/jdbc/web/page/Menu.html index 3e8d139..4c21bfb 100644 --- a/src/nl/astraeus/jdbc/web/page/Menu.html +++ b/src/nl/astraeus/jdbc/web/page/Menu.html @@ -9,13 +9,16 @@ Simple JDBC Statistics
{q.total} {q.formattedNano} {q.count}
@@ -45,7 +45,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.html b/src/nl/astraeus/jdbc/web/page/QueryOverview.html index 9dd140f..b52b2c4 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.html +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.html @@ -1,5 +1,5 @@
@@ -10,17 +10,17 @@
Avg. time/query: {avgTime}
- Clear + Clear
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.formattedTimestamp} {q.threadId} {q.type.description}
@@ -36,7 +36,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.java b/src/nl/astraeus/jdbc/web/page/QueryOverview.java index f2a1c46..3c7e20b 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.java +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.java @@ -149,8 +149,12 @@ result.put("recording", JdbcLogger.get().isRecording()); + result.put("test", getTest()); return result; } + public String getTest() { + return "Test HaHa"; + } } diff --git a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html index 68c4c77..4c1a56a 100644 --- a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html +++ b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html @@ -29,6 +29,6 @@
- Save + Save
diff --git a/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html b/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html index d9b93d1..5f28fa2 100644 --- a/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html +++ b/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html @@ -4,7 +4,7 @@
- Back + Back
diff --git a/src/nl/astraeus/jdbc/web/page/TemplatePage.java b/src/nl/astraeus/jdbc/web/page/TemplatePage.java index 35f04a8..f1d4bd6 100644 --- a/src/nl/astraeus/jdbc/web/page/TemplatePage.java +++ b/src/nl/astraeus/jdbc/web/page/TemplatePage.java @@ -45,7 +45,7 @@ private static Map templateCache = new HashMap(); public synchronized static SimpleTemplate getSimpleTemplate(Class cls) { - SimpleTemplate result = templateCache.get(cls); + SimpleTemplate result = null; //templateCache.get(cls); if (result == null) { InputStream in = null; diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.html b/src/nl/astraeus/jdbc/web/page/LiveOverview.html new file mode 100644 index 0000000..67c99aa --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.html @@ -0,0 +1,54 @@ + + +
+
+ +
# Queries: {count}
+
Time span: {deltaTime} ({fromTime} - {toTime})
+
Avg. time/query: {avgTime}
+
+
+ + + + + + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.java b/src/nl/astraeus/jdbc/web/page/LiveOverview.java new file mode 100644 index 0000000..5133e39 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.java @@ -0,0 +1,160 @@ +package nl.astraeus.jdbc.web.page; + +import nl.astraeus.jdbc.JdbcLogger; +import nl.astraeus.jdbc.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * User: rnentjes + * Date: 4/12/12 + * Time: 9:16 PM + */ +public class LiveOverview extends TemplatePage { + private static Logger logger = LoggerFactory.getLogger(LiveOverview.class); + + boolean sortTotalCalls = true; + boolean sortAvgTime = false; + boolean sortTotalTime = false; + + @Override + public Page processGetRequest(String action, String value) { + Page result = this; + + if ("select".equals(action)) { + return new QueryDetail(this, Integer.parseInt(value)); + } + + return result; + } + + @Override + public Page processRequest(HttpServletRequest request) { + if ("sortTotalCalls".equals(request.getParameter("action"))) { + sortTotalCalls = true; + sortAvgTime = false; + sortTotalTime = false; + } else if ("sortAvgTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = true; + sortTotalTime = false; + } else if ("sortTotalTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = false; + sortTotalTime = true; + } else if ("record".equals(request.getParameter("action"))) { + JdbcLogger.get().switchRecording(); + } else if ("clear".equals(request.getParameter("action"))) { + JdbcLogger.get().clear(); + } else if ("select".equals(request.getParameter("action"))) { + String hash = request.getParameter("actionValue"); + + return new QueryDetail(this, Integer.parseInt(hash)); + } + + return this; + } + + @Override + public Map defineModel(HttpServletRequest request) { + Map result = new HashMap(); + + List entries = JdbcLogger.get().getEntries(); + + long fromTime = System.currentTimeMillis(); + long toTime = System.currentTimeMillis(); + long avgTime = 0; + + Map condensed = new HashMap(); + List list; + + if (!entries.isEmpty()) { + fromTime = entries.get(0).getTimestamp(); + toTime = entries.get(entries.size()-1).getTimestamp(); + + long total = 0; + + for (JdbcLogger.LogEntry le : entries) { + total += le.getNano(); + + JdbcLogger.LogEntry entry = condensed.get(le.getHash()); + + if (entry == null) { + entry = new JdbcLogger.LogEntry(le); + condensed.put(entry.getHash(), entry); + } else { + entry.addCount(le); + } + } + + avgTime = total / entries.size(); + } + + list = new LinkedList(condensed.values()); + + if (sortTotalCalls) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + return o2.getCount() - o1.getCount(); + } + }); + } else if (sortAvgTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + long n1 = o1.getNano() / o1.getCount(); + long n2 = o2.getNano() / o2.getCount(); + + if (n2 > n1) { + return 1; + } else if (n2 < n1) { + return -1; + } else { + return 0; + } + } + }); + } else if (sortTotalTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + if (o2.getNano() > o1.getNano()) { + return 1; + } else if (o2.getNano() < o1.getNano()) { + return -1; + } else { + return 0; + } + } + }); + } + + result.put("queries", list); + result.put("count", entries.size()); + + result.put("sortTotalCalls", sortTotalCalls); + result.put("sortAvgTime", sortAvgTime); + result.put("sortTotalTime", sortTotalTime); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + DateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); + + result.put("fromTime", dateFormatter.format(new Date(fromTime))); + result.put("toTime", dateFormatter.format(new Date(toTime))); + result.put("deltaTime", dateFormatter.format(new Date(toTime-fromTime))); + result.put("avgTime", Util.formatNano(avgTime)); + + result.put("recording", JdbcLogger.get().isRecording()); + + result.put("test", getTest()); + + return result; + } + + public String getTest() { + return "Test HaHa"; + } +} diff --git a/src/nl/astraeus/jdbc/web/page/Login.html b/src/nl/astraeus/jdbc/web/page/Login.html index 1be0ee2..57d7fcf 100644 --- a/src/nl/astraeus/jdbc/web/page/Login.html +++ b/src/nl/astraeus/jdbc/web/page/Login.html @@ -23,6 +23,6 @@
- Login + Login
\ No newline at end of file diff --git a/src/nl/astraeus/jdbc/web/page/Menu.html b/src/nl/astraeus/jdbc/web/page/Menu.html index 3e8d139..4c21bfb 100644 --- a/src/nl/astraeus/jdbc/web/page/Menu.html +++ b/src/nl/astraeus/jdbc/web/page/Menu.html @@ -9,13 +9,16 @@ Simple JDBC Statistics
{q.total} {q.formattedNano} {q.count}
@@ -45,7 +45,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.html b/src/nl/astraeus/jdbc/web/page/QueryOverview.html index 9dd140f..b52b2c4 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.html +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.html @@ -1,5 +1,5 @@
@@ -10,17 +10,17 @@
Avg. time/query: {avgTime}
- Clear + Clear
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.formattedTimestamp} {q.threadId} {q.type.description}
@@ -36,7 +36,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.java b/src/nl/astraeus/jdbc/web/page/QueryOverview.java index f2a1c46..3c7e20b 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.java +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.java @@ -149,8 +149,12 @@ result.put("recording", JdbcLogger.get().isRecording()); + result.put("test", getTest()); return result; } + public String getTest() { + return "Test HaHa"; + } } diff --git a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html index 68c4c77..4c1a56a 100644 --- a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html +++ b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html @@ -29,6 +29,6 @@
- Save + Save
diff --git a/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html b/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html index d9b93d1..5f28fa2 100644 --- a/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html +++ b/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html @@ -4,7 +4,7 @@
- Back + Back
diff --git a/src/nl/astraeus/jdbc/web/page/TemplatePage.java b/src/nl/astraeus/jdbc/web/page/TemplatePage.java index 35f04a8..f1d4bd6 100644 --- a/src/nl/astraeus/jdbc/web/page/TemplatePage.java +++ b/src/nl/astraeus/jdbc/web/page/TemplatePage.java @@ -45,7 +45,7 @@ private static Map templateCache = new HashMap(); public synchronized static SimpleTemplate getSimpleTemplate(Class cls) { - SimpleTemplate result = templateCache.get(cls); + SimpleTemplate result = null; //templateCache.get(cls); if (result == null) { InputStream in = null; diff --git a/src/nl/astraeus/jdbc/web/page/TransactionDetail.html b/src/nl/astraeus/jdbc/web/page/TransactionDetail.html index 06c357b..af4b5be 100644 --- a/src/nl/astraeus/jdbc/web/page/TransactionDetail.html +++ b/src/nl/astraeus/jdbc/web/page/TransactionDetail.html @@ -4,7 +4,7 @@
- Back + Back
@@ -23,10 +23,10 @@
{q.total} {q.formattedNano} {q.count}
@@ -42,7 +42,7 @@ {each(transaction.queries as q)} - + diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.html b/src/nl/astraeus/jdbc/web/page/LiveOverview.html new file mode 100644 index 0000000..67c99aa --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.html @@ -0,0 +1,54 @@ + + +
+
+ +
# Queries: {count}
+
Time span: {deltaTime} ({fromTime} - {toTime})
+
Avg. time/query: {avgTime}
+
+
+ + + + + + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.java b/src/nl/astraeus/jdbc/web/page/LiveOverview.java new file mode 100644 index 0000000..5133e39 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.java @@ -0,0 +1,160 @@ +package nl.astraeus.jdbc.web.page; + +import nl.astraeus.jdbc.JdbcLogger; +import nl.astraeus.jdbc.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * User: rnentjes + * Date: 4/12/12 + * Time: 9:16 PM + */ +public class LiveOverview extends TemplatePage { + private static Logger logger = LoggerFactory.getLogger(LiveOverview.class); + + boolean sortTotalCalls = true; + boolean sortAvgTime = false; + boolean sortTotalTime = false; + + @Override + public Page processGetRequest(String action, String value) { + Page result = this; + + if ("select".equals(action)) { + return new QueryDetail(this, Integer.parseInt(value)); + } + + return result; + } + + @Override + public Page processRequest(HttpServletRequest request) { + if ("sortTotalCalls".equals(request.getParameter("action"))) { + sortTotalCalls = true; + sortAvgTime = false; + sortTotalTime = false; + } else if ("sortAvgTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = true; + sortTotalTime = false; + } else if ("sortTotalTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = false; + sortTotalTime = true; + } else if ("record".equals(request.getParameter("action"))) { + JdbcLogger.get().switchRecording(); + } else if ("clear".equals(request.getParameter("action"))) { + JdbcLogger.get().clear(); + } else if ("select".equals(request.getParameter("action"))) { + String hash = request.getParameter("actionValue"); + + return new QueryDetail(this, Integer.parseInt(hash)); + } + + return this; + } + + @Override + public Map defineModel(HttpServletRequest request) { + Map result = new HashMap(); + + List entries = JdbcLogger.get().getEntries(); + + long fromTime = System.currentTimeMillis(); + long toTime = System.currentTimeMillis(); + long avgTime = 0; + + Map condensed = new HashMap(); + List list; + + if (!entries.isEmpty()) { + fromTime = entries.get(0).getTimestamp(); + toTime = entries.get(entries.size()-1).getTimestamp(); + + long total = 0; + + for (JdbcLogger.LogEntry le : entries) { + total += le.getNano(); + + JdbcLogger.LogEntry entry = condensed.get(le.getHash()); + + if (entry == null) { + entry = new JdbcLogger.LogEntry(le); + condensed.put(entry.getHash(), entry); + } else { + entry.addCount(le); + } + } + + avgTime = total / entries.size(); + } + + list = new LinkedList(condensed.values()); + + if (sortTotalCalls) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + return o2.getCount() - o1.getCount(); + } + }); + } else if (sortAvgTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + long n1 = o1.getNano() / o1.getCount(); + long n2 = o2.getNano() / o2.getCount(); + + if (n2 > n1) { + return 1; + } else if (n2 < n1) { + return -1; + } else { + return 0; + } + } + }); + } else if (sortTotalTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + if (o2.getNano() > o1.getNano()) { + return 1; + } else if (o2.getNano() < o1.getNano()) { + return -1; + } else { + return 0; + } + } + }); + } + + result.put("queries", list); + result.put("count", entries.size()); + + result.put("sortTotalCalls", sortTotalCalls); + result.put("sortAvgTime", sortAvgTime); + result.put("sortTotalTime", sortTotalTime); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + DateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); + + result.put("fromTime", dateFormatter.format(new Date(fromTime))); + result.put("toTime", dateFormatter.format(new Date(toTime))); + result.put("deltaTime", dateFormatter.format(new Date(toTime-fromTime))); + result.put("avgTime", Util.formatNano(avgTime)); + + result.put("recording", JdbcLogger.get().isRecording()); + + result.put("test", getTest()); + + return result; + } + + public String getTest() { + return "Test HaHa"; + } +} diff --git a/src/nl/astraeus/jdbc/web/page/Login.html b/src/nl/astraeus/jdbc/web/page/Login.html index 1be0ee2..57d7fcf 100644 --- a/src/nl/astraeus/jdbc/web/page/Login.html +++ b/src/nl/astraeus/jdbc/web/page/Login.html @@ -23,6 +23,6 @@
- Login + Login
\ No newline at end of file diff --git a/src/nl/astraeus/jdbc/web/page/Menu.html b/src/nl/astraeus/jdbc/web/page/Menu.html index 3e8d139..4c21bfb 100644 --- a/src/nl/astraeus/jdbc/web/page/Menu.html +++ b/src/nl/astraeus/jdbc/web/page/Menu.html @@ -9,13 +9,16 @@ Simple JDBC Statistics
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.type} {q.formattedTimestamp} {q.formattedNano}
@@ -45,7 +45,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.html b/src/nl/astraeus/jdbc/web/page/QueryOverview.html index 9dd140f..b52b2c4 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.html +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.html @@ -1,5 +1,5 @@
@@ -10,17 +10,17 @@
Avg. time/query: {avgTime}
- Clear + Clear
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.formattedTimestamp} {q.threadId} {q.type.description}
@@ -36,7 +36,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.java b/src/nl/astraeus/jdbc/web/page/QueryOverview.java index f2a1c46..3c7e20b 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.java +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.java @@ -149,8 +149,12 @@ result.put("recording", JdbcLogger.get().isRecording()); + result.put("test", getTest()); return result; } + public String getTest() { + return "Test HaHa"; + } } diff --git a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html index 68c4c77..4c1a56a 100644 --- a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html +++ b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html @@ -29,6 +29,6 @@
- Save + Save
diff --git a/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html b/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html index d9b93d1..5f28fa2 100644 --- a/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html +++ b/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html @@ -4,7 +4,7 @@
- Back + Back
diff --git a/src/nl/astraeus/jdbc/web/page/TemplatePage.java b/src/nl/astraeus/jdbc/web/page/TemplatePage.java index 35f04a8..f1d4bd6 100644 --- a/src/nl/astraeus/jdbc/web/page/TemplatePage.java +++ b/src/nl/astraeus/jdbc/web/page/TemplatePage.java @@ -45,7 +45,7 @@ private static Map templateCache = new HashMap(); public synchronized static SimpleTemplate getSimpleTemplate(Class cls) { - SimpleTemplate result = templateCache.get(cls); + SimpleTemplate result = null; //templateCache.get(cls); if (result == null) { InputStream in = null; diff --git a/src/nl/astraeus/jdbc/web/page/TransactionDetail.html b/src/nl/astraeus/jdbc/web/page/TransactionDetail.html index 06c357b..af4b5be 100644 --- a/src/nl/astraeus/jdbc/web/page/TransactionDetail.html +++ b/src/nl/astraeus/jdbc/web/page/TransactionDetail.html @@ -4,7 +4,7 @@
- Back + Back
@@ -23,10 +23,10 @@
{q.total} {q.formattedNano} {q.count}
@@ -42,7 +42,7 @@ {each(transaction.queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/TransactionOverview.html b/src/nl/astraeus/jdbc/web/page/TransactionOverview.html index 629517b..08873a9 100644 --- a/src/nl/astraeus/jdbc/web/page/TransactionOverview.html +++ b/src/nl/astraeus/jdbc/web/page/TransactionOverview.html @@ -10,18 +10,18 @@
Avg. time/query: {avgTime}
- Clear + Clear
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.type} {q.formattedTimestamp} {q.formattedNano}
@@ -38,7 +38,7 @@ {each(transactions as t)} - + diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.html b/src/nl/astraeus/jdbc/web/page/LiveOverview.html new file mode 100644 index 0000000..67c99aa --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.html @@ -0,0 +1,54 @@ + + +
+
+ +
# Queries: {count}
+
Time span: {deltaTime} ({fromTime} - {toTime})
+
Avg. time/query: {avgTime}
+
+
+ + + + + + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.java b/src/nl/astraeus/jdbc/web/page/LiveOverview.java new file mode 100644 index 0000000..5133e39 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.java @@ -0,0 +1,160 @@ +package nl.astraeus.jdbc.web.page; + +import nl.astraeus.jdbc.JdbcLogger; +import nl.astraeus.jdbc.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * User: rnentjes + * Date: 4/12/12 + * Time: 9:16 PM + */ +public class LiveOverview extends TemplatePage { + private static Logger logger = LoggerFactory.getLogger(LiveOverview.class); + + boolean sortTotalCalls = true; + boolean sortAvgTime = false; + boolean sortTotalTime = false; + + @Override + public Page processGetRequest(String action, String value) { + Page result = this; + + if ("select".equals(action)) { + return new QueryDetail(this, Integer.parseInt(value)); + } + + return result; + } + + @Override + public Page processRequest(HttpServletRequest request) { + if ("sortTotalCalls".equals(request.getParameter("action"))) { + sortTotalCalls = true; + sortAvgTime = false; + sortTotalTime = false; + } else if ("sortAvgTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = true; + sortTotalTime = false; + } else if ("sortTotalTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = false; + sortTotalTime = true; + } else if ("record".equals(request.getParameter("action"))) { + JdbcLogger.get().switchRecording(); + } else if ("clear".equals(request.getParameter("action"))) { + JdbcLogger.get().clear(); + } else if ("select".equals(request.getParameter("action"))) { + String hash = request.getParameter("actionValue"); + + return new QueryDetail(this, Integer.parseInt(hash)); + } + + return this; + } + + @Override + public Map defineModel(HttpServletRequest request) { + Map result = new HashMap(); + + List entries = JdbcLogger.get().getEntries(); + + long fromTime = System.currentTimeMillis(); + long toTime = System.currentTimeMillis(); + long avgTime = 0; + + Map condensed = new HashMap(); + List list; + + if (!entries.isEmpty()) { + fromTime = entries.get(0).getTimestamp(); + toTime = entries.get(entries.size()-1).getTimestamp(); + + long total = 0; + + for (JdbcLogger.LogEntry le : entries) { + total += le.getNano(); + + JdbcLogger.LogEntry entry = condensed.get(le.getHash()); + + if (entry == null) { + entry = new JdbcLogger.LogEntry(le); + condensed.put(entry.getHash(), entry); + } else { + entry.addCount(le); + } + } + + avgTime = total / entries.size(); + } + + list = new LinkedList(condensed.values()); + + if (sortTotalCalls) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + return o2.getCount() - o1.getCount(); + } + }); + } else if (sortAvgTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + long n1 = o1.getNano() / o1.getCount(); + long n2 = o2.getNano() / o2.getCount(); + + if (n2 > n1) { + return 1; + } else if (n2 < n1) { + return -1; + } else { + return 0; + } + } + }); + } else if (sortTotalTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + if (o2.getNano() > o1.getNano()) { + return 1; + } else if (o2.getNano() < o1.getNano()) { + return -1; + } else { + return 0; + } + } + }); + } + + result.put("queries", list); + result.put("count", entries.size()); + + result.put("sortTotalCalls", sortTotalCalls); + result.put("sortAvgTime", sortAvgTime); + result.put("sortTotalTime", sortTotalTime); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + DateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); + + result.put("fromTime", dateFormatter.format(new Date(fromTime))); + result.put("toTime", dateFormatter.format(new Date(toTime))); + result.put("deltaTime", dateFormatter.format(new Date(toTime-fromTime))); + result.put("avgTime", Util.formatNano(avgTime)); + + result.put("recording", JdbcLogger.get().isRecording()); + + result.put("test", getTest()); + + return result; + } + + public String getTest() { + return "Test HaHa"; + } +} diff --git a/src/nl/astraeus/jdbc/web/page/Login.html b/src/nl/astraeus/jdbc/web/page/Login.html index 1be0ee2..57d7fcf 100644 --- a/src/nl/astraeus/jdbc/web/page/Login.html +++ b/src/nl/astraeus/jdbc/web/page/Login.html @@ -23,6 +23,6 @@
- Login + Login
\ No newline at end of file diff --git a/src/nl/astraeus/jdbc/web/page/Menu.html b/src/nl/astraeus/jdbc/web/page/Menu.html index 3e8d139..4c21bfb 100644 --- a/src/nl/astraeus/jdbc/web/page/Menu.html +++ b/src/nl/astraeus/jdbc/web/page/Menu.html @@ -9,13 +9,16 @@ Simple JDBC Statistics
{t.formattedTotalTime} {t.formattedQueryTime} {t.formattedAvgTime}
@@ -45,7 +45,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.html b/src/nl/astraeus/jdbc/web/page/QueryOverview.html index 9dd140f..b52b2c4 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.html +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.html @@ -1,5 +1,5 @@
@@ -10,17 +10,17 @@
Avg. time/query: {avgTime}
- Clear + Clear
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.formattedTimestamp} {q.threadId} {q.type.description}
@@ -36,7 +36,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.java b/src/nl/astraeus/jdbc/web/page/QueryOverview.java index f2a1c46..3c7e20b 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.java +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.java @@ -149,8 +149,12 @@ result.put("recording", JdbcLogger.get().isRecording()); + result.put("test", getTest()); return result; } + public String getTest() { + return "Test HaHa"; + } } diff --git a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html index 68c4c77..4c1a56a 100644 --- a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html +++ b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html @@ -29,6 +29,6 @@
- Save + Save
diff --git a/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html b/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html index d9b93d1..5f28fa2 100644 --- a/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html +++ b/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html @@ -4,7 +4,7 @@
- Back + Back
diff --git a/src/nl/astraeus/jdbc/web/page/TemplatePage.java b/src/nl/astraeus/jdbc/web/page/TemplatePage.java index 35f04a8..f1d4bd6 100644 --- a/src/nl/astraeus/jdbc/web/page/TemplatePage.java +++ b/src/nl/astraeus/jdbc/web/page/TemplatePage.java @@ -45,7 +45,7 @@ private static Map templateCache = new HashMap(); public synchronized static SimpleTemplate getSimpleTemplate(Class cls) { - SimpleTemplate result = templateCache.get(cls); + SimpleTemplate result = null; //templateCache.get(cls); if (result == null) { InputStream in = null; diff --git a/src/nl/astraeus/jdbc/web/page/TransactionDetail.html b/src/nl/astraeus/jdbc/web/page/TransactionDetail.html index 06c357b..af4b5be 100644 --- a/src/nl/astraeus/jdbc/web/page/TransactionDetail.html +++ b/src/nl/astraeus/jdbc/web/page/TransactionDetail.html @@ -4,7 +4,7 @@
- Back + Back
@@ -23,10 +23,10 @@
{q.total} {q.formattedNano} {q.count}
@@ -42,7 +42,7 @@ {each(transaction.queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/TransactionOverview.html b/src/nl/astraeus/jdbc/web/page/TransactionOverview.html index 629517b..08873a9 100644 --- a/src/nl/astraeus/jdbc/web/page/TransactionOverview.html +++ b/src/nl/astraeus/jdbc/web/page/TransactionOverview.html @@ -10,18 +10,18 @@
Avg. time/query: {avgTime}
- Clear + Clear
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.type} {q.formattedTimestamp} {q.formattedNano}
@@ -38,7 +38,7 @@ {each(transactions as t)} - + diff --git a/src/nl/astraeus/jdbc/web/resources/js/smoothie.js b/src/nl/astraeus/jdbc/web/resources/js/smoothie.js new file mode 100644 index 0000000..43f5739 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/resources/js/smoothie.js @@ -0,0 +1,301 @@ +// MIT License: +// +// Copyright (c) 2010-2011, Joe Walnes +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +/** + * Smoothie Charts - http://smoothiecharts.org/ + * (c) 2010-2012, Joe Walnes + * + * v1.0: Main charting library, by Joe Walnes + * v1.1: Auto scaling of axis, by Neil Dunn + * v1.2: fps (frames per second) option, by Mathias Petterson + * v1.3: Fix for divide by zero, by Paul Nikitochkin + * v1.4: Set minimum, top-scale padding, remove timeseries, add optional timer to reset bounds, by Kelley Reynolds + * v1.5: Set default frames per second to 50... smoother. + * .start(), .stop() methods for conserving CPU, by Dmitry Vyal + * options.iterpolation = 'bezier' or 'line', by Dmitry Vyal + * options.maxValue to fix scale, by Dmitry Vyal + * v1.6: minValue/maxValue will always get converted to floats, by Przemek Matylla + * v1.7: options.grid.fillStyle may be a transparent color, by Dmitry A. Shashkin + * Smooth rescaling, by Kostas Michalopoulos + */ + +function TimeSeries(options) { + options = options || {}; + options.resetBoundsInterval = options.resetBoundsInterval || 3000; // Reset the max/min bounds after this many milliseconds + options.resetBounds = options.resetBounds || true; // Enable or disable the resetBounds timer + this.options = options; + this.data = []; + + this.maxValue = Number.NaN; // The maximum value ever seen in this time series. + this.minValue = Number.NaN; // The minimum value ever seen in this time series. + + // Start a resetBounds Interval timer desired + if (options.resetBounds) { + this.boundsTimer = setInterval(function(thisObj) { thisObj.resetBounds(); }, options.resetBoundsInterval, this); + } +} + +// Reset the min and max for this timeseries so the graph rescales itself +TimeSeries.prototype.resetBounds = function() { + this.maxValue = Number.NaN; + this.minValue = Number.NaN; + for (var i = 0; i < this.data.length; i++) { + this.maxValue = !isNaN(this.maxValue) ? Math.max(this.maxValue, this.data[i][1]) : this.data[i][1]; + this.minValue = !isNaN(this.minValue) ? Math.min(this.minValue, this.data[i][1]) : this.data[i][1]; + } +}; + +TimeSeries.prototype.append = function(timestamp, value) { + this.data.push([timestamp, value]); + this.maxValue = !isNaN(this.maxValue) ? Math.max(this.maxValue, value) : value; + this.minValue = !isNaN(this.minValue) ? Math.min(this.minValue, value) : value; +}; + +function SmoothieChart(options) { + // Defaults + options = options || {}; + options.grid = options.grid || { fillStyle:'#000000', strokeStyle: '#777777', lineWidth: 1, millisPerLine: 1000, verticalSections: 2 }; + options.millisPerPixel = options.millisPerPixel || 20; + options.fps = options.fps || 50; + options.maxValueScale = options.maxValueScale || 1; + options.minValue = options.minValue; + options.maxValue = options.maxValue; + options.labels = options.labels || { fillStyle:'#ffffff' }; + options.interpolation = options.interpolation || "bezier"; + options.scaleSmoothing = options.scaleSmoothing || 0.125; + this.options = options; + this.seriesSet = []; + this.currentValueRange = 1; + this.currentVisMinValue = 0; +} + +SmoothieChart.prototype.addTimeSeries = function(timeSeries, options) { + this.seriesSet.push({timeSeries: timeSeries, options: options || {}}); +}; + +SmoothieChart.prototype.removeTimeSeries = function(timeSeries) { + this.seriesSet.splice(this.seriesSet.indexOf(timeSeries), 1); +}; + +SmoothieChart.prototype.streamTo = function(canvas, delay) { + var self = this; + this.render_on_tick = function() { + self.render(canvas, new Date().getTime() - (delay || 0)); + }; + + this.start(); +}; + +SmoothieChart.prototype.start = function() { + if (!this.timer) + this.timer = setInterval(this.render_on_tick, 1000/this.options.fps); +}; + +SmoothieChart.prototype.stop = function() { + if (this.timer) { + clearInterval(this.timer); + this.timer = undefined; + } +}; + +SmoothieChart.prototype.render = function(canvas, time) { + var canvasContext = canvas.getContext("2d"); + var options = this.options; + var dimensions = {top: 0, left: 0, width: canvas.clientWidth, height: canvas.clientHeight}; + + // Save the state of the canvas context, any transformations applied in this method + // will get removed from the stack at the end of this method when .restore() is called. + canvasContext.save(); + + // Round time down to pixel granularity, so motion appears smoother. + time = time - time % options.millisPerPixel; + + // Move the origin. + canvasContext.translate(dimensions.left, dimensions.top); + + // Create a clipped rectangle - anything we draw will be constrained to this rectangle. + // This prevents the occasional pixels from curves near the edges overrunning and creating + // screen cheese (that phrase should neeed no explanation). + canvasContext.beginPath(); + canvasContext.rect(0, 0, dimensions.width, dimensions.height); + canvasContext.clip(); + + // Clear the working area. + canvasContext.save(); + canvasContext.fillStyle = options.grid.fillStyle; + canvasContext.clearRect(0, 0, dimensions.width, dimensions.height); + canvasContext.fillRect(0, 0, dimensions.width, dimensions.height); + canvasContext.restore(); + + // Grid lines.... + canvasContext.save(); + canvasContext.lineWidth = options.grid.lineWidth || 1; + canvasContext.strokeStyle = options.grid.strokeStyle || '#ffffff'; + // Vertical (time) dividers. + if (options.grid.millisPerLine > 0) { + for (var t = time - (time % options.grid.millisPerLine); t >= time - (dimensions.width * options.millisPerPixel); t -= options.grid.millisPerLine) { + canvasContext.beginPath(); + var gx = Math.round(dimensions.width - ((time - t) / options.millisPerPixel)); + canvasContext.moveTo(gx, 0); + canvasContext.lineTo(gx, dimensions.height); + canvasContext.stroke(); + canvasContext.closePath(); + } + } + + // Horizontal (value) dividers. + for (var v = 1; v < options.grid.verticalSections; v++) { + var gy = Math.round(v * dimensions.height / options.grid.verticalSections); + canvasContext.beginPath(); + canvasContext.moveTo(0, gy); + canvasContext.lineTo(dimensions.width, gy); + canvasContext.stroke(); + canvasContext.closePath(); + } + // Bounding rectangle. + canvasContext.beginPath(); + canvasContext.strokeRect(0, 0, dimensions.width, dimensions.height); + canvasContext.closePath(); + canvasContext.restore(); + + // Calculate the current scale of the chart, from all time series. + var maxValue = Number.NaN; + var minValue = Number.NaN; + + for (var d = 0; d < this.seriesSet.length; d++) { + // TODO(ndunn): We could calculate / track these values as they stream in. + var timeSeries = this.seriesSet[d].timeSeries; + if (!isNaN(timeSeries.maxValue)) { + maxValue = !isNaN(maxValue) ? Math.max(maxValue, timeSeries.maxValue) : timeSeries.maxValue; + } + + if (!isNaN(timeSeries.minValue)) { + minValue = !isNaN(minValue) ? Math.min(minValue, timeSeries.minValue) : timeSeries.minValue; + } + } + + if (isNaN(maxValue) && isNaN(minValue)) { + return; + } + + // Scale the maxValue to add padding at the top if required + if (options.maxValue != null) + maxValue = options.maxValue; + else + maxValue = maxValue * options.maxValueScale; + // Set the minimum if we've specified one + if (options.minValue != null) + minValue = options.minValue; + var targetValueRange = maxValue - minValue; + this.currentValueRange += options.scaleSmoothing*(targetValueRange - this.currentValueRange); + this.currentVisMinValue += options.scaleSmoothing*(minValue - this.currentVisMinValue); + var valueRange = this.currentValueRange; + var visMinValue = this.currentVisMinValue; + + // For each data set... + for (var d = 0; d < this.seriesSet.length; d++) { + canvasContext.save(); + var timeSeries = this.seriesSet[d].timeSeries; + var dataSet = timeSeries.data; + var seriesOptions = this.seriesSet[d].options; + + // Delete old data that's moved off the left of the chart. + // We must always keep the last expired data point as we need this to draw the + // line that comes into the chart, but any points prior to that can be removed. + while (dataSet.length >= 2 && dataSet[1][0] < time - (dimensions.width * options.millisPerPixel)) { + dataSet.splice(0, 1); + } + + // Set style for this dataSet. + canvasContext.lineWidth = seriesOptions.lineWidth || 1; + canvasContext.fillStyle = seriesOptions.fillStyle; + canvasContext.strokeStyle = seriesOptions.strokeStyle || '#ffffff'; + // Draw the line... + canvasContext.beginPath(); + // Retain lastX, lastY for calculating the control points of bezier curves. + var firstX = 0, lastX = 0, lastY = 0; + for (var i = 0; i < dataSet.length; i++) { + // TODO: Deal with dataSet.length < 2. + var x = Math.round(dimensions.width - ((time - dataSet[i][0]) / options.millisPerPixel)); + var value = dataSet[i][1]; + var offset = value - visMinValue; + var scaledValue = dimensions.height - (valueRange ? Math.round((offset / valueRange) * dimensions.height) : 0); + var y = Math.max(Math.min(scaledValue, dimensions.height - 1), 1); // Ensure line is always on chart. + + if (i == 0) { + firstX = x; + canvasContext.moveTo(x, y); + } + // Great explanation of Bezier curves: http://en.wikipedia.org/wiki/B�zier_curve#Quadratic_curves + // + // Assuming A was the last point in the line plotted and B is the new point, + // we draw a curve with control points P and Q as below. + // + // A---P + // | + // | + // | + // Q---B + // + // Importantly, A and P are at the same y coordinate, as are B and Q. This is + // so adjacent curves appear to flow as one. + // + else { + switch (options.interpolation) { + case "line": + canvasContext.lineTo(x,y); + break; + case "bezier": + default: + canvasContext.bezierCurveTo( // startPoint (A) is implicit from last iteration of loop + Math.round((lastX + x) / 2), lastY, // controlPoint1 (P) + Math.round((lastX + x)) / 2, y, // controlPoint2 (Q) + x, y); // endPoint (B) + break; + } + } + + lastX = x, lastY = y; + } + if (dataSet.length > 0 && seriesOptions.fillStyle) { + // Close up the fill region. + canvasContext.lineTo(dimensions.width + seriesOptions.lineWidth + 1, lastY); + canvasContext.lineTo(dimensions.width + seriesOptions.lineWidth + 1, dimensions.height + seriesOptions.lineWidth + 1); + canvasContext.lineTo(firstX, dimensions.height + seriesOptions.lineWidth); + canvasContext.fill(); + } + canvasContext.stroke(); + canvasContext.closePath(); + canvasContext.restore(); + } + + // Draw the axis values on the chart. + if (!options.labels.disabled) { + canvasContext.fillStyle = options.labels.fillStyle; + var maxValueString = parseFloat(maxValue).toFixed(2); + var minValueString = parseFloat(minValue).toFixed(2); + canvasContext.fillText(maxValueString, dimensions.width - canvasContext.measureText(maxValueString).width - 2, 10); + canvasContext.fillText(minValueString, dimensions.width - canvasContext.measureText(minValueString).width - 2, dimensions.height - 2); + } + + canvasContext.restore(); // See .save() above. +} diff --git a/.idea/libraries/junit_4_5.xml b/.idea/libraries/junit_4_5.xml new file mode 100644 index 0000000..a3352c2 --- /dev/null +++ b/.idea/libraries/junit_4_5.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 385878f..c490a2d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,6 @@ + @@ -7,7 +8,7 @@ http://www.w3.org/1999/xhtml - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 73ff239..7185899 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 275077f..bb8b683 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,8 @@ + + diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml index 3c8910a..7ebf932 100644 --- a/Simple-jdbc-statistics.iml +++ b/Simple-jdbc-statistics.iml @@ -18,6 +18,8 @@ + + diff --git a/lib/ssr-0.3.jar b/lib/ssr-0.3.jar deleted file mode 100644 index d02a311..0000000 --- a/lib/ssr-0.3.jar +++ /dev/null Binary files differ diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar deleted file mode 100644 index 37c9e38..0000000 --- a/lib/vst-0.4.jar +++ /dev/null Binary files differ diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java index c00a661..e424856 100644 --- a/src/nl/astraeus/jdbc/Driver.java +++ b/src/nl/astraeus/jdbc/Driver.java @@ -105,6 +105,8 @@ server.addServlet(new JdbcStatisticsServlet(), "/*"); server.addServlet(new ResourceServlet(), "/resources/*"); + server.setNumberOfConnections(5); + server.start(); started = true; diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java index 96690ba..553477d 100644 --- a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java +++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.security.auth.login.LoginContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -98,6 +97,8 @@ } else if (!(page instanceof Login)) { if (page == null || "menumain".equals(req.getParameter("action"))) { page = new QueryOverview(); + } else if ("menulive".equals(req.getParameter("action"))) { + page = new LiveOverview(); } else if ("menutransactions".equals(req.getParameter("action"))) { page = new TransactionOverview(); } else if ("menusettings".equals(req.getParameter("action"))) { diff --git a/src/nl/astraeus/jdbc/web/head.html b/src/nl/astraeus/jdbc/web/head.html index c99b11e..39ee2f7 100644 --- a/src/nl/astraeus/jdbc/web/head.html +++ b/src/nl/astraeus/jdbc/web/head.html @@ -20,30 +20,49 @@ + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.html b/src/nl/astraeus/jdbc/web/page/LiveOverview.html new file mode 100644 index 0000000..67c99aa --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.html @@ -0,0 +1,54 @@ + + +
+
+ +
# Queries: {count}
+
Time span: {deltaTime} ({fromTime} - {toTime})
+
Avg. time/query: {avgTime}
+
+
+ + + + + + diff --git a/src/nl/astraeus/jdbc/web/page/LiveOverview.java b/src/nl/astraeus/jdbc/web/page/LiveOverview.java new file mode 100644 index 0000000..5133e39 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/page/LiveOverview.java @@ -0,0 +1,160 @@ +package nl.astraeus.jdbc.web.page; + +import nl.astraeus.jdbc.JdbcLogger; +import nl.astraeus.jdbc.util.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * User: rnentjes + * Date: 4/12/12 + * Time: 9:16 PM + */ +public class LiveOverview extends TemplatePage { + private static Logger logger = LoggerFactory.getLogger(LiveOverview.class); + + boolean sortTotalCalls = true; + boolean sortAvgTime = false; + boolean sortTotalTime = false; + + @Override + public Page processGetRequest(String action, String value) { + Page result = this; + + if ("select".equals(action)) { + return new QueryDetail(this, Integer.parseInt(value)); + } + + return result; + } + + @Override + public Page processRequest(HttpServletRequest request) { + if ("sortTotalCalls".equals(request.getParameter("action"))) { + sortTotalCalls = true; + sortAvgTime = false; + sortTotalTime = false; + } else if ("sortAvgTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = true; + sortTotalTime = false; + } else if ("sortTotalTime".equals(request.getParameter("action"))) { + sortTotalCalls = false; + sortAvgTime = false; + sortTotalTime = true; + } else if ("record".equals(request.getParameter("action"))) { + JdbcLogger.get().switchRecording(); + } else if ("clear".equals(request.getParameter("action"))) { + JdbcLogger.get().clear(); + } else if ("select".equals(request.getParameter("action"))) { + String hash = request.getParameter("actionValue"); + + return new QueryDetail(this, Integer.parseInt(hash)); + } + + return this; + } + + @Override + public Map defineModel(HttpServletRequest request) { + Map result = new HashMap(); + + List entries = JdbcLogger.get().getEntries(); + + long fromTime = System.currentTimeMillis(); + long toTime = System.currentTimeMillis(); + long avgTime = 0; + + Map condensed = new HashMap(); + List list; + + if (!entries.isEmpty()) { + fromTime = entries.get(0).getTimestamp(); + toTime = entries.get(entries.size()-1).getTimestamp(); + + long total = 0; + + for (JdbcLogger.LogEntry le : entries) { + total += le.getNano(); + + JdbcLogger.LogEntry entry = condensed.get(le.getHash()); + + if (entry == null) { + entry = new JdbcLogger.LogEntry(le); + condensed.put(entry.getHash(), entry); + } else { + entry.addCount(le); + } + } + + avgTime = total / entries.size(); + } + + list = new LinkedList(condensed.values()); + + if (sortTotalCalls) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + return o2.getCount() - o1.getCount(); + } + }); + } else if (sortAvgTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + long n1 = o1.getNano() / o1.getCount(); + long n2 = o2.getNano() / o2.getCount(); + + if (n2 > n1) { + return 1; + } else if (n2 < n1) { + return -1; + } else { + return 0; + } + } + }); + } else if (sortTotalTime) { + Collections.sort(list, new Comparator() { + public int compare(JdbcLogger.LogEntry o1, JdbcLogger.LogEntry o2) { + if (o2.getNano() > o1.getNano()) { + return 1; + } else if (o2.getNano() < o1.getNano()) { + return -1; + } else { + return 0; + } + } + }); + } + + result.put("queries", list); + result.put("count", entries.size()); + + result.put("sortTotalCalls", sortTotalCalls); + result.put("sortAvgTime", sortAvgTime); + result.put("sortTotalTime", sortTotalTime); + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + DateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); + + result.put("fromTime", dateFormatter.format(new Date(fromTime))); + result.put("toTime", dateFormatter.format(new Date(toTime))); + result.put("deltaTime", dateFormatter.format(new Date(toTime-fromTime))); + result.put("avgTime", Util.formatNano(avgTime)); + + result.put("recording", JdbcLogger.get().isRecording()); + + result.put("test", getTest()); + + return result; + } + + public String getTest() { + return "Test HaHa"; + } +} diff --git a/src/nl/astraeus/jdbc/web/page/Login.html b/src/nl/astraeus/jdbc/web/page/Login.html index 1be0ee2..57d7fcf 100644 --- a/src/nl/astraeus/jdbc/web/page/Login.html +++ b/src/nl/astraeus/jdbc/web/page/Login.html @@ -23,6 +23,6 @@
- Login + Login
\ No newline at end of file diff --git a/src/nl/astraeus/jdbc/web/page/Menu.html b/src/nl/astraeus/jdbc/web/page/Menu.html index 3e8d139..4c21bfb 100644 --- a/src/nl/astraeus/jdbc/web/page/Menu.html +++ b/src/nl/astraeus/jdbc/web/page/Menu.html @@ -9,13 +9,16 @@ Simple JDBC Statistics
{t.formattedTotalTime} {t.formattedQueryTime} {t.formattedAvgTime}
@@ -45,7 +45,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.html b/src/nl/astraeus/jdbc/web/page/QueryOverview.html index 9dd140f..b52b2c4 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.html +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.html @@ -1,5 +1,5 @@
@@ -10,17 +10,17 @@
Avg. time/query: {avgTime}
- Clear + Clear
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.formattedTimestamp} {q.threadId} {q.type.description}
@@ -36,7 +36,7 @@ {each(queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/QueryOverview.java b/src/nl/astraeus/jdbc/web/page/QueryOverview.java index f2a1c46..3c7e20b 100644 --- a/src/nl/astraeus/jdbc/web/page/QueryOverview.java +++ b/src/nl/astraeus/jdbc/web/page/QueryOverview.java @@ -149,8 +149,12 @@ result.put("recording", JdbcLogger.get().isRecording()); + result.put("test", getTest()); return result; } + public String getTest() { + return "Test HaHa"; + } } diff --git a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html index 68c4c77..4c1a56a 100644 --- a/src/nl/astraeus/jdbc/web/page/SettingsOverview.html +++ b/src/nl/astraeus/jdbc/web/page/SettingsOverview.html @@ -29,6 +29,6 @@
- Save + Save
diff --git a/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html b/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html index d9b93d1..5f28fa2 100644 --- a/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html +++ b/src/nl/astraeus/jdbc/web/page/ShowStacktrace.html @@ -4,7 +4,7 @@
- Back + Back
diff --git a/src/nl/astraeus/jdbc/web/page/TemplatePage.java b/src/nl/astraeus/jdbc/web/page/TemplatePage.java index 35f04a8..f1d4bd6 100644 --- a/src/nl/astraeus/jdbc/web/page/TemplatePage.java +++ b/src/nl/astraeus/jdbc/web/page/TemplatePage.java @@ -45,7 +45,7 @@ private static Map templateCache = new HashMap(); public synchronized static SimpleTemplate getSimpleTemplate(Class cls) { - SimpleTemplate result = templateCache.get(cls); + SimpleTemplate result = null; //templateCache.get(cls); if (result == null) { InputStream in = null; diff --git a/src/nl/astraeus/jdbc/web/page/TransactionDetail.html b/src/nl/astraeus/jdbc/web/page/TransactionDetail.html index 06c357b..af4b5be 100644 --- a/src/nl/astraeus/jdbc/web/page/TransactionDetail.html +++ b/src/nl/astraeus/jdbc/web/page/TransactionDetail.html @@ -4,7 +4,7 @@
- Back + Back
@@ -23,10 +23,10 @@
{q.total} {q.formattedNano} {q.count}
@@ -42,7 +42,7 @@ {each(transaction.queries as q)} - + diff --git a/src/nl/astraeus/jdbc/web/page/TransactionOverview.html b/src/nl/astraeus/jdbc/web/page/TransactionOverview.html index 629517b..08873a9 100644 --- a/src/nl/astraeus/jdbc/web/page/TransactionOverview.html +++ b/src/nl/astraeus/jdbc/web/page/TransactionOverview.html @@ -10,18 +10,18 @@
Avg. time/query: {avgTime}
- Clear + Clear
{if(q.stackTrace)}{/if}{if(q.stackTrace)}{/if} {q.type} {q.formattedTimestamp} {q.formattedNano}
@@ -38,7 +38,7 @@ {each(transactions as t)} - + diff --git a/src/nl/astraeus/jdbc/web/resources/js/smoothie.js b/src/nl/astraeus/jdbc/web/resources/js/smoothie.js new file mode 100644 index 0000000..43f5739 --- /dev/null +++ b/src/nl/astraeus/jdbc/web/resources/js/smoothie.js @@ -0,0 +1,301 @@ +// MIT License: +// +// Copyright (c) 2010-2011, Joe Walnes +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +/** + * Smoothie Charts - http://smoothiecharts.org/ + * (c) 2010-2012, Joe Walnes + * + * v1.0: Main charting library, by Joe Walnes + * v1.1: Auto scaling of axis, by Neil Dunn + * v1.2: fps (frames per second) option, by Mathias Petterson + * v1.3: Fix for divide by zero, by Paul Nikitochkin + * v1.4: Set minimum, top-scale padding, remove timeseries, add optional timer to reset bounds, by Kelley Reynolds + * v1.5: Set default frames per second to 50... smoother. + * .start(), .stop() methods for conserving CPU, by Dmitry Vyal + * options.iterpolation = 'bezier' or 'line', by Dmitry Vyal + * options.maxValue to fix scale, by Dmitry Vyal + * v1.6: minValue/maxValue will always get converted to floats, by Przemek Matylla + * v1.7: options.grid.fillStyle may be a transparent color, by Dmitry A. Shashkin + * Smooth rescaling, by Kostas Michalopoulos + */ + +function TimeSeries(options) { + options = options || {}; + options.resetBoundsInterval = options.resetBoundsInterval || 3000; // Reset the max/min bounds after this many milliseconds + options.resetBounds = options.resetBounds || true; // Enable or disable the resetBounds timer + this.options = options; + this.data = []; + + this.maxValue = Number.NaN; // The maximum value ever seen in this time series. + this.minValue = Number.NaN; // The minimum value ever seen in this time series. + + // Start a resetBounds Interval timer desired + if (options.resetBounds) { + this.boundsTimer = setInterval(function(thisObj) { thisObj.resetBounds(); }, options.resetBoundsInterval, this); + } +} + +// Reset the min and max for this timeseries so the graph rescales itself +TimeSeries.prototype.resetBounds = function() { + this.maxValue = Number.NaN; + this.minValue = Number.NaN; + for (var i = 0; i < this.data.length; i++) { + this.maxValue = !isNaN(this.maxValue) ? Math.max(this.maxValue, this.data[i][1]) : this.data[i][1]; + this.minValue = !isNaN(this.minValue) ? Math.min(this.minValue, this.data[i][1]) : this.data[i][1]; + } +}; + +TimeSeries.prototype.append = function(timestamp, value) { + this.data.push([timestamp, value]); + this.maxValue = !isNaN(this.maxValue) ? Math.max(this.maxValue, value) : value; + this.minValue = !isNaN(this.minValue) ? Math.min(this.minValue, value) : value; +}; + +function SmoothieChart(options) { + // Defaults + options = options || {}; + options.grid = options.grid || { fillStyle:'#000000', strokeStyle: '#777777', lineWidth: 1, millisPerLine: 1000, verticalSections: 2 }; + options.millisPerPixel = options.millisPerPixel || 20; + options.fps = options.fps || 50; + options.maxValueScale = options.maxValueScale || 1; + options.minValue = options.minValue; + options.maxValue = options.maxValue; + options.labels = options.labels || { fillStyle:'#ffffff' }; + options.interpolation = options.interpolation || "bezier"; + options.scaleSmoothing = options.scaleSmoothing || 0.125; + this.options = options; + this.seriesSet = []; + this.currentValueRange = 1; + this.currentVisMinValue = 0; +} + +SmoothieChart.prototype.addTimeSeries = function(timeSeries, options) { + this.seriesSet.push({timeSeries: timeSeries, options: options || {}}); +}; + +SmoothieChart.prototype.removeTimeSeries = function(timeSeries) { + this.seriesSet.splice(this.seriesSet.indexOf(timeSeries), 1); +}; + +SmoothieChart.prototype.streamTo = function(canvas, delay) { + var self = this; + this.render_on_tick = function() { + self.render(canvas, new Date().getTime() - (delay || 0)); + }; + + this.start(); +}; + +SmoothieChart.prototype.start = function() { + if (!this.timer) + this.timer = setInterval(this.render_on_tick, 1000/this.options.fps); +}; + +SmoothieChart.prototype.stop = function() { + if (this.timer) { + clearInterval(this.timer); + this.timer = undefined; + } +}; + +SmoothieChart.prototype.render = function(canvas, time) { + var canvasContext = canvas.getContext("2d"); + var options = this.options; + var dimensions = {top: 0, left: 0, width: canvas.clientWidth, height: canvas.clientHeight}; + + // Save the state of the canvas context, any transformations applied in this method + // will get removed from the stack at the end of this method when .restore() is called. + canvasContext.save(); + + // Round time down to pixel granularity, so motion appears smoother. + time = time - time % options.millisPerPixel; + + // Move the origin. + canvasContext.translate(dimensions.left, dimensions.top); + + // Create a clipped rectangle - anything we draw will be constrained to this rectangle. + // This prevents the occasional pixels from curves near the edges overrunning and creating + // screen cheese (that phrase should neeed no explanation). + canvasContext.beginPath(); + canvasContext.rect(0, 0, dimensions.width, dimensions.height); + canvasContext.clip(); + + // Clear the working area. + canvasContext.save(); + canvasContext.fillStyle = options.grid.fillStyle; + canvasContext.clearRect(0, 0, dimensions.width, dimensions.height); + canvasContext.fillRect(0, 0, dimensions.width, dimensions.height); + canvasContext.restore(); + + // Grid lines.... + canvasContext.save(); + canvasContext.lineWidth = options.grid.lineWidth || 1; + canvasContext.strokeStyle = options.grid.strokeStyle || '#ffffff'; + // Vertical (time) dividers. + if (options.grid.millisPerLine > 0) { + for (var t = time - (time % options.grid.millisPerLine); t >= time - (dimensions.width * options.millisPerPixel); t -= options.grid.millisPerLine) { + canvasContext.beginPath(); + var gx = Math.round(dimensions.width - ((time - t) / options.millisPerPixel)); + canvasContext.moveTo(gx, 0); + canvasContext.lineTo(gx, dimensions.height); + canvasContext.stroke(); + canvasContext.closePath(); + } + } + + // Horizontal (value) dividers. + for (var v = 1; v < options.grid.verticalSections; v++) { + var gy = Math.round(v * dimensions.height / options.grid.verticalSections); + canvasContext.beginPath(); + canvasContext.moveTo(0, gy); + canvasContext.lineTo(dimensions.width, gy); + canvasContext.stroke(); + canvasContext.closePath(); + } + // Bounding rectangle. + canvasContext.beginPath(); + canvasContext.strokeRect(0, 0, dimensions.width, dimensions.height); + canvasContext.closePath(); + canvasContext.restore(); + + // Calculate the current scale of the chart, from all time series. + var maxValue = Number.NaN; + var minValue = Number.NaN; + + for (var d = 0; d < this.seriesSet.length; d++) { + // TODO(ndunn): We could calculate / track these values as they stream in. + var timeSeries = this.seriesSet[d].timeSeries; + if (!isNaN(timeSeries.maxValue)) { + maxValue = !isNaN(maxValue) ? Math.max(maxValue, timeSeries.maxValue) : timeSeries.maxValue; + } + + if (!isNaN(timeSeries.minValue)) { + minValue = !isNaN(minValue) ? Math.min(minValue, timeSeries.minValue) : timeSeries.minValue; + } + } + + if (isNaN(maxValue) && isNaN(minValue)) { + return; + } + + // Scale the maxValue to add padding at the top if required + if (options.maxValue != null) + maxValue = options.maxValue; + else + maxValue = maxValue * options.maxValueScale; + // Set the minimum if we've specified one + if (options.minValue != null) + minValue = options.minValue; + var targetValueRange = maxValue - minValue; + this.currentValueRange += options.scaleSmoothing*(targetValueRange - this.currentValueRange); + this.currentVisMinValue += options.scaleSmoothing*(minValue - this.currentVisMinValue); + var valueRange = this.currentValueRange; + var visMinValue = this.currentVisMinValue; + + // For each data set... + for (var d = 0; d < this.seriesSet.length; d++) { + canvasContext.save(); + var timeSeries = this.seriesSet[d].timeSeries; + var dataSet = timeSeries.data; + var seriesOptions = this.seriesSet[d].options; + + // Delete old data that's moved off the left of the chart. + // We must always keep the last expired data point as we need this to draw the + // line that comes into the chart, but any points prior to that can be removed. + while (dataSet.length >= 2 && dataSet[1][0] < time - (dimensions.width * options.millisPerPixel)) { + dataSet.splice(0, 1); + } + + // Set style for this dataSet. + canvasContext.lineWidth = seriesOptions.lineWidth || 1; + canvasContext.fillStyle = seriesOptions.fillStyle; + canvasContext.strokeStyle = seriesOptions.strokeStyle || '#ffffff'; + // Draw the line... + canvasContext.beginPath(); + // Retain lastX, lastY for calculating the control points of bezier curves. + var firstX = 0, lastX = 0, lastY = 0; + for (var i = 0; i < dataSet.length; i++) { + // TODO: Deal with dataSet.length < 2. + var x = Math.round(dimensions.width - ((time - dataSet[i][0]) / options.millisPerPixel)); + var value = dataSet[i][1]; + var offset = value - visMinValue; + var scaledValue = dimensions.height - (valueRange ? Math.round((offset / valueRange) * dimensions.height) : 0); + var y = Math.max(Math.min(scaledValue, dimensions.height - 1), 1); // Ensure line is always on chart. + + if (i == 0) { + firstX = x; + canvasContext.moveTo(x, y); + } + // Great explanation of Bezier curves: http://en.wikipedia.org/wiki/B�zier_curve#Quadratic_curves + // + // Assuming A was the last point in the line plotted and B is the new point, + // we draw a curve with control points P and Q as below. + // + // A---P + // | + // | + // | + // Q---B + // + // Importantly, A and P are at the same y coordinate, as are B and Q. This is + // so adjacent curves appear to flow as one. + // + else { + switch (options.interpolation) { + case "line": + canvasContext.lineTo(x,y); + break; + case "bezier": + default: + canvasContext.bezierCurveTo( // startPoint (A) is implicit from last iteration of loop + Math.round((lastX + x) / 2), lastY, // controlPoint1 (P) + Math.round((lastX + x)) / 2, y, // controlPoint2 (Q) + x, y); // endPoint (B) + break; + } + } + + lastX = x, lastY = y; + } + if (dataSet.length > 0 && seriesOptions.fillStyle) { + // Close up the fill region. + canvasContext.lineTo(dimensions.width + seriesOptions.lineWidth + 1, lastY); + canvasContext.lineTo(dimensions.width + seriesOptions.lineWidth + 1, dimensions.height + seriesOptions.lineWidth + 1); + canvasContext.lineTo(firstX, dimensions.height + seriesOptions.lineWidth); + canvasContext.fill(); + } + canvasContext.stroke(); + canvasContext.closePath(); + canvasContext.restore(); + } + + // Draw the axis values on the chart. + if (!options.labels.disabled) { + canvasContext.fillStyle = options.labels.fillStyle; + var maxValueString = parseFloat(maxValue).toFixed(2); + var minValueString = parseFloat(minValue).toFixed(2); + canvasContext.fillText(maxValueString, dimensions.width - canvasContext.measureText(maxValueString).width - 2, 10); + canvasContext.fillText(minValueString, dimensions.width - canvasContext.measureText(minValueString).width - 2, dimensions.height - 2); + } + + canvasContext.restore(); // See .save() above. +} diff --git a/web/test.html b/web/test.html new file mode 100644 index 0000000..98e1d25 --- /dev/null +++ b/web/test.html @@ -0,0 +1,44 @@ + + + + + + + + + + + + + \ No newline at end of file
{t.formattedTotalTime} {t.formattedQueryTime} {t.formattedAvgTime}