Commit 8c04d369 8c04d369291c1675db5f4eef83d80846e4e709f4 by Christian Gerdes

New version with working viewOraMon and updated viewJmxMon and working

action buttons in OraMon.jsp. 

Name of DB is now set in OraMonREST/getMetrics
Some cleanup of code
Changed the order of counters to have the most interresting first
OraMonREST/getData and getMetrics now support new style connection
strings
Added a find() method to both Registry implementations
Both getData methods (Ora and Jmx) now support to be called without
:username:password in connection string if the monitor already exists
1 parent 91783105
...@@ -33,11 +33,4 @@ ...@@ -33,11 +33,4 @@
33 <nature>org.eclipse.jdt.core.javanature</nature> 33 <nature>org.eclipse.jdt.core.javanature</nature>
34 <nature>org.eclipse.wst.jsdt.core.jsNature</nature> 34 <nature>org.eclipse.wst.jsdt.core.jsNature</nature>
35 </natures> 35 </natures>
36 <linkedResources>
37 <link>
38 <name>jetty/lilom.jar</name>
39 <type>1</type>
40 <locationURI>PROJECT_LOC/WebContent/WEB-INF/lib/lilom.jar</locationURI>
41 </link>
42 </linkedResources>
43 </projectDescription> 36 </projectDescription>
......
...@@ -42,12 +42,53 @@ if(request.getParameter("action") != null) { ...@@ -42,12 +42,53 @@ if(request.getParameter("action") != null) {
42 <div style="background: Aquamarine; padding: 10px;">Info: <%= infMsg %> <form><input type="submit" value="OK"></form></div> 42 <div style="background: Aquamarine; padding: 10px;">Info: <%= infMsg %> <form><input type="submit" value="OK"></form></div>
43 <% } %> 43 <% } %>
44 44
45 <script type="text/javascript">
46 function getData(type, input) {
47 // Update the data
48 var client1 = new XMLHttpRequest();
49 client1.onreadystatechange = dataHandler;
50 client1.open("GET", "/" + type + "/getData?age=14&connectionString=" + encodeURIComponent(input));
51 client1.setRequestHeader('Cache-Control', 'no-cache');
52 client1.setRequestHeader('Pragma', 'no-cache');
53 client1.send();
54 }
55
56 function getMetrics(type, input) {
57 // Get the metrics
58 var client2 = new XMLHttpRequest();
59 client2.onreadystatechange = metricsHandler;
60 client2.open("GET", "/" + type + "/getMetrics?connectionString=" + encodeURIComponent(input));
61 client2.setRequestHeader('Cache-Control', 'no-cache');
62 client2.setRequestHeader('Pragma', 'no-cache');
63 client2.send();
64 }
65
66 function metricsHandler() {
67 if (this.readyState == 4) {
68 window.alert("HTTP " + this.status + "\n\n" + this.responseText);
69 }
70 }
71
72 function dataHandler() {
73 if (this.readyState == 4) {
74 window.alert("HTTP " + this.status + "\n\n" + this.responseText);
75 }
76 }
77 </script>
78
45 <h1>OraMon Web 1.1 with JmxMon</h1> 79 <h1>OraMon Web 1.1 with JmxMon</h1>
46 80
47 <h2>Status Oracle Monitors</h2> 81 <h2>Status Oracle Monitors</h2>
48
49 <p>Number of monitors: <%= se.lil.om.Registry.getList().size() %></p> 82 <p>Number of monitors: <%= se.lil.om.Registry.getList().size() %></p>
50 83
84 <div title="Add Monitor" style="background: WhiteSmoke; padding: 10px;">
85 <form>
86 <table>
87 <tr><td>Connection String:</td><td><input id="addoradata" name="data" size="70"></td><td><input type="button" value="add" onClick="getData('OraMonREST', addoradata.value)"></td></tr>
88 </table>
89 </form>
90 </div>
91
51 <div style="background-color: LightSteelBlue; padding: 10px;"> 92 <div style="background-color: LightSteelBlue; padding: 10px;">
52 <table> 93 <table>
53 <tr> 94 <tr>
...@@ -75,7 +116,9 @@ if(request.getParameter("action") != null) { ...@@ -75,7 +116,9 @@ if(request.getParameter("action") != null) {
75 <form method="POST"> 116 <form method="POST">
76 <input type="submit" name="action" value="remove" > 117 <input type="submit" name="action" value="remove" >
77 <input type="hidden" name="omconstr" value="<%= mon.getConString() %>"> 118 <input type="hidden" name="omconstr" value="<%= mon.getConString() %>">
78 <input type="button" value="view" onClick="window.open('/viewOraMon.html?<%= URLEncoder.encode(mon.getConString(), "UTF-8") %>')"> 119 <input type="button" value="graph" onClick="window.open('/viewOraMon.html?<%= URLEncoder.encode(mon.getConString(), "UTF-8") %>')">
120 <input id="getDataButton" type="button" value="getData" onClick="getData('OraMonREST', '<%= mon.getConString() %>')">
121 <input id="getMetricsButton" type="button" value="getMetrics" onClick="getMetrics('OraMonREST', '<%= mon.getConString() %>')">
79 </form> 122 </form>
80 </td> 123 </td>
81 </tr> 124 </tr>
...@@ -84,9 +127,16 @@ if(request.getParameter("action") != null) { ...@@ -84,9 +127,16 @@ if(request.getParameter("action") != null) {
84 </div> 127 </div>
85 128
86 <h2>Status JMX Monitors</h2> 129 <h2>Status JMX Monitors</h2>
87
88 <p>Number of monitors: <%= se.lil.jm.Registry.getList().size() %></p> 130 <p>Number of monitors: <%= se.lil.jm.Registry.getList().size() %></p>
89 131
132 <div title="Add Monitor" style="background: WhiteSmoke; padding: 10px;">
133 <form>
134 <table>
135 <tr><td>Connection String:</td><td><input id="addjmxdata" name="data" size="70"></td><td><input type="button" value="add" onClick="getData('JmxMonREST', addjmxdata.value)"></td></tr>
136 </table>
137 </form>
138 </div>
139
90 <div style="background-color: LightSteelBlue; padding: 10px;"> 140 <div style="background-color: LightSteelBlue; padding: 10px;">
91 <table> 141 <table>
92 <tr> 142 <tr>
...@@ -114,7 +164,9 @@ if(request.getParameter("action") != null) { ...@@ -114,7 +164,9 @@ if(request.getParameter("action") != null) {
114 <form method="POST"> 164 <form method="POST">
115 <input type="submit" name="action" value="remove" > 165 <input type="submit" name="action" value="remove" >
116 <input type="hidden" name="jmconstr" value="<%= mon.getConString() %>"> 166 <input type="hidden" name="jmconstr" value="<%= mon.getConString() %>">
117 <input type="button" value="view" onClick="window.open('/viewJmxMon.html?<%= URLEncoder.encode(mon.getConString(), "UTF-8") %>')"> 167 <input type="button" value="graph" onClick="window.open('/viewJmxMon.html?<%= URLEncoder.encode(mon.getConString(), "UTF-8") %>')">
168 <input type="button" value="getData" onClick="getData('JmxMonREST', '<%= mon.getConString() %>')">
169 <input type="button" value="getMetrics" onClick="getMetrics('JmxMonREST', '<%= mon.getConString() %>')">
118 </form> 170 </form>
119 </td> 171 </td>
120 </tr> 172 </tr>
...@@ -122,18 +174,5 @@ if(request.getParameter("action") != null) { ...@@ -122,18 +174,5 @@ if(request.getParameter("action") != null) {
122 </table> 174 </table>
123 </div> 175 </div>
124 176
125 <!--
126 <h2>Administration</h2>
127
128 <div title="Add Monitor" style="background: WhiteSmoke; padding: 10px;">
129 <form>
130 <table>
131 <tr><td>Data:</td><td><input name="data" size="50"></td></tr>
132 </table>
133 <input type="submit" name="action" value="add">
134 </form>
135 </div>
136 -->
137
138 </body> 177 </body>
139 </html> 178 </html>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
51 client1.send(); 51 client1.send();
52 } else { 52 } else {
53 // Error, no monitor specified 53 // Error, no monitor specified
54 statusP.innerHTML = "No monitor specified in URL QueryString (use ?enter uri encoded con string)"; 54 statusP.innerHTML = "No monitor specified in URL QueryString (use ?enter%20uri%20encoded%20con%20string)";
55 } 55 }
56 } 56 }
57 57
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
68 client2.send(); 68 client2.send();
69 } else { 69 } else {
70 // Error, no monitor specified 70 // Error, no monitor specified
71 statusP.innerHTML = "No monitor specified in URL QueryString (use ?enter uri encoded con string)"; 71 statusP.innerHTML = "No monitor specified in URL QueryString (use ?enter%20uri%20encoded%20con%20string)";
72 } 72 }
73 } 73 }
74 74
...@@ -101,6 +101,7 @@ ...@@ -101,6 +101,7 @@
101 function addData(res) { 101 function addData(res) {
102 if(res.error == false && res.nvarray.length > 0) { 102 if(res.error == false && res.nvarray.length > 0) {
103 main_title.innerHTML = res.name + " JMX Monitor"; 103 main_title.innerHTML = res.name + " JMX Monitor";
104 document.title = "JmxMon " + res.name;
104 if (created == false) { 105 if (created == false) {
105 createChart(res.nvarray); 106 createChart(res.nvarray);
106 } 107 }
...@@ -110,7 +111,7 @@ ...@@ -110,7 +111,7 @@
110 dataRow[0] = new Date(); 111 dataRow[0] = new Date();
111 dataRow[1] = res.nvarray[i].value; 112 dataRow[1] = res.nvarray[i].value;
112 ac_data[i].addRow(dataRow); 113 ac_data[i].addRow(dataRow);
113 if (ac_data[i].getNumberOfRows() > 1000) ac_data[i].removeRow(0); 114 if (ac_data[i].getNumberOfRows() > 100) ac_data[i].removeRow(0);
114 ac_options.title = res.nvarray[i].name + ": " + res.nvarray[i].value; 115 ac_options.title = res.nvarray[i].name + ": " + res.nvarray[i].value;
115 ac_chart[i].draw(ac_data[i], ac_options); 116 ac_chart[i].draw(ac_data[i], ac_options);
116 } 117 }
......
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>LIL JMX Monitor</title>
5 <script type="text/javascript" src="https://www.google.com/jsapi"></script>
6 </head>
7 <body>
8 <h1 id="main_title">LIL ORA Monitor</h1>
9 <div style="background-color: lightgrey; line-height:1em; min-height:3em;"><p id="statusP">Nothing loaded</p></div>
10 <div id="main_div"></div>
11 <script type="text/javascript">
12 var ac_data = [];
13 var ac_chart = [];
14 var created = false;
15
16 google.load("visualization", "1", { packages: ["corechart"] });
17 google.setOnLoadCallback(getData);
18
19 var ac_options = {
20 title: 'Current Activity',
21 hAxis: { title: 'Timeline', titleTextStyle: { color: '#333'}, format: 'HH:mm:ss' },
22 vAxis: { },
23 isStacked: false,
24 legend: { position: 'none' }
25 };
26
27 function createChart(nvarray) {
28 for(var i=0; i < nvarray.length; i++) {
29 ac_data[i] = new google.visualization.DataTable();
30 ac_data[i].addColumn('datetime', 'Time');
31 ac_data[i].addColumn('number', nvarray[i].name);
32 var newdiv = document.createElement('div');
33 newdiv.id = 'ac_div' + i;
34 main_div.appendChild(newdiv);
35 ac_chart[i] = new google.visualization.LineChart(newdiv);
36 }
37
38 created = true;
39 }
40
41 function getData() {
42 if(location.search != '')
43 {
44 // Update the data
45 statusP.innerHTML = "Calling getData...";
46 var client1 = new XMLHttpRequest();
47 client1.onreadystatechange = handler1;
48 client1.open("GET", "/OraMonREST/getData?age=14&connectionString=" + location.search.substring(1));
49 client1.setRequestHeader('Cache-Control', 'no-cache');
50 client1.setRequestHeader('Pragma', 'no-cache');
51 client1.send();
52 } else {
53 // Error, no monitor specified
54 statusP.innerHTML = "No monitor specified in URL QueryString (use ?enter%20uri%20encoded%20con%20string)";
55 }
56 }
57
58 function getMetrics() {
59 if(location.search != '')
60 {
61 // Get the metrics
62 statusP.innerHTML += "<br>Calling getMetrics...";
63 var client2 = new XMLHttpRequest();
64 client2.onreadystatechange = handler2;
65 client2.open("GET", "/OraMonREST/getMetrics?connectionString=" + location.search.substring(1));
66 client2.setRequestHeader('Cache-Control', 'no-cache');
67 client2.setRequestHeader('Pragma', 'no-cache');
68 client2.send();
69 } else {
70 // Error, no monitor specified
71 statusP.innerHTML = "No monitor specified in URL QueryString (use ?enter%20uri%20encoded%20con%20string)";
72 }
73 }
74
75 function handler1() {
76 if (this.readyState == 4) {
77 if ((this.status == 200 || this.status == 202) &&
78 this.responseText != null) {
79 var res = eval('(' + this.responseText + ')');
80 statusP.innerHTML += " Received 200 OK (ms:" + res.ms + " age:" + res.age + ")<br>" + res.msg;
81 getMetrics();
82 } else {
83 statusP.innerHTML += " Received responsecode " + this.status;
84 }
85 }
86 }
87
88 function handler2() {
89 if (this.readyState == 4) {
90 if (this.status == 200 &&
91 this.responseText != null) {
92 statusP.innerHTML += " Received 200 OK";
93 var res = eval('(' + this.responseText + ')');
94 addData(res);
95 } else {
96 statusP.innerHTML += " Received responsecode " + this.status;
97 }
98 }
99 }
100
101 function addData(res) {
102 if(res.error == false && res.nvarray.length > 0) {
103 main_title.innerHTML = res.name + " ORA Monitor";
104 document.title = "OraMon " + res.name;
105 if (created == false) {
106 createChart(res.nvarray);
107 }
108
109 for(var i=0; i < res.nvarray.length; i++) {
110 var dataRow = [];
111 dataRow[0] = new Date();
112 dataRow[1] = res.nvarray[i].value;
113 ac_data[i].addRow(dataRow);
114 if (ac_data[i].getNumberOfRows() > 100) ac_data[i].removeRow(0);
115 ac_options.title = res.nvarray[i].name + ": " + res.nvarray[i].value;
116 ac_chart[i].draw(ac_data[i], ac_options);
117 }
118 }
119
120 window.setTimeout('getData()', 15000);
121 }
122
123 </script>
124 </body>
125 </html>
No preview for this file type
...@@ -46,47 +46,84 @@ public class OraMonRESTgetData extends HttpServlet { ...@@ -46,47 +46,84 @@ public class OraMonRESTgetData extends HttpServlet {
46 46
47 if(request.getParameterMap().containsKey("connectionString")) { 47 if(request.getParameterMap().containsKey("connectionString")) {
48 // We have a connection string, find the monitor or create it and call getData() on the monitor 48 // We have a connection string, find the monitor or create it and call getData() on the monitor
49 49 OraMon monitor = null;
50 // Check that we have a valid connection string (added support to handle diffrent kinds of connection strings) 50 if(request.getParameter("connectionString").startsWith("jdbc:oracle")) {
51 String[] conStrParamArray = request.getParameter("connectionString").split(":"); 51 // Full con string
52 Boolean serviceName = false; 52 String[] shortConArray = request.getParameter("connectionString").split("@");
53 if(conStrParamArray.length == 4) { 53 if(shortConArray.length != 2) {
54 // Check if service name is used ( / instead of : ) 54 // Error, wrong format of string
55 if(conStrParamArray[1].indexOf("/") >= 0) { 55 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
56 serviceName = true; 56 response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format jdbc:oracle:thin:@//host:port/sid with optional :username:password at the end.\"}");
57 return;
58 }
59 String[] shortConArray2 = shortConArray[1].split(":");
60 if(shortConArray2[0].startsWith("//") && shortConArray2.length == 4) {
61 // We have new style and username and password, we can try to create the monitor if it doesnt exist
62 monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1], shortConArray2[2], shortConArray2[3]);
63 } else if(!shortConArray2[0].startsWith("//") && shortConArray2.length == 5) {
64 // We have old style with sid with :username:password, try to find or create it
65 monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1] + ":" + shortConArray2[2], shortConArray2[3], shortConArray2[4]);
66 } else if(shortConArray2[0].startsWith("//") && shortConArray2.length == 2) {
67 // We have new style but only have the connection string, try to find it (we cant create one without username/password)
68 monitor = Registry.find(request.getParameter("connectionString"));
69 } else if(!shortConArray2[0].startsWith("//") && shortConArray2.length == 3) {
70 // We have old style sid and no :username:password
71 monitor = Registry.find(request.getParameter("connectionString"));
72 } else {
73 // Wrong format
74 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
75 response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format jdbc:oracle:thin:@//host:port/sid with optional :username:password at the end.\"}");
76 return;
57 } 77 }
58 }
59 if(conStrParamArray.length != 5 && serviceName == false) {
60 // Error, we need 5 parts in the connection string
61 response.setStatus(400);
62 response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format host:port:sid:username:password or host:port/servicename:username:password\"}");
63 return;
64 }
65 String conStr, usrStr, pwdStr;
66 if(serviceName) {
67 conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1];
68 usrStr = conStrParamArray[2];
69 pwdStr = conStrParamArray[3];
70 } else { 78 } else {
71 conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1] + ":" + conStrParamArray[2]; 79 // Short con string
72 usrStr = conStrParamArray[3]; 80 // Check that we have a valid connection string (added support to handle diffrent kinds of connection strings)
73 pwdStr = conStrParamArray[4]; 81 String[] conStrParamArray = request.getParameter("connectionString").split(":");
82 Boolean serviceName = false;
83 if(conStrParamArray.length == 4) {
84 // Check if service name is used ( / instead of : )
85 if(conStrParamArray[1].indexOf("/") >= 0) {
86 serviceName = true;
87 }
88 }
89 if(conStrParamArray.length != 5 && serviceName == false) {
90 // Error, we need 5 parts in the connection string
91 response.setStatus(400);
92 response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format host:port:sid:username:password or host:port/servicename:username:password\"}");
93 return;
94 }
95 String conStr, usrStr, pwdStr;
96 if(serviceName) {
97 conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1];
98 usrStr = conStrParamArray[2];
99 pwdStr = conStrParamArray[3];
100 } else {
101 conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1] + ":" + conStrParamArray[2];
102 usrStr = conStrParamArray[3];
103 pwdStr = conStrParamArray[4];
104 }
105
106 // Try to find the monitor in our list
107 monitor = Registry.findOrCreate(conStr, usrStr, pwdStr);
74 } 108 }
75 109
76 // Try to find the monitor in our list 110 if(monitor != null) {
77 OraMon monitor = Registry.findOrCreate(conStr, usrStr, pwdStr); 111 // Call getData()
78 112 boolean didUpdate = monitor.getData(age);
79 // Call getData() 113 String dbName = monitor.getDBName();
80 boolean didUpdate = monitor.getData(age); 114 if(didUpdate) {
81 String dbName = monitor.getDBName(); 115 sb.append("{\"error\":false,\"msg\":\"Sucessfully collected data on instance '" + dbName + "'\"");
82 if(didUpdate) { 116 sb.append(",\"ms\":"+monitor.getLastRTms()+"}");
83 sb.append("{\"error\":false,\"msg\":\"Sucessfully collected data on instance '" + dbName + "'\""); 117 } else {
84 sb.append(",\"ms\":"+monitor.getLastRTms()+"}"); 118 response.setStatus(HttpServletResponse.SC_ACCEPTED);
119 sb.append("{\"error\":false");
120 sb.append(",\"msg\":\"Data does not need to be updated on instance '" + dbName + "' either because another thread did concurrently update the monitor and we just waited for it to complete, or because the age (if) specified was higher than the monitors data age.\"");
121 sb.append(",\"age\":"+monitor.getAgeTs()+"}");
122 }
85 } else { 123 } else {
86 response.setStatus(HttpServletResponse.SC_ACCEPTED); 124 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
87 sb.append("{\"error\":false"); 125 sb.append("{\"error\":true,\"msg\":\"Monitor not found and can't create one without :username:password '" + request.getParameter("connectionString") + "'\"");
88 sb.append(",\"msg\":\"Data does not need to be updated on instance '" + dbName + "' either because another thread did concurrently update the monitor and we just waited for it to complete, or because the age (if) specified was higher than the monitors data age.\""); 126 sb.append("}");
89 sb.append(",\"age\":"+monitor.getAgeTs()+"}");
90 } 127 }
91 128
92 } else { 129 } else {
......
...@@ -25,6 +25,15 @@ public class Registry { ...@@ -25,6 +25,15 @@ public class Registry {
25 return monitor; 25 return monitor;
26 } 26 }
27 27
28 public static synchronized OraMon find(String conStr) {
29 for (OraMon item : getList()) {
30 if(item.getConString().equals(conStr)) {
31 return item;
32 }
33 }
34 return null;
35 }
36
28 public static synchronized void remove(String conStr) { 37 public static synchronized void remove(String conStr) {
29 OraMon mon = null; 38 OraMon mon = null;
30 for (OraMon item : getList()) { 39 for (OraMon item : getList()) {
......